DBAtlas · Atlas de operaciones de bases de datos

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.name

5. 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.tfplan

7. 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
Abrir en DBAtlas →