DBAtlas · Atlas de operações de banco de dados

Provisionamento de bancos com Terraform (IaC)

Sintoma

Objetivo: definir a infraestrutura do banco (instância, parameter group, rede) como código (Infrastructure as Code) com Terraform; montar o fluxo plan/apply, o remote state e o gerenciamento de drift.

1. Escolha e configure o provider (aws / google / azurerm)

Defina o provider da nuvem em que você roda e fixe sua versão. Trave o provider hashicorp/aws para AWS, hashicorp/google para GCP e hashicorp/azurerm para Azure no bloco required_providers. Fixar a versão garante um comportamento consistente em toda a equipe.

PostgreSQL

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "eu-central-1"
}

2. Configure o remote state e o locking

Não mantenha o arquivo de state localmente; use um backend remoto para trabalho em equipe e segurança. As escolhas comuns são o backend S3 + uma tabela de lock no DynamoDB na AWS, o backend gcs no GCP e o backend azurerm (Storage Account) no Azure. O remote state evita applies simultâneos por meio do locking e faz do state a única fonte da verdade. Como senhas podem ficar no state em texto puro, mantenha o backend criptografado e com acesso restrito.

PostgreSQL

terraform {
  backend "s3" {
    bucket         = "company-tfstate"
    key            = "db/terraform.tfstate"
    region         = "eu-central-1"
    dynamodb_table = "tf-lock"
    encrypt        = true
  }
}

3. Defina o recurso do banco

Escreva o recurso principal para o seu engine e nuvem: aws_db_instance na AWS (ou aws_rds_cluster para Aurora), google_sql_database_instance no GCP, azurerm_mssql_database no Azure (para SQL Server, sob um azurerm_mssql_server). Especifique aqui engine, versão, classe, armazenamento e janela 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. Escreva o parameter group como código

Defina as configurações do banco (max_connections, work_mem, conjunto de caracteres) com um recurso de parâmetros, não manualmente no console. Use aws_db_parameter_group na AWS, settings.database_flags dentro de google_sql_database_instance no GCP e o recurso de configuração do servidor no Azure. Assim as configurações ficam versionadas e reproduzíveis.

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. Passe segredos por variáveis e um secrets manager

Não coloque a senha fixa em um arquivo .tf; defina-a como variável sensível (variable ... sensitive = true) e forneça o valor por uma variável de ambiente TF_VAR_, um secrets manager (AWS Secrets Manager, Vault) ou um segredo de CI. Lembre-se: o valor é gravado no arquivo de state, então o remote state precisa ser criptografado. A abordagem mais limpa é nunca passar a senha ao Terraform e lê-la de um recurso de secrets manager.

PostgreSQL

variable "db_password" {
  type      = string
  sensitive = true
}

# CI/shell:
export TF_VAR_db_password="$(vault kv get -field=pw secret/db)"

6. Execute o fluxo plan e apply

Primeiro prepare o provider/backend com terraform init, veja o que vai mudar com terraform plan, aprove e aplique com terraform apply. Não aplique sem revisar a saída do plan; o fluxo seguro em CI é postar o 'plan' como comentário no PR e aplicar após aprovação humana. Identifique mudanças destrutivas (ex.: recriação da instância) pelo marcador -/+ na saída do plan.

PostgreSQL

terraform init
terraform plan -out=plan.tfplan
terraform apply plan.tfplan

7. Detecte e corrija o drift

Se alguém fizer uma alteração manual no console, a infraestrutura real e o state divergem (drift). Diferenças que aparecem no terraform plan 'quando nada deveria ter mudado' revelam o drift; a diferença é lida com terraform refresh/plan. Ou leve a alteração de volta para o código, ou traga a infraestrutura de volta ao código com apply. Proíba alterações manuais como regra; o código deve ser a única fonte da verdade.

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 no DBAtlas →