{"id":3336,"date":"2022-06-03T03:13:39","date_gmt":"2022-06-03T03:13:39","guid":{"rendered":"https:\/\/exceedthecloud.com\/?p=3336"},"modified":"2022-06-03T03:48:55","modified_gmt":"2022-06-03T03:48:55","slug":"automating-infrastructure-deployments-in-the-cloud-with-terraform-and-azure-pipelines","status":"publish","type":"post","link":"https:\/\/exceedthecloud.com\/?p=3336","title":{"rendered":"Automating infrastructure deployments in the Cloud with Terraform and Azure Pipelines"},"content":{"rendered":"\n<p><\/p>\n\n\n\n<p><a href=\"https:\/\/www.terraform.io\/intro\/index.html\" target=\"_blank\" rel=\"noreferrer noopener\">Terraform<\/a>&nbsp;is a tool for building, changing and versioning infrastructure. Terraform can manage existing and popular cloud service providers as well as custom in-house solutions.<\/p>\n\n\n\n<p>Terraform configuration files describe the components needed to run a single application or your entire datacenter. Terraform generates an execution plan describing what it will do to reach the desired state, and then executes it to build the described infrastructure. As the configuration changes, Terraform is able to determine what changed and create incremental execution plans to execute.<\/p>\n\n\n\n<p>In this lab, you will learn how to incorporate Terraform into Azure Pipelines for implementing Infrastructure as Code.<\/p>\n\n\n\n<p>After you complete this lab, you will be able to:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Use Terraform to implement Infrastructure as Code<\/li><li>Automate infrastructure deployments in Azure with Terraform and Azure Pipelines<\/li><\/ul>\n\n\n\n<p><strong>Review applications required for this lab<\/strong><\/p>\n\n\n\n<p>Identify the applications that you\u2019ll use in this lab:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Microsoft Edge<\/li><\/ul>\n\n\n\n<p>Set up an Azure DevOps organization.<\/p>\n\n\n\n<p>If you don\u2019t already have an Azure DevOps organization that you can use for this lab, create one by following the instructions available at&nbsp;<a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/devops\/organizations\/accounts\/create-organization?view=azure-devops\" target=\"_blank\" rel=\"noreferrer noopener\">Create an organization or project collection<\/a>.<\/p>\n\n\n\n<p><strong>Prepare an Azure subscription<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Identify an existing Azure subscription or create a new one.<\/li><li>Verify that you have a Microsoft account or an Azure AD account with the Owner role in the Azure subscription and the Global Administrator role in the Azure AD tenant associated with the Azure subscription.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Lab 0: Configure the lab prerequisites<\/strong><\/p>\n\n\n\n<p>In this Lab, you will set up the prerequisites for the lab, which consist of the preconfigured Parts Unlimited team project based on an Azure DevOps Demo Generator template.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Task 1: Configure the team project<\/strong><\/p>\n\n\n\n<p>In this task, you will use Azure DevOps Demo Generator to generate a new project based on the&nbsp;<strong>Terraform<\/strong>&nbsp;template.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>On your lab computer, start a web browser and navigate to&nbsp;<a href=\"https:\/\/azuredevopsdemogenerator.azurewebsites.net\/\" target=\"_blank\" rel=\"noreferrer noopener\">Azure DevOps Demo Generator<\/a>. This utility site will automate the process of creating a new Azure DevOps project within your account that is prepopulated with content (work items, repos, etc.) required for the lab.<\/li><\/ul>\n\n\n\n<p><strong>Note<\/strong>: For more information on the site, see https:\/\/docs.microsoft.com\/en-us\/azure\/devops\/demo-gen.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\" start=\"2\"><li>Click&nbsp;<strong>Sign in<\/strong>&nbsp;and sign in using the Microsoft account associated with your Azure DevOps subscription.<\/li><li>If required, on the&nbsp;<strong>Azure DevOps Demo Generator<\/strong>&nbsp;page, click&nbsp;<strong>Accept<\/strong>&nbsp;to accept the permission requests for accessing your Azure DevOps subscription.<\/li><li>On the&nbsp;<strong>Create New Project<\/strong>&nbsp;page, in the&nbsp;<strong>New Project Name<\/strong>&nbsp;textbox, type&nbsp;<strong>Automating&nbsp;infrastructure&nbsp;deployments&nbsp;with&nbsp;Terraform<\/strong>, in the&nbsp;<strong>Select organization<\/strong>&nbsp;dropdown list, select your Azure DevOps organization, and then click&nbsp;<strong>Choose template<\/strong>.<\/li><li>In the list of templates, in the toolbar, click&nbsp;<strong>DevOps Labs<\/strong>, select the&nbsp;<strong>Terraform<\/strong>&nbsp;template and click&nbsp;<strong>Select Template<\/strong>.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"287\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture1.png\" alt=\"\" class=\"wp-image-3337\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture1.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture1-300x138.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>Back on the&nbsp;<strong>Create New Project<\/strong>&nbsp;page, if prompted to install a missing extension, select the checkbox below the&nbsp;<strong>Replace Tokens<\/strong>&nbsp;and&nbsp;<strong>Terraform<\/strong>&nbsp;labels and click&nbsp;<strong>Create Project<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"417\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture2.png\" alt=\"\" class=\"wp-image-3338\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture2.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture2-300x200.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p><strong>Note<\/strong>: Wait for the process to complete. This should take about 2 minutes. In case the process fails, navigate to your DevOps organization, delete the project, and try again.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>On the&nbsp;<strong>Create New Project<\/strong>&nbsp;page, click&nbsp;<strong>Navigate to project<\/strong>.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Lab 1: Automate infrastructure deployments in the cloud with Terraform and Azure Pipelines<\/strong><\/p>\n\n\n\n<p>In this Lab, you will deploy Infrastructure as Code into Azure by using Terraform&nbsp;and&nbsp;Azure&nbsp;Pipelines<\/p>\n\n\n\n<p><strong>Task 1: Examine the Terraform configuration files<\/strong><\/p>\n\n\n\n<p>In this task, you will examine the use of Terraform in provisioning Azure Resources required to deploy PartsUnlimited website.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>On your lab computer, in the web browser window displaying the Azure DevOps portal with the&nbsp;<strong>Automating&nbsp;infrastructure&nbsp;deployments&nbsp;with&nbsp;Terraform<\/strong>&nbsp;project open, in the vertical menu bar at the far left of the Azure DevOps portal, click&nbsp;<strong>Repos<\/strong>.<\/li><li>On the&nbsp;<strong>Files<\/strong>&nbsp;pane, click the facing-down caret next to the&nbsp;<strong>master<\/strong>&nbsp;entry at the top and, in the dropdown list of branches, click the entry representing the&nbsp;<strong>terraform<\/strong>&nbsp;branch.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"310\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture3.png\" alt=\"\" class=\"wp-image-3339\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture3.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture3-300x149.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p><strong>Note<\/strong>: Make sure that you are now on the&nbsp;<strong>terraform<\/strong>&nbsp;branch and&nbsp;<strong>Terraform<\/strong>&nbsp;folder appears within the content of the repo.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>In the folder hierarchy of the&nbsp;<strong>Terraform<\/strong>&nbsp;repo, expand the&nbsp;<strong>Terraform<\/strong>&nbsp;folder and click&nbsp;<strong>webapp.tf<\/strong>.<\/li><li>On the&nbsp;<strong>webapp.tf<\/strong>&nbsp;review the content of the&nbsp;<strong>webapp.tf<\/strong>&nbsp;file and click&nbsp;<strong>Edit<\/strong>.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"445\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture4.png\" alt=\"\" class=\"wp-image-3340\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture4.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture4-300x214.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>Add a new lines for the&nbsp;<strong>provider<\/strong>&nbsp;section, the file should like the following example:<\/li><\/ul>\n\n\n\n<p>CodeCopy<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>terraform {\n  required_version = \"&gt;= 0.11\" \n  backend \"azurerm\" {\n  storage_account_name = \"__terraformstorageaccount__\"\n    container_name       = \"terraform\"\n    key                  = \"terraform.tfstate\"\n    access_key  =\"__storagekey__\"\n    }\n}\nprovider \"azurerm\" {\n    features {} \n  }\n\nresource \"azurerm_resource_group\" \"dev\" {\n  name     = \"PULTerraform\"\n  location = \"West Europe\"\n}\n\nresource \"azurerm_app_service_plan\" \"dev\" {\n  name                = \"__appserviceplan__\"\n  location            = \"${azurerm_resource_group.dev.location}\"\n  resource_group_name = \"${azurerm_resource_group.dev.name}\"\n\n  sku {\n    tier = \"Free\"\n    size = \"F1\"\n  }\n}\n\nresource \"azurerm_app_service\" \"dev\" {\n  name                = \"__appservicename__\"\n  location            = \"${azurerm_resource_group.dev.location}\"\n  resource_group_name = \"${azurerm_resource_group.dev.name}\"\n  app_service_plan_id = \"${azurerm_app_service_plan.dev.id}\"\n\n}\n<\/code><\/pre>\n\n\n\n<p>Click&nbsp;<strong>Commit<\/strong>, and, on the&nbsp;<strong>Commit<\/strong>&nbsp;pane, click&nbsp;<strong>Commit<\/strong>&nbsp;again.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"472\" height=\"842\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture5.png\" alt=\"\" class=\"wp-image-3341\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture5.png 472w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture5-168x300.png 168w\" sizes=\"auto, (max-width: 472px) 100vw, 472px\" \/><\/figure>\n\n\n\n<p><strong>Note<\/strong>:&nbsp;<strong>webapp.tf<\/strong>&nbsp;is a terraform configuration file. Terraform uses its own file format, called HCL (Hashicorp Configuration Language), similar to YAML.<\/p>\n\n\n\n<p><strong>Note<\/strong>: In this example, we want to create an Azure Resource group, App service plan and App service required to deploy a website. We have added the Terraform file to source control repository in the Azure DevOps project so you can use it to deploy the required Azure resources.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Task 2: Build your application using Azure CI Pipeline<\/strong><\/p>\n\n\n\n<p>In this task, you will build your application and publish the required files as an artifact called drop.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>In the Azure DevOps portal, in the vertical menu bar at the left of the Azure DevOps portal, click&nbsp;<strong>Pipelines<\/strong>. Underneath, select&nbsp;<strong>Pipelines<\/strong>.<\/li><li>On the&nbsp;<strong>Pipelines<\/strong>&nbsp;pane, click&nbsp;<strong>Terraform-CI<\/strong>&nbsp;to select it and, on the&nbsp;<strong>Terraform-CI<\/strong>&nbsp;pane, click&nbsp;<strong>Edit<\/strong>.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"310\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture7.png\" alt=\"\" class=\"wp-image-3342\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture7.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture7-300x149.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p><strong>Note<\/strong>: This CI pipeline has tasks to compile the .NET Core project. The DotNet tasks in the pipeline will restore dependencies, build, test and publish the build output into a zip file (package), which can be deployed to a web application. In addition to the application build, we need to publish terraform files to build artifacts to make them available in CD pipeline. This is the reason for the&nbsp;<strong>Copy files<\/strong>&nbsp;task to copy Terraform file to Artifacts directory.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>Once you review the&nbsp;<strong>Tasks<\/strong>&nbsp;tab of the&nbsp;<strong>Terraform-CI<\/strong>&nbsp;pane, click&nbsp;<strong>Queue<\/strong>&nbsp;(you might first need to click the ellipsis symbol in the top right corner of the pane to display a drop-down menu).<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"430\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture8.png\" alt=\"\" class=\"wp-image-3343\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture8.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture8-300x207.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>On the&nbsp;<strong>Run pipeline<\/strong>&nbsp;pane, click&nbsp;<strong>Run<\/strong>&nbsp;to initiate the build.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"466\" height=\"840\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture9.png\" alt=\"\" class=\"wp-image-3344\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture9.png 466w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture9-166x300.png 166w\" sizes=\"auto, (max-width: 466px) 100vw, 466px\" \/><\/figure>\n\n\n\n<p>On the&nbsp;<strong>Summary<\/strong>&nbsp;tab of the build run pane, in the&nbsp;<strong>Jobs<\/strong>&nbsp;section, click&nbsp;<strong>Agent job 1<\/strong>&nbsp;and monitor the progress of the build process.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"421\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture10.png\" alt=\"\" class=\"wp-image-3345\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture10.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture10-300x202.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>Once the build succeeds, switch back to the&nbsp;<strong>Summary<\/strong>&nbsp;tab of the build run pane, in the&nbsp;<strong>Related<\/strong>&nbsp;section, click the&nbsp;<strong>1 published, 1 consumed<\/strong>&nbsp;link. This will display the&nbsp;<strong>Artifacts<\/strong>&nbsp;pane.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"263\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture11.png\" alt=\"\" class=\"wp-image-3346\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture11.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture11-300x126.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>On the&nbsp;<strong>Artifacts<\/strong>&nbsp;pane, on the&nbsp;<strong>Published<\/strong>&nbsp;tab, expand the&nbsp;<strong>drop<\/strong>&nbsp;folder, verify that it contains the&nbsp;<strong>PartsUnlimitedwebsite.zip<\/strong>&nbsp;file, then expand its&nbsp;<strong>Terraform<\/strong>&nbsp;subfolder, and verify that it includes the&nbsp;<strong>webapp.tf<\/strong>&nbsp;file.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"236\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture12.png\" alt=\"\" class=\"wp-image-3347\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture12.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture12-300x113.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Task 3: Deploy resources using Terraform (IaC) in Azure CD pipeline<\/strong><\/p>\n\n\n\n<p>In this task, you will create Azure resources using Terraform as part of your deployment pipeline and then deploy the PartsUnlimited application to an Azure app service web app provisioned by Terraform.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>In the Azure DevOps portal, in the vertical menu bar at the left of the Azure DevOps portal, in the&nbsp;<strong>Pipelines<\/strong>&nbsp;section, click&nbsp;<strong>Releases<\/strong>, ensure that the&nbsp;<strong>Terraform-CD<\/strong>&nbsp;entry is selected, and click&nbsp;<strong>Edit<\/strong>.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"320\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture13.png\" alt=\"\" class=\"wp-image-3348\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture13.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture13-300x154.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>On the&nbsp;<strong>All pipelines &gt; Terraform-CD<\/strong>&nbsp;pane, in the rectangle representing the&nbsp;<strong>Dev<\/strong>&nbsp;stage, click the&nbsp;<strong>1 job, 8 tasks<\/strong>&nbsp;link.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"297\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture14.png\" alt=\"\" class=\"wp-image-3349\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture14.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture14-300x143.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>In the list of tasks of the&nbsp;<strong>Dev<\/strong>&nbsp;stage, select the&nbsp;<strong>Azure CLI to deploy required Azure resources<\/strong>&nbsp;task.<\/li><li>On the&nbsp;<strong>Azure CLI<\/strong>&nbsp;pane, in the&nbsp;<strong>Azure subscription<\/strong>&nbsp;dropdown list, select the entry representing your Azure subscription and then click&nbsp;<strong>Authorize<\/strong>&nbsp;to configure the corresponding service connection. When prompted, sign in using the account with the Owner role in the Azure subscription and the Global Administrator role in the Azure AD tenant associated with the Azure subscription.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"482\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture15.png\" alt=\"\" class=\"wp-image-3350\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture15.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture15-300x232.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p><strong>Note<\/strong>: By default, Terraform stores state locally in a file named terraform.tfstate. When working with Terraform in a team, use of a local file makes Terraform usage complicated. Terraform supports a remote data store, that facilitates state sharing. In this case, we are using the&nbsp;<strong>Azure CLI<\/strong>&nbsp;task to create an Azure storage account and a blob container to store Terraform state. For more information regarding Terraform remote state, refer to&nbsp;<a href=\"https:\/\/www.terraform.io\/docs\/state\/remote.html\">Terraform documentation<\/a><\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>In the list of tasks of the&nbsp;<strong>Dev<\/strong>&nbsp;stage, select the&nbsp;<strong>Azure PowerShell<\/strong>&nbsp;task.<\/li><li>On the&nbsp;<strong>Azure PowerShell<\/strong>&nbsp;pane, in the&nbsp;<strong>Azure Connection Type<\/strong>&nbsp;dropdown list, select&nbsp;<strong>Azure Resource Manager<\/strong>&nbsp;and then, in the&nbsp;<strong>Azure Subscription<\/strong>&nbsp;dropdown list, select the newly created Azure service connection (the one under \u201cAvailable Azure Service Connection\u201d).<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"501\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture16.png\" alt=\"\" class=\"wp-image-3351\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture16.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture16-300x241.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p><strong>Note<\/strong>: To configure the Terraform&nbsp;<a href=\"https:\/\/www.terraform.io\/docs\/backends\/\">backend<\/a>, we need the access key to the Azure Storage account hosting the Terraform state. In this case, we are using Azure PowerShell task to retrieve the access key of the Azure Storage account provisioned in the previous task. By using&nbsp;Write-Host &#8220;##vso[task.setvariable variable=storagekey]$key&#8221;&nbsp;we are creating a pipeline variable that we will be able to use on later tasks.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>In the list of tasks of the&nbsp;<strong>Dev<\/strong>&nbsp;stage, select the&nbsp;<strong>Replace tokens in Terraform file<\/strong>&nbsp;task.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"517\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture17.png\" alt=\"\" class=\"wp-image-3352\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture17.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture17-300x249.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><figcaption><strong>Note<\/strong>: If you carefully reviewed the&nbsp;<strong>webapp.tf<\/strong>&nbsp;file, you should have noticed a few values suffixed and prefixed with&nbsp;<strong>__<\/strong>, such as&nbsp;__terraformstorageaccount__. The&nbsp;<strong>Replace Tokens<\/strong>&nbsp;task will replace those values with the variable values defined in the release pipeline.<br>Terraform tool installer task is used to install a specified version of Terraform from the Internet or the tools cache and prepends it to the PATH of the Azure Pipelines Agent (hosted or private).<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"417\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture18.png\" alt=\"\" class=\"wp-image-3353\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture18.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture18-300x200.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\"><li>In the list of tasks of the&nbsp;<strong>Dev<\/strong>&nbsp;stage, select and review the&nbsp;<strong>Install Terraform<\/strong>&nbsp;task. This task installs the Terraform version you designate.<\/li><\/ol>\n\n\n\n<p><strong>Note<\/strong>: The When running Terraform in automation, the focus is usually on the core plan\/apply cycle, which typically consists of the following three stages:<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>Initializing the Terraform working directory.<\/li><li>Producing a plan for modifying current configuration to match the desired configuration.<\/li><li>Applying the changes determined during the planning stage.<\/li><\/ul>\n\n\n\n<p><strong>Note<\/strong>: The remaining Terraform tasks in the release pipeline implement this workflow.<\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\" start=\"2\"><li>In the list of tasks of the&nbsp;<strong>Dev<\/strong>&nbsp;stage, select the&nbsp;<strong>Terraform: init<\/strong>&nbsp;task.<\/li><li>On the&nbsp;<strong>Terraform<\/strong>&nbsp;pane, in the&nbsp;<strong>Azure subscription<\/strong>&nbsp;dropdown list, select the same Azure service connection you used previously.<\/li><li>On the&nbsp;<strong>Terraform<\/strong>&nbsp;pane, in the&nbsp;<strong>Container<\/strong>&nbsp;dropdown list, type&nbsp;<strong>terraform<\/strong>&nbsp;and ensure that the&nbsp;<strong>Key<\/strong>&nbsp;parameter is set to&nbsp;<strong>terraform.tfstate<\/strong>.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"472\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture19.png\" alt=\"\" class=\"wp-image-3354\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture19.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture19-300x227.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p><strong>Note<\/strong>: The&nbsp;terraform init&nbsp;command parses all of the *.tf files in the current working directory and automatically downloads any of the providers required to process them. In this example, it will download the&nbsp;<a href=\"https:\/\/www.terraform.io\/docs\/providers\/azurerm\/\">Azure provider<\/a>, since we are deploying Azure resources. For more information about&nbsp;terraform init&nbsp;command, refer to&nbsp;<a href=\"https:\/\/www.terraform.io\/docs\/commands\/init.html\">Terraform documentation<\/a><\/p>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>In the list of tasks of the&nbsp;<strong>Dev<\/strong>&nbsp;stage, select the&nbsp;<strong>Terraform: plan<\/strong>&nbsp;task.<\/li><li>On the&nbsp;<strong>Terraform<\/strong>&nbsp;pane, in the&nbsp;<strong>Azure subscription<\/strong>&nbsp;dropdown list, select the same Azure service connection you used previously.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"500\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture20.png\" alt=\"\" class=\"wp-image-3355\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture20.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture20-300x240.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>On the&nbsp;<strong>Terraform<\/strong>&nbsp;pane, in the&nbsp;<strong>Additional command arguments<\/strong>&nbsp;text box, enter&nbsp;-out=tfplan.<\/li><\/ul>\n\n\n\n<p><strong>Note<\/strong>: The&nbsp;terraform plan&nbsp;command is used to create an execution plan. Terraform determines what actions are necessary to achieve the desired state specified in the configuration files. This allows you to review which changes are in scope, without actually having to apply them. For more information about&nbsp;terraform plan&nbsp;command, refer to&nbsp;<a href=\"https:\/\/www.terraform.io\/docs\/commands\/plan.html\">Terraform documentation<\/a><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>In the list of tasks of the&nbsp;<strong>Dev<\/strong>&nbsp;stage, select the&nbsp;<strong>Terraform: apply -auto-approve<\/strong>&nbsp;task.<\/li><li>On the&nbsp;<strong>Terraform<\/strong>&nbsp;pane, in the&nbsp;<strong>Azure subscription<\/strong>&nbsp;dropdown list, select the same Azure service connection you used previously.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"497\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture21.png\" alt=\"\" class=\"wp-image-3356\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture21.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture21-300x239.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>On the&nbsp;<strong>Terraform<\/strong>&nbsp;pane, in the&nbsp;<strong>Additional command arguments<\/strong>&nbsp;text box, replace the current entry with&nbsp;-auto-approve tfplan.<\/li><\/ul>\n\n\n\n<p><strong>Note<\/strong>: This task will run the&nbsp;terraform apply&nbsp;command to deploy the resources. By default, it would also prompt for a confirmation to proceed. Since we are automating the deployment, the task includes the&nbsp;auto-approve&nbsp;parameter that eliminates the need for a confirmation.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>In the list of tasks of the&nbsp;<strong>Dev<\/strong>&nbsp;stage, select the&nbsp;<strong>Azure App Service Deploy<\/strong>&nbsp;task. Select Azure service connection from the drop-down.<\/li><\/ul>\n\n\n\n<p><strong>Note<\/strong>: This task will deploy the PartsUnlimited package to Azure app service, provisioned by the&nbsp;<strong>Terraform: apply -auto-approve<\/strong>&nbsp;task in the previous step.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>On the&nbsp;<strong>Dev<\/strong>&nbsp;stage, click on&nbsp;<strong>Agent job<\/strong>&nbsp;and on the Agent pool dropdown list select:&nbsp;<strong>Azure Pipelines &gt; windows-2019<\/strong>.<\/li><li>On the&nbsp;<strong>All pipelines &gt; Terraform-CD<\/strong>&nbsp;pane, click&nbsp;<strong>Save<\/strong>, in the&nbsp;<strong>Save<\/strong>&nbsp;dialog box, click&nbsp;<strong>OK<\/strong>, and, in the upper right corner, click&nbsp;<strong>Create a release<\/strong>.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"520\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture22.png\" alt=\"\" class=\"wp-image-3357\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture22.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture22-300x250.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>On the&nbsp;<strong>Create a new release<\/strong>&nbsp;pane, in the&nbsp;<strong>Stages for a trigger change from automated to manual<\/strong>&nbsp;dropdown list, click&nbsp;<strong>Dev<\/strong>, in the&nbsp;<strong>Artifacts<\/strong>&nbsp;section, in the&nbsp;<strong>Version<\/strong>&nbsp;dropdown list, select the entry representing the version of the artifact for this release, and click&nbsp;<strong>Create<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"520\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture23.png\" alt=\"\" class=\"wp-image-3358\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture23.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture23-300x250.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"605\" height=\"853\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture24.png\" alt=\"\" class=\"wp-image-3359\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture24.png 605w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture24-213x300.png 213w\" sizes=\"auto, (max-width: 605px) 100vw, 605px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>In the Azure DevOps portal, navigate back to the&nbsp;<strong>Terraform-CD<\/strong>&nbsp;pane and click the entry&nbsp;<strong>Release-1<\/strong>&nbsp;representing the newly created release.<\/li><li>On the&nbsp;<strong>Terraform-CD &gt; Release-1<\/strong>&nbsp;blade, click the rectangle representing the&nbsp;<strong>Dev<\/strong>&nbsp;stage, on the&nbsp;<strong>Dev<\/strong>&nbsp;pane, click&nbsp;<strong>Deploy<\/strong>&nbsp;and then click&nbsp;<strong>Deploy<\/strong>&nbsp;again.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"457\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture25.png\" alt=\"\" class=\"wp-image-3360\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture25.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture25-300x220.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"393\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture26.png\" alt=\"\" class=\"wp-image-3361\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture26.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture26-300x189.png 300w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture26-80x50.png 80w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p>Back on the On the&nbsp;<strong>Terraform-CD &gt; Release-1<\/strong>&nbsp;blade, click the rectangle representing the&nbsp;<strong>Dev<\/strong>&nbsp;stage and monitor the deployment process.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"407\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture27.png\" alt=\"\" class=\"wp-image-3362\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture27.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture27-300x196.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\" type=\"1\"><li>Once the release successfully completes, on your lab computer, launch another web browser window, navigate to the\u00a0<a href=\"https:\/\/portal.azure.com\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Azure Portal<\/strong><\/a>, and sign in with the user account that has at least the Contributor role in the Azure subscription you will be using in this lab.<\/li><li>In the Azure portal, search for and select the\u00a0<strong>App Services<\/strong>\u00a0resources and, from the\u00a0<strong>App Services<\/strong>\u00a0blade, navigate to the web app which name starts with\u00a0<strong>pulterraformweb<\/strong>.<\/li><li>On the web app blade, click\u00a0<strong>Browse<\/strong>. This will open another web browser tab, displaying the newly deployed web application.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"468\" src=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture28.png\" alt=\"\" class=\"wp-image-3363\" srcset=\"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture28.png 624w, https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/Picture28-300x225.png 300w\" sizes=\"auto, (max-width: 624px) 100vw, 624px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Review<\/strong><\/p>\n\n\n\n<p>In this lab, you learned how to automate repeatable deployments with Terraform on Azure using Azure Pipelines.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><mark class=\"kt-highlight\">Reminder: Don\u2019t forget to delete or shutdown all unused Azure resources after your labs for cost saving<\/mark><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Terraform&nbsp;is a tool for building, changing and versioning infrastructure. Terraform can manage existing and popular cloud service providers as well as custom in-house solutions. Terraform configuration files describe the components needed to run a single application or your entire datacenter. &hellip; <a href=\"https:\/\/exceedthecloud.com\/?p=3336\">Continued<\/a><\/p>\n","protected":false},"author":1,"featured_media":3365,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"kt_blocks_editor_width":"","_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[16,4,26],"tags":[8,107,116],"class_list":["post-3336","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","category-practical-labs-series","category-web","tag-azure","tag-pipelines","tag-terraform"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/exceedthecloud.com\/wp-content\/uploads\/2022\/06\/images.jpg","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=\/wp\/v2\/posts\/3336","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3336"}],"version-history":[{"count":9,"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=\/wp\/v2\/posts\/3336\/revisions"}],"predecessor-version":[{"id":3379,"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=\/wp\/v2\/posts\/3336\/revisions\/3379"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=\/wp\/v2\/media\/3365"}],"wp:attachment":[{"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3336"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3336"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/exceedthecloud.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3336"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}