Terraform state allows for terraform to understand what resources to add, update or delete. When using terraform, the state file is initially stored locally on your computer. This becomes a problem if you are working in a production environment for these couple reasons:
- Terraform state files can contain sensitive information
- No ability to share environment resources with team members for collaboration
- No central backup location for state file which holds all environment resources
So with that here are a list of advantages to storing your terraform state in an azure storage account.
- State locking: When running terraform apply, terraform puts a lock on the .tfstate file to prevent other terraform executions at the same time.
- Encryption at rest: Azure storage provides encryption to your file when stored.
- Redundancy: Azure provides redundancy since the blob storage is always replicated.
Before getting started you will need to have a free azure account created, terraform and azure cli installed.
Create an azure service principal user azure cli
In order to be able to create resources in azure we need to create an account we can authenticate with. To create a service principal first you need to login to the azure cli using:
az login
Once logged in, if you have more than one subscription take the subscription_id which is the “id” field you want and run the command
az account set --subscription="Subscription_ID"
Now we will create a service principal account that will have the “contributor” role using the following command:
az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/SUBSCRIPTION_ID"
Once the output displays on the screen, we need to login as the service principal running the following command:
az login --service-principal --username "appid" --password "password" --tenant "tenant"
Create azure remote state storage account
Before we can utilize azure as our backend we need to create an azure storage account to store the remote state file. We will create this outside of terraform that way the tfsate does not get automatically deleted if we destroy our terraform environment. Run these commands from your console:
$RESOURCE_GROUP_NAME="tfstate"
$STORAGE_ACCOUNT_NAME="tfstate$(get-random)"
$CONTAINER_NAME="tfstate"
# 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
# Create blob container
az storage container create --name $CONTAINER_NAME --account-name $STORAGE_ACCOUNT_NAME
Create azure storage account backend
Now that we have everything put together, we can run terraform plan and terraform apply.
First we need to add the terraform block referencing the new backend.
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=3.23.0"
}
}
backend "azurerm" {
resource_group_name = "tfstate"
storage_account_name = "tfstate755331626"
container_name = "tfstate"
key = "terraform.tfstate"
}
}
provider "azurerm" {
features {}
}
you will need to fill the backend “azurerm” values in with the required values that match your configuration. In order for you to access your storage container you need a key that you can obtain by running:
az storage account keys list --resource-group tfstate --account-name <name of storage account>
you should get a list of keys that will then allow you to run the following command to put the key in an environment variable for terraform to see
$env:ARM_ACCESS_KEY="access key"
Next you want to copy the below code into your editor of choice and put the following commands in: terraform init, terraform plan, terraform apply.
You will now see that your local tfstate file will no longer have anything in it or will be gone. Now go to your storage container in azure and you should now see your tfstate file.
Conclusion
You discovered how to secure Terraform state in an Azure Storage Account in this lesson. The authoritative document for Terraform setup and deployment is the Terraform state file. While learning and testing can be done using a local state file, you should create a strategy for managing distant state files. When performing true infrastructure-as-code inside of an automated CI/CD pipeline for infrastructure deployments, having a remote state file is beneficial for team collaboration.