Remote Terraform State file (terraform.tfstate) en Azure Blob Storage

Terraform nos permite realizar implementaciones de IaC. Podemos aplicar y destruir infraestructura de una manera rapida y automatizada. Para poder realizar estas operaciones uno de los archivos fundamentales de Terraform es el archivo <terraform.tfstate>

¿Que es y para que se utiliza el State en Terraform?

Terraform necesita almacenar el estado o “state” de la infraestructura y su configuracion. Esta información “del mundo real” es almacenada en el archivo <terraform.tfstate>. Almacenando el estado de los recursos y sus dependencias, Terraform puede determinar qué cambios necesita aplicar a la infraestructura existente para alcanzar el estado deseado definido en el código: el “desired state”.

Este archivo guarda la información de los recursos que Terraform ha creado o configurado y se mantiene actualizado a medida que se generan cambios en la infraestrctura bajo el radar de la herramienta.

Es crucial manejarlo con cuidado, ya que puede contener información sensible. También es fundamental asegurarse de que el estado no entre en conflictos, especialmente en equipos grandes, mediante el uso de bloqueos o “locking”.

Por defecto, el estado se almacena en el backend “local”: se genera un archivo en el path en el que se encuentren nuestros archivos “.tf”. Sin embargo, en entornos de equipo o para garantizar una mejor seguridad y versionado, es recomendable utilizar backends remotos como Azure Blob Storage, AWS S3, entre otros.

Remote State

El Remote State es la solución recomendada para el trabajo colaborativo con Terraform. Nos permitirá que varias personas/equipos puedan trabajar sobre la misma infarestructura. Mediante un backend de estado completamente funcional, Terraform puede utilizar el State Lock remoto como medida para prevenir que dos o más usuarios ejecuten Terraform simultáneamente, garantizando así que cada ejecución comience con el estado más recientemente actualizado.

Al usar Azure Blob Storage (o cualquier solución de almacenamiento remoto), aseguras que tu estado de Terraform esté centralizado, encriptado, versionado y accesible para aquellos que lo necesiten, lo cual es esencial para la gestión adecuada de la infraestructura con Terraform, especialmente en entornos de equipo y producción.

Ahora, veamos como configurarlo en nuestra subscripción de Azure

Conectarnos a Azure CLI

Debemos realizar el login a nuestro tenant y subscripción de Azure. Para esto debemos ingresar los siguientes comandos en Azure CLI:

  • az login
  • az account list –output table
  • az account set –subscription <SubscriptionId>

Crear ‘tfstate’ Resource Group, Storage Account y Container:

Para crear el ‘tfstate’ Resource Group, Storage Account y Container debemos ejecutar el siguiente script en PowerShell:

$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

Guardar la Access Key como variable de entorno

Para acceder al archivo, Terraform deberá poseer la Access Key del Storage account. Debemos guardar el valor de la clave en una variable de entorno llamada <ARM_ACCESS_KEY>. Para realizar esto debemos ejecutar el siguiente script:

$ACCOUNT_KEY= az storage account keys list --resource-group $RESOURCE_GROUP_NAME --account-name $STORAGE_ACCOUNT_NAME --query '[0].value' -o tsv 

env:ARM_ACCESS_KEY=$ACCOUNT_KEY

Crear nuestro archivo main.tf

Ahora que tenemos nuestro Storage Account listo y terraform tiene el Access Key como una variable de entorno, podemos crear nuestro primer archivo de Terraform. En este archivo configuraremos nuestro provider “AzureRM” y aprovecharemos la ocación para configurar el backend configuration block.

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~>3.0"
    }
  }
  backend "azurerm" {
      resource_group_name  = "tfstate"
      storage_account_name = "<storage_account_name>"
      container_name       = "tfstate"
      key                  = "terraform.tfstate"
  }

}

provider "azurerm" {
  features {}
}

Debemos reemplazar <storage_account_name> con el nombre de nuestro Storage Account.

En este caso será tfstate1953629526.

Inicializar configuración: <Terraform Init>

Inicializaremos la configuración de terraform con el comando <terraform init>

Comprobar creación del archivo

Podemos comprobar que el archivo se encuentra creado en nuestro Container del Blob.

Cómo podemos ver el archivo fue creado en nuestro contenedor. Cabe tambien destacar que Azure Blob Storage soporte el State Lock.

State Lock

  • El bloqueo de estado impide que múltiples operaciones de Terraform se ejecuten simultáneamente en el mismo archivo de estado. Esto es crucial cuando se trabaja en equipos o en sistemas de CI/CD para evitar conflictos.
  • Cuando Terraform comienza a aplicar cambios, adquiere un bloqueo en el archivo de estado. Si otro proceso de Terraform intenta hacer cambios al mismo tiempo, no podrá hacerlo hasta que se libere el bloqueo.
  • El state lock asegura la coherencia y evita la corrupción del archivo de estado.No todos los backends de Terraform admiten el bloqueo de estado. Algunos backends comunes que lo soportan incluyen Azure Blob Storage, Amazon S3 con DynamoDB, y Consul, entre otros.

Al ejecutar <terraform apply> vamos a poder apreciar que se realiza el lock del state:

Como podemos comprobarlo en el archivo de nuestro contenedor en el blob storage:

Terraform Apply

Crearemos un recurso “Resource Group” a modo de prueba:

Luego de realizar apply (y crear un resource group de prueba) podemos verificar que el contenido del archivo de State:


Posted

in

, , ,

by

Comments

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.