Terraform Associate
Deep Dive
Los backends remotos son esenciales para trabajar en equipo: permiten compartir el estado, habilitar el locking y mantener los secretos fuera del disco local. Esta guía cubre los backends más usados y sus diferencias clave.
Contenido
Si no configuras un backend, Terraform usa el backend local por defecto. El estado se almacena en terraform.tfstate en el directorio de trabajo.
✅ Ventajas del backend local
⚠️ Limitaciones del backend local
# Backend local explícito (equivalente al comportamiento por defecto)
terraform {
backend "local" {
path = "terraform.tfstate" # ruta del archivo de estado
}
}
# O simplemente no definir ningún backend — el local es el defaultEl backend S3 es el más usado en entornos AWS. Almacena el estado en un bucket S3 y opcionalmente usa DynamoDB para locking.
terraform {
backend "s3" {
bucket = "mi-empresa-terraform-state" # nombre del bucket S3
key = "prod/vpc/terraform.tfstate" # ruta del archivo dentro del bucket
region = "us-east-1" # región del bucket
# Locking via DynamoDB (RECOMENDADO — sin esto no hay locking)
dynamodb_table = "terraform-state-lock" # tabla DynamoDB
# Cifrado en reposo
encrypt = true # SSE-S3 o SSE-KMS
kms_key_id = "arn:aws:kms:..." # opcional: usar KMS específico
# Perfil AWS (alternativa a variables de entorno)
profile = "mi-perfil-aws" # opcional
}
}
# La tabla DynamoDB debe tener:
# - Nombre: terraform-state-lock (el mismo que dynamodb_table)
# - Clave primaria: LockID (tipo: String)| Argumento | Requerido | Descripción |
|---|---|---|
| bucket | ✅ Sí | Nombre del bucket S3 donde se almacena el estado |
| key | ✅ Sí | Ruta del objeto dentro del bucket (ej: prod/tfstate) |
| region | ✅ Sí | Región AWS del bucket |
| dynamodb_table | ❌ No* | * Sin esto no hay locking. Nombre de la tabla DynamoDB. |
| encrypt | ❌ No | Si true, habilita cifrado SSE del archivo de estado |
| kms_key_id | ❌ No | ARN de la clave KMS para SSE-KMS (más seguro que SSE-S3) |
Azure Storage proporciona locking nativo mediante Blob Leases, sin necesidad de un recurso adicional (a diferencia de S3 + DynamoDB).
terraform {
backend "azurerm" {
resource_group_name = "rg-terraform-state"
storage_account_name = "samiempresatfstate" # nombre único global
container_name = "tfstate" # blob container
key = "prod.terraform.tfstate" # nombre del blob
# Autenticación (varias opciones):
# 1. Variables de entorno ARM_* (recomendado en CI/CD)
# 2. Azure CLI (az login) para uso local
# 3. Managed Identity en VMs/AKS
}
}
# Ventaja sobre S3: el locking es automático via Blob Lease
# No necesitas un recurso adicional para el lockingGCS también proporciona locking nativo, simplificando la configuración respecto a S3.
terraform {
backend "gcs" {
bucket = "mi-empresa-terraform-state" # nombre del bucket GCS
prefix = "terraform/prod" # prefijo para los objetos de estado
# Autenticación: usa Application Default Credentials (gcloud auth)
# O: credentials = "/ruta/a/service-account.json" (no recomendado hardcodear)
}
}
# GCS soporta locking nativo vía object locking
# No necesita recurso adicional (igual que Azure, diferente a S3)HCP Terraform (antes Terraform Cloud) tiene una integración especial más profunda que los backends de almacenamiento tradicionales: no solo almacena el estado sino que también ejecuta los planes y applies remotamente.
# Opción 1: Bloque cloud (recomendado para HCP Terraform)
terraform {
cloud {
organization = "mi-empresa"
workspaces {
name = "prod-vpc" # workspace específico
# O por tags:
# tags = ["prod", "networking"]
}
}
}
# Opción 2: Backend "remote" (forma antigua, aún soportada)
terraform {
backend "remote" {
organization = "mi-empresa"
workspaces {
name = "prod-vpc"
}
}
}
# Autenticación: terraform login
# O: variable de entorno TF_TOKEN_app_terraform_io🎯 cloud vs remote backend
El bloque cloud es la forma moderna de conectar con HCP Terraform (introducido en Terraform 1.1). El backend remote es el método antiguo que sigue funcionando. Para nuevas configuraciones, usa siempre el bloque cloud.
La configuración parcial de backend permite no hardcodear información sensible (credenciales, nombres de buckets) directamente en los archivos .tf.
# CONFIGURACIÓN PARCIAL — no hardcodes credenciales en el bloque backend
terraform {
backend "s3" {
# Solo la configuración estática (no sensible):
region = "us-east-1"
encrypt = true
# bucket, key y dynamodb_table se pasan en init
}
}
# Pasar la config restante en terraform init:
terraform init -backend-config="bucket=mi-empresa-tfstate" -backend-config="key=prod/vpc/terraform.tfstate" -backend-config="dynamodb_table=terraform-lock"
# O desde un archivo HCL (sin el bloque terraform {}):
# backend.hcl:
# bucket = "mi-empresa-tfstate"
# key = "prod/vpc/terraform.tfstate"
# dynamodb_table = "terraform-lock"
terraform init -backend-config=backend.hcl
# MIGRACIÓN DE ESTADO entre backends:
# 1. Cambia el bloque backend en el .tf
# 2. Ejecuta:
terraform init -migrate-state
# Terraform preguntará confirmación para mover el estado| Backend | Locking | Cifrado nativo | Config extra para locking |
|---|---|---|---|
| Local | ❌ No | ❌ No | — |
| S3 | ✅ Sí | ✅ Sí | Tabla DynamoDB requerida |
| Azure Storage | ✅ Sí | ✅ Sí | Ninguno (Blob Lease automático) |
| GCS | ✅ Sí | ✅ Sí | Ninguno (nativo) |
| HCP Terraform | ✅ Sí | ✅ Sí | Ninguno (automático) |
¿Entendiste este tema?
Pon a prueba lo que acabas de aprender
Un equipo quiere usar el backend S3 para el estado de Terraform pero necesita que no aparezcan credenciales ni el nombre del bucket en los archivos .tf del repositorio. ¿Cuál es la solución correcta?