kb.erickguedes.com
Terraform: Infraestrutura como Código

State Management

Aula 2 de 7

Entendendo o State

O state file mapeia recursos declarados no código para recursos reais no provedor. É o "source of truth" do Terraform.

{
  "version": 4,
  "terraform_version": "1.10.0",
  "resources": [
    {
      "module": "root",
      "mode": "managed",
      "type": "aws_instance",
      "name": "web",
      "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
      "instances": [
        {
          "attributes": {
            "id": "i-0a1b2c3d4e5f",
            "public_ip": "203.0.113.10"
          }
        }
      ]
    }
  ]
}

Nunca edite o state manualmente. Use comandos específicos.

Remote State + Locking

terraform {
  backend "s3" {
    bucket         = "terraform-state-company"
    key            = "network/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}
# Criar bucket + tabela de lock (fora do Terraform, bootstrap)
aws s3 mb s3://terraform-state-company
aws dynamodb create-table \
  --table-name terraform-locks \
  --attribute-definitions AttributeName=LockID,AttributeType=S \
  --key-schema AttributeName=LockID,KeyType=HASH \
  --billing-mode PAY_PER_REQUEST

Data Sources — Ler State de Outra Stack

# data "terraform_remote_state" — ler outputs de outra stack
data "terraform_remote_state" "network" {
  backend = "s3"
  config = {
    bucket = "terraform-state-company"
    key    = "network/terraform.tfstate"
    region = "us-east-1"
  }
}

# Usar outputs da stack network
resource "aws_instance" "app" {
  subnet_id = data.terraform_remote_state.network.outputs.public_subnet_id
}

State Commands

# Listar recursos no state
terraform state list

# Mostrar detalhes de um recurso
terraform state show aws_instance.web

# Mover recurso (renomear ou mover entre módulos)
terraform state mv aws_instance.web aws_instance.app_server

# Remover do state (sem destruir recurso)
terraform state rm aws_s3_bucket.legado

# Importar recurso existente
terraform import aws_instance.web i-0a1b2c3d4e5f

# Substituir recurso degradado
terraform apply -replace="aws_instance.web"

Workspaces — Múltiplos Ambientes

# workspaces criam state files separados
# produção: terraform.tfstate.d/prod/
# staging:  terraform.tfstate.d/staging/

resource "aws_instance" "app" {
  instance_type = terraform.workspace == "prod" ? "t3.large" : "t3.micro"
  tags = {
    Environment = terraform.workspace
  }
}
terraform workspace new dev
terraform workspace new staging
terraform workspace new prod

terraform workspace select staging
terraform apply -var-file="staging.tfvars"

# Listar workspaces
terraform workspace list

Sensitive Data

# Marcar output como sensitive
output "db_password" {
  value     = random_password.db.result
  sensitive = true
}

# Armazenar secrets no state é inevitável
# Mitigação: usar Vault ou AWS Secrets Manager
data "aws_secretsmanager_secret_version" "db" {
  secret_id = "prod/db/password"
}

resource "aws_db_instance" "main" {
  password = data.aws_secretsmanager_secret_version.db.secret_string
}

O state contém todos os IDs e configurações dos seus recursos (às vezes senhas). Proteja o state: bucket com acesso restrito, encryption at-rest e in-transit, lock com DynamoDB.