Terraform Part 2: A Brief Deployment
This post is part of a short Terraform series which will take you through some of my learning about Terraform with examples. I wanted to document the steps I used to deploy my first Terraform template. I always find examples helpful when learning a new technology and I hope my early attempts at Terraform help to clarify some topics for you as well.
Before we configure and deploy resources with Terraform, we will need to create a service principle that will be used to create resources within our Azure tenant. There are a number of ways to authenticate to Azure with Terraform. This is just a simple demo so a Service Principal with a secret will do. Use the permissions matrix in the link above to assign appropriate permissions to the Terraform service principle.
My preferred IDE is Visual Studio Code. It is free and has tons of extensions to get you up and running with most languages, including HashiCorp Configuration Language (HCL). You can download Visual Studio Code here. Once downloaded, install the Terraform extension by HashiCorp. There are other extensions on the marketplace developed by others but ensure that you download the one created by HashiCorp. You may also want to download a formatter like the Prettier extension as well. This will ensure that your HCL is lined up every time you hit save and make it even easier to read. Now that we have our tools. Let's dive into the Terraform documentation.
Terraform documentation for every Azure resource that can be deployed with Terraform can be found here in the Terraform registry. From there you can search for providers and modules in the search bar and find the resources that you need:

Let set up our file structure. Create a folder and inside that folder, create a file called main.tf. The tf extension will let Terraform know where to look when we run Terraform commands. Terraform will specifically look for .tf files in the current folder and compose them into a deployment. You can have multiple .tf files your deployment. This file can contain your providers (will demonstrate below) as well as resources that you want to deploy. You can also split our your providers block into a separate file but for our purposes, let's keep it one main file. You can also name the main file whatever you please. You can name it after your resource(s) or application name if the file contains all of the resources that are needed to run an application. Whatever you choose, just make sure that it makes sense for its purpose. Here we will stick with the typical "main" moniker. Here is what I have in my folder so far:

Our we now have an empty main file and need to populate it with the provider we want to use as a first step. We need to specify the following:
The cloud provider author/provider
The version - Note that the minor version changes often for the HashiCorp AzureRM provider
Here is an example of the provider block for your main.tf file:

Below that block we need to configure the provider to work with Azure by populating the service principal information:

We havent gone over variables yet but feel free to put this sensitive information as variables now (var.<variablename>). Now that we have the required providers and the configuration for the provider, we can get started defining our resources. You can use variables for the values here as well, just remember to add them to the variables.tf file. Next let get our resources. Today I will be showing snippets of the template that will be presented in the next post in this series.

Notice the format of the resource blocks. 'azurerm_app_service_plan' is the type of the resource and 'server_farm' is the name which Terraform will use to reference the resource. You can refer to the resource later in the template using an expressions, in this case 'azurerm_app_service_plan.server_farm' Notice how in the resource block that there is a reference expressions to the resource group's name in the respective variables. Expressions like this are handy in Terraform and help to avoid fat fingering these types of values several times throughout the template. Our template if fairly short and trivial but deployments can be much larger and expressions are tools that we can use to ensure continuity in our template. At times, you may find yourself confused about which properties you need on a resource. You can sanity check with the Azure ARM Template Schema documentation and use it to compare against the Terraform resource documentation.
The next step is the flesh our you variable blocks in a separate file: variables.tf Remember how we used variables before for the provider specification block? We will create a file that will populate those variables now. Create a variables.tf file and ensure that this file is in the same folder as your main.tf file. Create your variable blocks, ensuring that you set the sensitive descriptor for sensitive or secret values and other constraints. Ensure that you include information about the variable, including validation information. You could have blocks that look something like this (taken from a different template):

None of the information is mandatory for any of the variables but it is good to have your variable specifications ready to go. Don’t leave your variables specs and constraints until after testing! Make sure you test you deployment with the constraints in place tonce you have your variables.tf file, when we run the Terraform Plan command, Terraform will look for these files ending in .tf in order to compose the deployment. Unless we specify the values for these variables at the time of deployment, Terraform will prompt for them at run time. In the same folder as our main.tf and variables.tf files, we will create another file called variables.tfvars. This will allow us to bootstrap and test our deployment with prepopulated variables. A .tfvars file looks something like this:

As we can see, one variable per line, each of the variables that we use for deployment is specified. Ensure that if you are using source control online that you do not check this file in as it may contain sensitive values and even if it doesn’t, there may be information that can be used to compromise your deployment.
Now that we have our variables files and main resource file, you will want to test your deployment. Open the terminal for Visual Studio Code and navigate to the folder where the newly created Terraform files are located. Run 'terraform init'. You should see the below message that the required providers are downloaded and that the lock file has been create so that Terraform knows what versions of providers were used for this deployment:

I have run this deployment several times in preparation for this demo which is why we see 'Reusing previous version of <author/module>' This information is contained in the lock file that gets created when you run terraform init. Otherwise it would say '
Finding previous version of <author/module>'
Now run 'terraform plan -var-file <path to variables.tfvars>'. Note that the screenshot is taken from another deployment to give you an example of the output.We

The output of the plan command shows us what will be created/deleted/updated as part of our deployment. As you can tell from the screenshot, we can specify the out parameter to save the file. Terraform is also reaching out to Azure to see what infrastructure is already there, if any, and would output any update or delete actions if the current deployment called for them. Lets run 'terraform apply' to run our deployment. Terraform will once again display the plan of the deployment and prompt for an answer to confirm the deployment. Enter 'yes' Terraform will update as to the state of the deployment as it goes until it is finished. Once the deployment has successfully completed, you will see your resources in Azure. Using the 'terraform destroy' command, you will once again be prompted to confirm. Terraform will then destroy the resources. See Part 3 of this series for how I transpose ARM templates to Terraform.
Commenti