Sunday, August 13, 2017

Getting started with Terraform

When I look back at my time with Azure, I've made the progression from portal, to powershell, to ARM templates.  As I am writing more and more infrastructure-as-code, I'm always looking for better ways to execute deployments as part of a build/release pipeline.  For a while now, Terraform has been on my list of technologies to look in to.  The goal of this post is to provide a brief intro into terraform and build a simple storage account via template.

What is Terraform?

According to their website, Terraform is a "tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions."

Terraform excites me for a few reasons, namely:
  • The fact that there is a plan step, allowing you to confirm changes
  • The fact that it is open-source
  • The fact that you can add on other providers (custom or otherwise
Obviously, Terraform is an abstraction language, and comes with the various downfalls of this approach.  It'll be interesting to see where the limitations are.

Installing Terraform

There are two ways you can access terraform, and it really depends on what you are trying to do.  Firstly, and probably the easiest, is you can download a binary.  The second is that Hashicorp does release a docker container with the executable on it.   

Initially I had opted for the docker container, but I was having issues with my docker for windows setup and sharing drives, so I resorted to using the executable.

Configuring the AzureRM Provider

Terraform has the concepts of providers, and you need to initialize one to connect to AzureRM.  The provider configuration looks something like the following:

provider "azurerm" {
  subscription_id = "..."
  client_id       = "..."
  client_secret   = "..."
  tenant_id       = "..."

The authentication mechanism is using Service principals, and you will have to set something up.  There is a script that you can download to automate the process, but I just ran the commands manually.

What I like about the providers it that you can default the pulling of credentials to use environment variables.  This is a step up from putting the provider details in code.  I'm sure there are more secure ways of passing in credentials which I haven't gotten to yet.  In order to mitigate risk here, I only gave access to this service principal to the required resource group.

The storage account resource

The definition for this was surprisingly easy.  Here is my code:

resource "azurerm_storage_account" "shamtestterraform" {
    name = "shamtestterraform1"
    resource_group_name = "terraformTest"
    location = "westus"
    account_type = "Standard_LRS"

    tags {
        environment = "test"

You can find information on the resource definition using this link.

Deploying via Terraform

There are a couple of steps that you can perform to start a deployment via Terraform.

Step 1 is to run "terraform init"

Essentially this step confirms the provider is setup correctly and installs required modules/code to make everything run.

Step 2 is to run "terraform plan"

This is one of the main reasons why I like the idea of Terraform.  Essentially this step will refresh the current state and then compare the code being applied to the that state.  It will produce a report as to what will be created/updated/destroyed.

Here is a screenshot of what this looks like:

Pretty cool.

Step 3 is to run "terraform apply"

This essentially applies to code to the targets.  Creating a storage account is pretty simple and resulted in only one event in Azure.

What is interesting to note is that this does not create an ARM template and then do a deployment.  It is calling the API directly.  At a later date, I want to crack open the code and have a look and what it is actually doing.

Now that you are deployed, you could run "terraform destroy" to remove any created resources.

In conclusion, the goal of this post was to experiment with Terraform on a very simple Azure deployment.  So far, I like what I see, and I hope to create more with Terraform in the future.