In this post, I want to show you how to configure terraform to use an Azure storage account to store and protect your tfstate file. To manage the infrastructure and configuration, Terraform writes the status of resources to a tfstate file. By default, this file is called “terraform. tfstate” and is stored locally in JSON format but can also be stored remotely. It is created by Terraform the first time the terraform plan command is run and will use it each time it is run to compare its state with that of the target infrastructure and return the preview of the changes to be made.
Storing the tfstate file in an Azure storage account gives us several advantages, such as:
- State locking: Terraform creates a file lock on the state file when running terraform apply, preventing other terraform executions against this state file.
- Encryption at rest: data stored in an Azure blob is encrypted before being persisted.
- Redundancy: The data in Azure Blob Storage is always replicated to ensure durability and high availability.
Prerequisites
- This tutorial assumes that you already have a Microsoft Azure account configured.
- You can use an existing Storage Account, or you can create a new one. If you want to know how to create a Storage Account using PowerShell, check out this link.
Create a container
The first thing we need to do is create a container in our storage account to locate the tfstate file. To perform this task, we can use Powershell or Azure CLI. In the following examples, I used variables for a more straightforward reading of the code and code reuse.
Azure PowerShell Workaround
To create a container in the storage account, use the New-AzStorageContainer cmdlet with the following syntax.
1 2 3 4 5 6 7 8 9 10 11 12 | $resourceGroupName = "RG-DEMO-TF" $storageAccountNam = "storageaccountdemostf" $containerName = "terraform" $storageAccount = Get-AzStorageAccount -Name "$storageAccountName" ` -ResourceGroupName $resourceGroupName New-AzStorageContainer -Name $containerName ` -Context $storageAccount.Context ` -Permission blob |
Azure CLI Workaround
In this case, you used the Azure Cloud Shell bash console. To create a container on the storage account, use the following command.
1 2 3 4 5 6 | storageAccountName = az storage account show --name $storageAccountName --query name -o tsv containerName="terraform" az storage container create --name $containerName --account-name $storageAccountName \ |
Terraform Backend block
To store the state file in the blob container created in the previous step, you should include the backend block in your “main.tf” file. The configuration data of this block depends on the authentication method used.
Service Principal
If you use this authentication method, you should specify the following values.
1 2 3 4 5 6 7 8 9 10 | terraform { backend "azurerm" { resource_group_name = "RG-DEMO-TF" storage_account_name = "storageaccountdemostf" container_name = "terraform" key = "terraform.tfstate" } } |
Managed Service Identity
If you use Managed Service Identity as an authentication method, specify the following values in the “backend” block.
1 2 3 4 5 6 7 8 9 10 11 12 | terraform { backend "azurerm" { storage_account_name = "storageaccountdemostf" container_name = "terraform" key = "terraform.tfstate" use_msi = true subscription_id = "<your_subscription_id>" tenant_id = "<your_tenant_id>" } } |
Storage Account Access Key
If you prefer a Storage Account Access Key as an authentication method, you should define the following values in the backend block.
1 2 3 4 5 6 7 8 9 10 | terraform { backend "azurerm" { storage_account_name = "storageaccountdemostf" container_name = "terraform" key = "terraform.tfstate" access_key = "<your_storage_account_access_key>" } } |
Storage Account SAS Token
And finally, if the authentication method used by you is a SAS Token, the backend block should contain the following values.
1 2 3 4 5 6 7 8 9 10 | terraform { backend "azurerm" { storage_account_name = "storageaccountdemostf" container_name = "terraform" key = "terraform.tfstate" sas_token = "<your_storage_account_sas_token>" } } |
Create and apply a Terraform execution plan
In this example, I will run it from my Azure cloud shell session, and my configuration file looks like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | provider "azurerm" { features {} } terraform { backend "azurerm" { resource_group_name = "RG-DEMO-TF" storage_account_name = "storageaccountdemostf" container_name = "terraform" key = "terraform.tfstate" } } resource "azurerm_resource_group" "rg"{ name = "rg_test" location = "westeurope" tags = { enviroment = "www.jorgebernhardt.com" } } |
Initialize configuration
You should use the following command to create the “main.tf” file in the Azure cloud shell.
1 2 3 | . code main.tf |
And paste or write the content of your local “main.tf” file and then run the following commands.
1 2 3 4 5 | terraform init terraform validate |
If configuration file validation is correct, you can run the following commands.
1 2 3 | terraform plan |
Once the terraform plan command is executed, the state file is created in the container defined in the configuration file. To see the contents of the state file, you should use the following command.
1 2 3 | terraform state pull |
As you can see, the state file has no defined resources yet. Once the following command is run, the newly created resource will be registered.
1 2 3 | terraform apply |
Reverse a Terraform execution plan
if you want to delete the resource group created in this example, you can use the following command
1 2 3 | terraform destroy |
Thanks for reading my post. I hope you find it helpful.
If you want to learn more about Terraform backends, check out this link.