Terraform Remote Backend with AzureRM Provider
Terraform + Azure = :heart:

Introduction

In this blog post we’re going to learn about managing Terraform state remotely, by leveraging Azure Blob Storage.

Prerequisites

Before you can follow this tutorial, you will need the following:

  • An [Azure subscription][azure-subscription]
  • The [Azure CLI][install-az-cli] installed on your computer and logged in to your Azure subscription
  • The [Terraform CLI][install-terraform-cli] installed on your computer

Terraform

What is Terraform?

Terraform is an open-source infrastructure as code (IAC) software tool that enables you to safely and predictably create, change, and destroy infrastructure. Terraform not only allows you to manage cloud infrastructure as code, but also allows you to configure tools such as Kubernetes, F5 Firewalls, Aquasec, and more.

In fact, if there’s has an API that can be used to deploy or configure a resource, Terraform can probably be used to manage it.

Terraform Providers

Providers are the plugins that Terraform uses to interact with various platforms and resources, there are over 3400 providers currently and that number is only increasing. Go over to the [Terraform registry][terraform-providers] and check out the providers that are available, you may be surprised to find out what you can find.

Terraform State

Terraform state is the information that Terraform needs to successfully manage infrastructure. It is used to map resources to configuration, which is then used to track any drift between the two over time. Terraform state is stored in a file called terraform.tfstate by default. If this doesn’t make sense, don’t worry, by the end of this tutorial you will know what Terraform state is, what it is made up of and how to manage it.

Working with Terraform state

When first starting out with Terraform, you’ll most likely start out by just storing your Terraform state locally, in a file called terraform.tfstate.

This is fine for testing and learning, but as soon as you start working with a team or in a production, you’ll need to start thinking about how to manage your Terraform state remotely, so it can be used collaboratively. Even if you’re working alone or in a small team, it’s a good idea to start thinking about this early on.

Why store Terraform state remotely?

You may be wondering why you should use store your state files remotely.

Well there are many benefits, here are some of them:

  • Provides a central place for your terraform state, so it can be used by other team members and can be used in CI/CD pipelines.
  • Reduces the risk of losing your state, or having different versions of it.
  • Makes it easier to manage your infrastructure across multiple environments
  • Reduces the chances of sensitive values falling into the wrong hands

State locking

State locking is a feature that prevents two people from updating the state file at the same time. Not all backends have this feature, but Azure Blob Storage does.

More info on state locking can be found [here][state-locking].

The fun part! Let’s get started!

Enough of the theory! We will now be going through practical examples of how to set up a remote backend for Terraform using the AzureRM provider and an Azure Storage Account. We will also go through what happens to your state when you plan and apply changes to your infrastructure, the different ways in how you can view your state and how to manage state.

Setting up the storage account

To set up the remote backend, you will need to create an Azure storage account and a container. You can do this using the Azure CLI, the name of the storage account must be globally unique.

Note: to follow along, it’s recommended that you create a new directory to put your terraform code into and make sure that is the current working directory.

For this example I’m going to create a storage account called tdstfstatedemo and a container called tfstate. I will create these resources in a resource group call rg-tfstate-demo.

You will need to at least need to replace the name of the storage account for the commands below to work.

az storage account create --name tdstfstatedemo --resource-group rg-tfstate-demo
az storage container create --name tfstate --account-name tdstfstatedemo

You should now have your own storage account and container, which you can use to store your Terraform state.

Configure and initialise the remote backend

Once you have created the storage account and container, you need to configure the Terraform remote backend.

Create a file called providers.tf and add the following to it, changing the name of the storage account and anything else you created in the previous step:

terraform {
  backend "azurerm" {
    resource_group_name  = "rg-tfstate-demo"
    storage_account_name = "tdstfstatedemo"
    container_name       = "tfstate"
    key                  = "remote-backend-demo/terraform.tfstate"
  }
}

provider "azurerm" {
  features {}
}

You should now be able to initialise Terraform and see that the remote backend has been configured:

terraform init

You should get a similar output to the below, meaning your initialisation was successful:

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

If we run a terraform plan now, we should see that there are no changes to be made as we haven’t defined any resources yet:

terraform plan

output:

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

Exploring the terraform state file

Before we do anything else, let’s spend a bit of time checking out the state file and making sure that we are actually storing our state remotely.

Use the following command to download the state file (update the storage account name):

az storage blob download --container-name tfstate --name remote-backend-demo/terraform.tfstate --file remote-terraform.tfstate --account-name tdstfstatedemo

cat remote-terraform.tfstate

Note: You will probably never need to use this command again when working with terraform state as you can use the terraform CLI to download the state file using the terraform state pull command. For this example though, I’m using the Azure CLI to prove to you that the state is actually stored in our storage account.

You should see something similar to the below:

{
  "version": 4,
  "terraform_version": "1.5.2",
  "serial": 1,
  "lineage": "9205abdc-9fa3-3cbd-3760-d4faa61b71b0",
  "outputs": {},
  "resources": [],
  "check_results": null
}

To dig a bit deeper into terraform state and how to manage it, head over to our blog on managing terraform state.

Conclusion

Awesome! We have just set up a remote backend for Terraform using the AzureRM provider and an Azure Storage Account! Hopefully you now have a better understanding of how to manage your Terraform state remotely by setting up a remote backend.

Thanks!

Terraform Remote Backend with AzureRM Provider
Older post

Getting started with cue templating

Get an idea on how to use cue, a data templating language

Newer post

Managing Terraform state

Learn how you can view Terraform state and manage the resources in it.

Terraform Remote Backend with AzureRM Provider