Terraform AzureRM Backend

One of the primary items I wanted to accomplish before my latest use of Terraform in production was storing the state file in a central location for shared use within my team.

This is controlled in Terraform by the “backend“. In my particular case, I was interested in the AzureRM backend.

There are a few ways to accomplish this configuration, but one of my requirements was to not actually store any key string in a file. Rather, I’m relying upon the Azure Cloud Shell as my deployment environment for Terraform, which I will have already authenticated to and can dynamically connect to resources within my subscription.

First I define a simple “backend.tf” file.

terraform {
    backend "azurerm" {}
}

Next, I wrote a wrapper script (“InitWrapper.ps1”) to actually run my “Terraform Init” command, passing in the variables for the backend as documented by Terraform.

 
$subscription_id = "e86a3dce" #
$resource_group = "Default"
$storage_account = "terraformstates"
$containerName = "Client1"
 
# Get the Storage Account Key for use in loading the backend file
Select-AzureRmSubscription -SubscriptionId $subscription_id
$accountKey = (Get-AzureRmStorageAccountKey -ResourceGroupName $resource_group -Name $storage_account)[0].Value
 
# Perform init
terraform init `
    -backend-config="storage_account_name=$storage_account" `
    -backend-config="container_name=$containerName" `
    -backend-config="access_key=$accountKey" `
    -backend-config="key=prod.terraform.tfstate"

You can see here I’m referencing a storage account, and a blob container. This way you can isolate state files within a container for purposes of RBAC or management.
The last parameter I’m passing in is “key” which tells Terraform what to name the state file.

The end result of running this is a file in my Azure Cloud Shell share (/home/azureuser/clouddrive/client1 is where I would typically change directory to) named “terraform.tfstate” which is a pointer to my backend sitting in an Azure storage account blob container.

Now I no longer need to run the init file unless there are specific Terraform changes that need to be initialized in my cloud shell.

If another team member wishes to work with the same state file, they can run the Init wrapper, and their local state pointer will connect to the same “prod.terraform.tfstate” and be able to create/modify infrastructure in the same way.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.