Terraform for Azure: Getting started

I've decided to write a series of blog post on using Terraform for provisioning Azure resources. The series will cover some more advanced topics regarding Terraform, but to start off here's an introduction. There is a lot of resources available covering Terraform, so I'll keep this short.

Terraform is a "Infrastructure as Code" tool to provision cloud resources using a declarative configuration language (JSON). Using such a tool makes sure that the resources you define is provisioned in the same way in every environment you define. Setting up the same resources in the web interface (e.g. Azure Portal, AWS Management Console) of you cloud provider is time consuming and increase the chances of making errors when setting up multiple environments. Defining your infrastructure in code also enables you to check in you infrastructure code in a repository, giving you the benefits of a commit history, required pull request etc. The most important thing is to stop using the web interface and start using code to define your infrastructure

Install and initialize

Enough of that, let's get started. Check the Terraform docs on how to install. I'm running Windows and prefer using Chocolatey. Run the following to install and verify your installation:

choco install terraform
terraform -help

Now create a project folder and create a Terraform file called main.tf. As stated, this blog series will cover Terraform for Azure, so start by defining Azure as the provider of your choice:

provider "azurerm" {
  version = "=2.20.0"
  features {}
}

The Azure Provider will regularly get updates from the Terraform team and contributors to add the latest Azure services and features. You select the version when defining the provider (as shown above). You'll find the repository for the Provider here: https://github.com/terraform-providers/terraform-provider-azurerm. I quite often find myself visiting this repository to check the latest releases or look at issues to find solutions to problems.

Now run the following command in the folder containing the main.tf.

terraform init

You will see that the command line tool installs the terraform provider and hopefully that Terraform has been successfully initialized!

Add a resource

Now you're ready to add some actual Azure resources. The first thing you'll usually need is a Resource Group, so let's create one. Let's start by looking at the documentation. It will show you the following example:

resource "azurerm_resource_group" "example" {
  name     = "my-resource-group"
  location = "West Europe"
}

Pretty straight forward, you select a name and a Azure region as location. But let's look at the full declaration. The "resource" statement is Terraforms way of telling us this is a resource. Obviously. The next string statement is the name of the Terraform resource type. You'll find all supported resource types in the Terraform documentation. The next statement ("example") is the name you want to give the resource when you reference the resource later in the Terraform code. So, if you want to use this Resource Group later, you'll use something like 'azurerm_resource_group.example.name'.

Let's provision this resource to your Azure-subscription! First you have to login to your Azure account and select the correct subscription. To do this, you'll need to install the Azure CLI. You can use Chocolaty, and then connect to your Azure subscription:

choco install azure-cli
az login
az account set --subscription "<GUID of your subscription>"

If you only have one Azure subscription, you won't need to run the last command. If you do, you'll find the "GUID of your subscription" listed when you run "az login".

Next step is to create a execution plan by running:

terraform plan

This will give you an overview of the changes you're about to execute. Something like this:

Terraform will perform the following actions:

  # azurerm_resource_group.example will be created
  + resource "azurerm_resource_group" "example" {
      + id       = (known after apply)
      + location = "westeurope"
      + name     = "example"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

You can check that the plan matches the changes you expect. Notice the "+" in front of each line. It indicates that this is a resource that are going to be added. Resources that are about to be destroyed/deleted are indicated by a "-" and changes are indicated by "~".

You also have the option to output the plan to a file, by using the -out option and selecting a file name. You can use this file to make sure the correct execution plan is used when applying the plan to your Azure subscription. Applying your Terraform code is done by running:

terraform apply

This will trigger Terraform to start provisioning the resources specified to you Azure Subscription, and you'll see something like this:

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

azurerm_resource_group.mywebpage: Creating...
azurerm_resource_group.mywebpage: Creation complete after 1s [id=/subscriptions/xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/resourceGroups/mywebpage-rg]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

If you go to the Azure Portal, the newly create resource group should be available!

So, that it for the introduction. In the next blog I'll cover Terraform State and Terraform Backends