Quem usa Terraform ou OpenTofu com estado remoto na AWS sabe: o backend S3 clássico exige uma tabela DynamoDB para locking. Isso adiciona um recurso extra para criar, manter e pagar. A partir do OpenTofu (e Terraform 1.10+), dá para usar lock file nativo direto no S3, sem DynamoDB.

Por que locking é importante?

Estado do Terraform/OpenTofu guarda o mapeamento entre recursos reais e o código. Se duas execuções (ou duas pessoas) rodarem tofu apply ao mesmo tempo, o estado pode ser corrompido. O locking garante que só uma execução escreva no estado por vez.

Antes, a receita era: S3 para armazenar o .tfstate e DynamoDB para guardar um “lock” (chave + condição). Funciona, mas exige:

  • Criar e manter uma tabela DynamoDB
  • Configurar IAM para a tabela
  • Mais um recurso na conta

Lock file nativo no S3

O backend S3 passou a suportar lock file nativo usando apenas o próprio bucket: um arquivo de lock (por exemplo .tflock) no S3 e conditional writes garantem que só uma execução escreva no estado por vez. Nada de DynamoDB.

Basta um bucket S3 normal: crie o bucket, configure o backend com use_lockfile = true e pronto. Não é obrigatório habilitar versionamento nem Object Lock no bucket para o lock file funcionar. (Versionamento continua sendo uma boa prática se você quiser recuperar versões anteriores do state em caso de erro.)

Configuração do backend

No seu código, use o backend s3 com use_lockfile = true:

terraform {
  backend "s3" {
    bucket         = "meu-bucket-state"
    key            = "prod/terraform.tfstate"
    region         = "us-east-1"
    use_lockfile   = true
  }
}

Para OpenTofu, o bloco é o mesmo (OpenTofu usa backends compatíveis com Terraform):

terraform {
  backend "s3" {
    bucket         = "meu-bucket-state"
    key            = "prod/opentofu.tfstate"
    region         = "us-east-1"
    use_lockfile   = true
  }
}

Não é necessário dynamodb_table. O backend usa o S3 para estado e para o lock.

Migrando de DynamoDB para lock file

Se você já usa S3 + DynamoDB:

  1. Adicione use_lockfile = true no backend e, se quiser, mantenha temporariamente o dynamodb_table para não quebrar quem ainda usa a tabela.
  2. Quando todos os runs estiverem usando OpenTofu/Terraform com use_lockfile, remova o parâmetro dynamodb_table do backend.
  3. Rode tofu init -reconfigure (ou terraform init -reconfigure) para recarregar a configuração do backend.

Depois disso, pode remover a tabela DynamoDB e as permissões IAM associadas.

Resumo

AntesDepois
S3 + DynamoDB para lockingS3 com use_lockfile = true
Dois recursos AWSApenas o bucket
IAM para S3 e DynamoDBIAM só para S3

Com isso você simplifica a infraestrutura de estado, reduz custo e mantém o locking necessário para uso em equipe e em CI/CD.