Terraform no OCI: state remoto com locking nativo, sem hack de S3
Objetivo
Terraform com state local (terraform.tfstate no disco) tem dois problemas assim que mais de uma
pessoa opera a mesma infraestrutura: nada impede dois apply simultâneos de corromper o state, e
não existe backup centralizado se o arquivo local se perder. A solução histórica na OCI era apontar
o backend s3 do Terraform para o endpoint compatível com S3 do Object Storage — hoje considerada
legado. A OCI passou a oferecer um backend nativo (oci), com locking embutido, sem precisar dessa
gambiarra.
Este guia mostra como configurar esse backend nativo e migrar um state existente para ele. Não cobre migração de state complexo com múltiplos workspaces e módulos aninhados — isso fica para um próximo artigo.
Premissas
- Terraform numa versão que suporte o backend nativo
oci— a documentação da HashiCorp não fixa uma versão mínima exata, mas o backends3compatível passou a ser tratado como legado a partir da faixa de versões 1.12.x. Confirme a compatibilidade na documentação oficial antes de aplicar. - Um bucket de Object Storage já criado na sua tenancy OCI. A Oracle recomenda (não exige) versionamento habilitado no bucket, para conseguir recuperar um state anterior em caso de erro.
- Autenticação configurada — via
~/.oci/config(API key) ou instance principal, dependendo de onde o Terraform roda. - Os blocos e comandos abaixo seguem a documentação oficial da HashiCorp e da Oracle, mas não foram executados neste ambiente — a sintaxe de argumentos de backend muda entre versões do provider.
Implementação
Configurar o backend
terraform {
backend "oci" {
bucket = "meu-bucket-tfstate"
namespace = "minha-namespace"
region = "us-ashburn-1"
key = "prod/terraform.tfstate"
config_file_profile = "DEFAULT"
}
}
Substitua bucket, namespace e region pelos valores reais da sua tenancy. namespace é o
namespace de Object Storage da tenancy (não um nome escolhido por você) — confira com
oci os ns get se não souber o seu.
Autenticação sem chave estática
Se o Terraform já roda dentro de uma instância OCI (compute ou node de OKE), prefira
auth = "InstancePrincipal" em vez de API key — evita ter que distribuir e rotacionar uma chave
privada:
terraform {
backend "oci" {
bucket = "meu-bucket-tfstate"
namespace = "minha-namespace"
region = "us-ashburn-1"
auth = "InstancePrincipal"
}
}
Migrar de state local
terraform init -migrate-state
O Terraform detecta a mudança de backend e pergunta se deve copiar o state local existente para o bucket. Confirme com atenção — a partir desse momento, o bucket passa a ser a fonte de verdade do state, não o arquivo local.
Validação
Depois de migrar, rode terraform plan e confirme que ele não aponta drift inesperado — se
apontar, o state copiado pode não ser o mesmo que estava realmente em uso antes da migração. Para
testar o locking, tente rodar dois terraform apply ao mesmo tempo, em dois terminais separados,
no mesmo diretório: o segundo deve falhar avisando que o state está bloqueado, em vez de aplicar
por cima da execução em andamento.
Limitações relevantes
- Depende da versão do Terraform. Times ainda em versões mais antigas podem não ter o backend
ocidisponível e vão precisar seguir usando o backends3compatível, mesmo esse sendo tratado como legado pela própria Oracle. - O locking depende do comportamento do Object Storage. O mecanismo usa a condição
If-None-Matchna escrita. Se algum passo do seu pipeline de CI fizer retry automático de uma operação de state sem tratar esse erro de lock especificamente, o retry pode mascarar o problema em vez de esperar a execução anterior terminar. - Isso resolve concorrência de state, não segredos dentro dele. Um
.tfstatefrequentemente guarda valores sensíveis em texto claro (senhas geradas, chaves). Migrar para Object Storage com locking não substitui criptografia do state (kms_key_id) nem controle de acesso restrito ao bucket.
Próximo passo
Depois de migrar, vale revisar as policies de IAM do bucket de state — quem tem permissão de leitura
no .tfstate deveria ser um grupo bem mais restrito do que quem tem permissão para rodar
terraform plan.