How to setup terraform with remote state Azure storage

In our previous post we have seen about using AWS s3 as remote state for terraform, In this article we are going to see how we can implement Azure storage as terraform backend.

How to setup terraform with remote state Azure storage

What we are trying to solve here? collaborative environment, secure your sensitive information in your terraform files and prevents from accidental deletes in your local environment.

We need to create Azure storage account to get started, save the following content in setup.sh.

#!/bin/bash

RESOURCE_GROUP_NAME=tstate-mobilelabs
STORAGE_ACCOUNT_NAME=tstatemobilelabs
CONTAINER_NAME=tstatemobilelabs

# Create resource group
az group create --name $RESOURCE_GROUP_NAME --location eastus

# Create storage account
az storage account create --resource-group $RESOURCE_GROUP_NAME --name $STORAGE_ACCOUNT_NAME --sku Standard_LRS --encryption-services blob

# Get storage account key
ACCOUNT_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP_NAME --account-name $STORAGE_ACCOUNT_NAME --query [0].value -o tsv)

# Create blob container
az storage container create --name $CONTAINER_NAME --account-name $STORAGE_ACCOUNT_NAME --account-key $ACCOUNT_KEY

echo "storage_account_name: $STORAGE_ACCOUNT_NAME"
echo "container_name: $CONTAINER_NAME"
echo "access_key: $ACCOUNT_KEY"

Run this script to create Azure Storage account.

sh ./setup.sh

Output

storage_account_name: tstatemobilelabs
container_name: tstatemobilelabs
access_key: *****

Now save this in .env file for later use and then export this access key to the ARM_ACCESS_KEY

ARM_ACCESS_KEY=<storage access key from previous step> 

We have created new storage account and storage container to store our terraform state.

Lets initialise terraform cli

Create a backend.tf file with the following content.

terraform {
  backend "azurerm" {
    resource_group_name   = "tstate-mobilelabs"
    storage_account_name  = "tstatemobilelabs"
    container_name        = "tstatemobilelabs"
    key                   = "terraform.tfstate"
  }
}

We have confiured terraform should use azure storage as backend with the newly created storage account.

Create a main.tf file with the following content.

# Configure the Azure Provider
provider "azurerm" {
  # whilst the `version` attribute is optional, we recommend pinning to a given version of the Provider
  version = "=2.0.0"
  features {}
}

# Create a resource group
resource "azurerm_resource_group" "rg" {
  name     = "mobilelabs"
  location = "West Europe"
}

# Create a virtual network within the resource group
resource "azurerm_virtual_network" "example" {
  name                = "mobilelabs-network"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  address_space       = ["10.0.0.0/16"]
}

In this we have terraform code to create a virtual network for demonstration purpose.

terraform init will bootstrap our local workspace.

terraform init

Above command will download the required backend modules and connect our local terraform state to the azure storage backend.

Now, run!

terraform plan

Output

Acquiring state lock. This may take a few moments...
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:

  • create

Terraform will perform the following actions:

azurerm_resource_group.rg will be created

  • resource "azurerm_resource_group" "rg" {
    • id = (known after apply)
    • location = "westeurope"
    • name = "mobilelabs"
      }

azurerm_virtual_network.example will be created

  • resource "azurerm_virtual_network" "example" {
    • address_space = [

      • "10.0.0.0/16",
        ]
    • id = (known after apply)

    • location = "westeurope"

    • name = "mobilelabs-network"

    • resource_group_name = "mobilelabs"

    • subnet {

      • address_prefix = (known after apply)
      • id = (known after apply)
      • name = (known after apply)
      • security_group = (known after apply)
        }
        }

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


Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

Releasing state lock. This may take a few moments...

Our state file will be created in our azure storage account.

terraform azure storage backend - mobilelabs

Time to create virtual network using the terraform code.

terraform apply
terraform azure storage backend - mobilelabs

Our virtual network is created in our azure portal

terraform azure storage backend - mobilelabs
terraform azure storage backend - mobilelabs

Time for clean up

when we no longer need the created resource we can run terraform destory command to clean up the created resources.

terraform destroy -auto-approve
terraform azure storage backend - mobilelabs

For more information about using Azure storage as a terraform backend refer https://www.terraform.io/docs/providers/azurerm/index.html

Looking for terraform s3 backend?

How to setup terraform with remote state s3
Terraform stores the state locally by default in the local project directory but we can also store this state remotely using the terraform backend.
terraform s3 backend - mobilelabs