Aprovisionamiento de bases de datos con Terraform (IaC)
Síntoma
Objetivo: definir la infraestructura de base de datos (instancia, grupo de parámetros, red) como código (Infrastructure as Code) con Terraform; configurar el flujo plan/apply, el estado remoto y la gestión del drift.
1. Elija y configure el provider (aws / google / azurerm)
Defina el provider de la nube en la que trabaja y fije su versión. Fije el provider hashicorp/aws para AWS, hashicorp/google para GCP y hashicorp/azurerm para Azure en el bloque required_providers. Fijar la versión garantiza un comportamiento coherente en todo el equipo.
PostgreSQL
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "eu-central-1"
}2. Configure el estado remoto y el bloqueo
No mantenga el archivo de estado en local; use un backend remoto para el trabajo en equipo y la seguridad. Las opciones habituales son el backend S3 + una tabla de bloqueo DynamoDB en AWS, el backend gcs en GCP y el backend azurerm (Storage Account) en Azure. El estado remoto evita applies simultáneos mediante el bloqueo y convierte el estado en la única fuente de verdad. Como puede haber contraseñas en texto plano en el estado, mantenga el backend cifrado y con acceso restringido.
PostgreSQL
terraform {
backend "s3" {
bucket = "company-tfstate"
key = "db/terraform.tfstate"
region = "eu-central-1"
dynamodb_table = "tf-lock"
encrypt = true
}
}3. Defina el recurso de base de datos
Escriba el recurso principal para su motor y su nube: aws_db_instance en AWS (o aws_rds_cluster para Aurora), google_sql_database_instance en GCP, azurerm_mssql_database en Azure (para SQL Server, bajo un azurerm_mssql_server). Especifique aquí el motor, la versión, la clase, el almacenamiento y la ventana de backup.
PostgreSQL
resource "aws_db_instance" "pg" {
identifier = "app-db"
engine = "postgres"
engine_version = "16"
instance_class = "db.t3.medium"
allocated_storage = 50
db_name = "appdb"
username = "pgadmin"
password = var.db_password
backup_retention_period = 7
}SQL Server
resource "azurerm_mssql_database" "db" {
name = "appdb"
server_id = azurerm_mssql_server.srv.id
sku_name = "S1"
}4. Escriba el grupo de parámetros como código
Defina la configuración de la base de datos (max_connections, work_mem, juego de caracteres) con un recurso de parámetros, no manualmente en la consola. Use aws_db_parameter_group en AWS, settings.database_flags dentro de google_sql_database_instance en GCP y el recurso de configuración del servidor en Azure. Así la configuración queda versionada y es reproducible.
PostgreSQL
resource "aws_db_parameter_group" "pg" {
name = "app-pg16"
family = "postgres16"
parameter {
name = "max_connections"
value = "200"
}
}
# inside aws_db_instance:
# parameter_group_name = aws_db_parameter_group.pg.name5. Pase los secretos mediante variables y un gestor de secretos
No escriba la contraseña directamente en un archivo .tf; defínala como variable sensible (variable ... sensitive = true) y proporcione el valor mediante una variable de entorno TF_VAR_, un gestor de secretos (AWS Secrets Manager, Vault) o un secreto de CI. Recuerde: el valor se escribe en el archivo de estado, por lo que el estado remoto debe estar cifrado. El enfoque más limpio es no pasar nunca la contraseña a Terraform y leerla desde un recurso del gestor de secretos.
PostgreSQL
variable "db_password" {
type = string
sensitive = true
}
# CI/shell:
export TF_VAR_db_password="$(vault kv get -field=pw secret/db)"6. Ejecute el flujo plan y apply
Primero prepare el provider/backend con terraform init, vea qué va a cambiar con terraform plan, apruebe y aplique con terraform apply. No aplique sin revisar la salida del plan; el flujo seguro en CI es publicar el 'plan' como comentario en el PR y aplicar tras la aprobación humana. Detecte los cambios destructivos (p. ej., la recreación de la instancia) por el marcador -/+ en la salida del plan.
PostgreSQL
terraform init
terraform plan -out=plan.tfplan
terraform apply plan.tfplan7. Detecte y corrija el drift
Si alguien hace un cambio manual en la consola, la infraestructura real y el estado divergen (drift). Las diferencias que aparecen en terraform plan 'cuando nada debería haber cambiado' revelan el drift; la diferencia se lee con terraform refresh/plan. Refleje el cambio de vuelta en el código o devuelva la infraestructura al estado del código con apply. Prohíba los cambios manuales como norma; el código debe ser la única fuente de verdad.
PostgreSQL
# drift check (when no changes are expected):
terraform plan
# expect 'No changes'; any diff means drift
# bring an existing resource into state with import:
terraform import aws_db_instance.pg app-db