Importar infraestrutura existente para o Terraform
Quase toda empresa tem infraestrutura criada no console antes de adotar IaC. Recriar não é opção — envolve indisponibilidade e perda de dado. Importar traz o recurso existente para o state, sem tocar nele.
O critério de sucesso de cada importação é sempre o mesmo: terraform plan sem
mudanças.
1. Mapeie o que existe
Seção intitulada “1. Mapeie o que existe”Inventarie antes de escrever qualquer HCL, e escolha por onde começar.
# AWS: liste por serviço e por tagaws ec2 describe-vpcs --query 'Vpcs[].{id:VpcId,cidr:CidrBlock,nome:Tags[?Key==`Name`].Value|[0]}' --output tableaws s3api list-buckets --query 'Buckets[].Name' --output textaws rds describe-db-instances --query 'DBInstances[].DBInstanceIdentifier' --output textComece pelo que muda pouco e não tem estado: rede, buckets, papéis de IAM. Deixe banco de dados e recursos com dado para o fim, quando você já confia no processo.
2. Escreva a configuração alvo
Seção intitulada “2. Escreva a configuração alvo”Declare o recurso com um esboço mínimo. O plano vai apontar as diferenças, e você ajusta até zerar.
resource "aws_s3_bucket" "relatorios" { bucket = "empresa-relatorios-prod"}3. Use blocos de import
Seção intitulada “3. Use blocos de import”O bloco import é preferível ao comando avulso: ele é versionado, revisável no pull
request e reproduzível.
import { to = aws_s3_bucket.relatorios id = "empresa-relatorios-prod"}# esboça o HCL do recurso importado — ponto de partida, não resultado finalterraform plan -generate-config-out=gerado.tfterraform plan # o alvo é: "No changes"O identificador (id) varia por recurso: nome para bucket, ARN para alguns, formatos
compostos para outros (vpc-123/sg-456). A documentação do provider traz o formato exato na
seção de import — é a consulta mais frequente deste processo.
4. Itere até o plano ficar vazio
Seção intitulada “4. Itere até o plano ficar vazio”O primeiro plano quase nunca vem limpo. Leia cada diferença e decida:
- O recurso real tem algo que o código não declara → acrescente ao código.
- O código declara algo que o recurso não tem → é uma mudança real; decida se você quer aplicá-la agora (separadamente) ou alinhar o código ao existente.
- Diferença em campo somente leitura → normalmente ruído; confira a documentação.
terraform plan -out=plano.bin && terraform show -json plano.bin \ | jq '[.resource_changes[] | select(.change.actions != ["no-op"])] | length'Depois do plano limpo, rode terraform apply uma vez: ele grava o state sem alterar nada.
Remova então os blocos import já aplicados, para o repositório não acumular.
5. Repita em lotes pequenos
Seção intitulada “5. Repita em lotes pequenos”Importe de 5 a 10 recursos por pull request. Lotes grandes tornam a revisão impossível e misturam ajustes legítimos com erros de importação.
Para volume grande, ferramentas geradoras ajudam a produzir o esqueleto — mas trate a saída como rascunho e revise recurso a recurso:
terraformer import aws --resources=s3,vpc --regions=sa-east-1 # gera código e state6. Proteja o que acabou de entrar
Seção intitulada “6. Proteja o que acabou de entrar”Recurso agora gerenciado por código pode ser destruído por código:
resource "aws_db_instance" "principal" { # ... deletion_protection = true lifecycle { prevent_destroy = true }}E combine com o time: a partir de agora, nada de alterar aquele recurso pelo console. A primeira mudança manual pós-importação reintroduz o drift que você acabou de eliminar.
Se der errado
Seção intitulada “Se der errado”| Sintoma | Causa provável |
|---|---|
Cannot import non-existent remote object |
id no formato errado para aquele recurso |
Resource already managed |
Já está no state — confira com terraform state list |
| Plano quer recriar tudo | O id importado não corresponde ao recurso declarado |
| Diferença que não some | Campo com valor padrão do provider; declare-o explicitamente |
| Import de recurso com sub-recursos | Alguns precisam ser importados separadamente (policy, ACL, versionamento) |
O último caso é comum em S3: bucket, versionamento, criptografia e bloqueio público são recursos distintos no provider moderno, e cada um precisa do seu bloco de import.
Checklist de pronto
Seção intitulada “Checklist de pronto”- Inventário do que existe, priorizado por risco.
- Blocos
importversionados no pull request. -
terraform plansem nenhuma mudança antes do apply. - Nenhum
-/+no plano de importação. - Proteção contra destruição em recursos com estado.
- Lotes pequenos, com revisão.
- Acordo com o time: sem alterações manuais no console.