Use Terraform to manage infrastructure deployment
TFS 2018
Terraform is an open-source infrastructure as code (IaC) tool to manage cloud services. Terraform can manage existing and popular cloud service providers as well as custom in-house solutions. Using Terraform you can define and provision your infrastructure components in config files using an easy to learn declarative language: HashiCorp Configuration Language (HCL).
In this tutorial, you will learn about:
- The structure of a Terraform file
- Building an application using an Azure CI pipeline
- Deploying resources using Terraform and Azure CD pipeline
Prerequisites
- A Microsoft Azure account.
- An Azure DevOps account.
- Set up the demo project using the Azure DevOps Demo Generator.
Examine the Terraform config file
This tutorial uses the PartsUnlimited project, a sample eCommerce website developed using .NET Core. The Terraform config file defines the Azure resources required to deploy our web application.
Select Repos then select the terraform branch.
Find and select the webapp.tf configuration file in your repo and review its content. In this example, we define the Azure resources that will be used to deploy our web application. Some variables will be populated during run time.
terraform { required_version = ">= 0.11" backend "azurerm" { storage_account_name = "__terraformstorageaccount__" container_name = "terraform" key = "terraform.tfstate" access_key ="__storagekey__" features{} } } provider "azurerm" { version = "=2.0.0" features {} } resource "azurerm_resource_group" "dev" { name = "PULTerraform" location = "West Europe" } resource "azurerm_app_service_plan" "dev" { name = "__appserviceplan__" location = "${azurerm_resource_group.dev.location}" resource_group_name = "${azurerm_resource_group.dev.name}" sku { tier = "Free" size = "F1" } } resource "azurerm_app_service" "dev" { name = "__appservicename__" location = "${azurerm_resource_group.dev.location}" resource_group_name = "${azurerm_resource_group.dev.name}" app_service_plan_id = "${azurerm_app_service_plan.dev.id}" }
Azure build pipeline
This DevOps project includes two separate pipelines to build and deploy our web application. The build pipeline produces the artifacts that will be deployed by the release pipeline in the next section.
Navigate to Pipelines and select the Terraform-CI pipeline.
Select Edit to review the tasks included in the pipeline. The .NET Core tasks help restore dependencies, build, test, and publish the build output as a zip file to be deployed to an app service.
The Copy files task copies the Terraform folder to the Artifact staging directory.
Select Queue then Run to queue and run your pipeline.
Release pipeline
Now that we built our application, it's time to deploy it. However, no deployment infrastructure has been created yet. This is where Terraform comes in. By following the definition file reviewed earlier, Terraform determines what actions are necessary to achieve the state outlined in the config file.
Navigate to Releases and select the Terraform-CD pipeline. Select Edit to review or edit the pipeline.
The release pipeline has been configured to consume the build artifact. Select the Dev stage to review or edit its tasks.
There are eight tasks defined in the release stage. Most of them require some configuration to work with your Azure account. Select each task and enter your Azure subscription in the appropriate field.
Select Agent job and set up the Agent pool and Agent specification.
Select the Azure CLI task and add your Azure subscription.
This task executes a series of Azure CLI commands to set up some basic infrastructure required to use Terraform.
# this will create Azure resource group az group create --location westus --name $(terraformstoragerg) az storage account create --name $(terraformstorageaccount) --resource-group $(terraformstoragerg) --location westus --sku Standard_LRS az storage container create --name terraform --account-name $(terraformstorageaccount) az storage account keys list -g $(terraformstoragerg) -n $(terraformstorageaccount)
By default, Terraform stores state locally in terraform.tfstate. When working in a team environment, using a local file makes Terraform implementation more complicated. With remote state, Terraform writes the state data to a remote data store. In our example, the Azure CLI task creates an Azure storage account and a storage container to store the Terraform state. For more information on Terraform remote state, see Remote State.
Select the Azure PowerShell task and set up the Azure Resource Manager and Azure subscription fields.
This task uses a PowerShell script to retrieve the storage account key needed for the Terraform provisioning.
# Using this script we will fetch storage key which is required in terraform file to authenticate backend storage account $key=(Get-AzStorageAccountKey -ResourceGroupName $(terraformstoragerg) -AccountName $(terraformstorageaccount)).Value[0] Write-Host "##vso[task.setvariable variable=storagekey]$key"
Select the Replace tokens in terraform file task. If you recall the file reviewed earlier, there were several resources that were unknown at the time and marked with token placeholders, such as terraformstorageaccount. This task assigns values during run-time to some of the variables in the webapp.tf config file including those from the pipeline's Variables section.
The Install Terraform task installs and configures the specified version of Terraform on the agent for the remaining tasks.
When running Terraform in automation, the focus is usually on the core plan/apply cycle. The next three tasks follow these stages.
The Terraform init task runs the init command to look through all of the *.tf files in the current working directory and automatically downloads any of the required providers. In this example, it will download Azure provider as it is going to deploy Azure resources.
Set up the Azure subscription, container, and Key fields.
The Terraform plan task runs the plan command to create an execution plan by determining what actions are necessary to achieve the desired state specified in the configuration files. This is just a dry run and shows which actions will be performed.
Enter your Azure subscription in the appropriate field.
The Terraform apply task runs the apply command to deploy the resources. By default, it will also prompt for confirmation before applying. Since this is an automated deployment, the auto-approve argument is included.
Enter your Azure subscription in the appropriate field.
Select the Azure App Service Deploy task and enter your Azure subscription. By the time this task runs, Terraform has already ensured that the deployment environment has been configured to meet the app's requirements. It will use the $(appservicename) from the Variables section.
Select Save then confirm.
Select Create release and specify the recent build's Artifact then select Create.
Select the new release to view the pipeline's execution.
Once the release is completed, select the Azure App Service Deploy task.
Copy the name of the app service from the task title.
Open a new browser tab and navigate to your deployed website. The domain format is [app service name].azurewebsites.net:
https://pulterraformweb99ac17bf.azurewebsites.net.
Clean up resources
In this tutorial, we created a Azure DevOps project and few resources in Azure. If you're not going to continue to use these resources, you can follow these steps to delete them:
Delete the Azure DevOps project created by the Azure DevOps Demo Generator.
All Azure resources created during this tutorial were assigned to either the PULTerraform or terraformrg resource groups. Deleting those two groups will delete the resources they contain.
az group delete --name PULTerraform az group delete --name terraformrg