Introdução
Sua equipe precisa de armazenamentos de relatórios de desenvolvimento e de prévia com conteúdos diferentes. Você reutilizará uma configuração, acompanhará as referências entre bucket e objeto e comprovará que dois diretórios raiz independentes gerenciam recursos AWS diferentes.
Use como base o primeiro laboratório de Terraform na AWS e seus conhecimentos de variáveis e saídas. As ferramentas, o acesso e a conexão do provedor estão preparados; nenhum recurso de uma VM anterior é reutilizado.
Relação com certificações
| Certificação | Tarefa do exame | Prática |
|---|---|---|
| Cloud Practitioner (CLF-C02) | Tarefa 3.1 | Usar definições de infraestrutura repetíveis e consultas operacionais a recursos. |
| Developer – Associate (DVA-C02) | Tarefa 3.3, Habilidade 3.3.4 | Prática básica de implantação de uma definição de infraestrutura. |
| DevOps Engineer – Professional (DOP-C02) | Tarefa 2.1 | Prática básica de gerenciamento de recursos por meio de uma definição de IaC. |

Implante o armazenamento de desenvolvimento
Nesta etapa, você usará variáveis de entrada e uma referência a recurso para criar um armazenamento de relatórios de desenvolvimento a partir de uma configuração.
Os dois diretórios raiz preparados, report-dev e report-preview, começam vazios, exceto pelo arquivo de conexão do provedor. Cada diretório raiz manterá seu próprio estado local. Isso é diferente de alterar entradas em um único diretório raiz: um diretório raiz continua gerenciando os recursos já registrados em seu estado.
Entre no diretório raiz de desenvolvimento e crie o modelo de recursos. As variáveis environment e report são entradas do tipo string. ${var.environment} insere o nome do ambiente no nome do bucket. O argumento bucket do objeto faz referência ao ID do recurso bucket, permitindo que o Terraform descubra a dependência e crie o bucket primeiro. content_type informa aos leitores como interpretar os bytes.
cd /home/labex/project/report-dev
cat > main.tf <<'EOF'
variable "environment" { type = string }
variable "report" { type = string }
resource "aws_s3_bucket" "reports" {
bucket = "terraform-reports-${var.environment}"
tags = {
Project = "TerraformReports"
Environment = var.environment
}
}
resource "aws_s3_object" "report" {
bucket = aws_s3_bucket.reports.id
key = "reports/current.csv"
content = var.report
content_type = "text/csv"
}
output "bucket_name" { value = aws_s3_bucket.reports.id }
output "report_key" { value = aws_s3_object.report.key }
EOF
Crie um arquivo de variáveis para este ambiente. A sequência de escape \n representa uma quebra de linha na string do relatório. Manter os valores separados permite reutilizar o mesmo modelo de recursos.
cat > dev.tfvars <<'EOF'
environment = "dev"
report = "orders,12\n"
EOF
Inicialize, valide e revise este diretório raiz. -var-file seleciona o arquivo de valores; ele não seleciona um estado diferente.
terraform init
terraform validate
terraform plan -var-file=dev.tfvars
Espere a adição de dois recursos: o bucket e seu objeto de relatório. Aplique as mesmas entradas e digite yes quando solicitado:
terraform apply -var-file=dev.tfvars
As saídas identificam o bucket e a chave do objeto. Salve e exiba esses valores usando $(...), que captura a saída de um comando. -raw imprime saídas do tipo string sem as aspas do Terraform.
BUCKET=$(terraform output -raw bucket_name)
echo "$BUCKET"
KEY=$(terraform output -raw report_key)
echo "$KEY"
Leia o relatório efetivamente armazenado pela AWS, em vez de tratar uma saída ou entrada no estado como prova dos dados. A resposta inclui ContentType: text/csv; o arquivo de destino contém os bytes.
aws s3api \
get-object \
--bucket "$BUCKET" \
--key "$KEY" \
dev-downloaded.csv
cat dev-downloaded.csv
Espere orders,12. O AWS View também permite expandir reports/current.csv dentro de terraform-reports-dev. Mantenha inalterado o relatório de referência separado da equipe.

Reutilize o modelo com estado separado
Nesta etapa, você implantará o mesmo modelo com entradas de prévia, preservando o armazenamento de desenvolvimento.
Copie apenas o modelo de recursos para o diretório raiz de prévia preparado. Neste exercício, copie apenas main.tf, pois cada diretório raiz preparado será inicializado separadamente. Não clone terraform.tfstate nem o diretório .terraform/ inicializado para criar outro ambiente: eles podem carregar o mapeamento original de recursos/backend. O arquivo de bloqueio de dependências .terraform.lock.hcl é diferente: ele registra versões de provedores e somas de verificação, pode ser compartilhado ou incluído em commits junto à configuração e não contém mapeamentos de recursos do ambiente. O diretório raiz de prévia já tem seu próprio arquivo de conexão do provedor.
cp /home/labex/project/report-dev/main.tf /home/labex/project/report-preview/main.tf
cd /home/labex/project/report-preview
cat > preview.tfvars <<'EOF'
environment = "preview"
report = "orders,25\n"
EOF
Inicialize este diretório raiz e revise o plano de prévia:
terraform init
terraform plan -var-file=preview.tfvars
Espere novamente duas adições, com terraform-reports-preview como nome do bucket. Uma exclusão inesperada do bucket de desenvolvimento indicaria que você reutilizou o estado errado. Aplique e digite yes:
terraform apply -var-file=preview.tfvars
Leia a saída e o relatório de prévia. A entrada de ambiente altera o nome e a tag; a entrada de relatório altera os bytes efetivamente armazenados.
BUCKET=$(terraform output -raw bucket_name)
echo "$BUCKET"
aws s3api \
get-object \
--bucket "$BUCKET" \
--key reports/current.csv \
preview-downloaded.csv
cat preview-downloaded.csv
Espere orders,25. Compare as saídas e as listas de estado dos dois diretórios raiz usando a opção global -chdir do Terraform, que executa o comando no diretório raiz indicado sem alterar o diretório do shell:
terraform -chdir=/home/labex/project/report-dev output bucket_name
terraform -chdir=/home/labex/project/report-dev state list
terraform -chdir=/home/labex/project/report-preview output bucket_name
terraform -chdir=/home/labex/project/report-preview state list
Os dois diretórios raiz têm endereços como aws_s3_bucket.reports, mas cada um mapeia para um bucket AWS diferente. Confirme que os dados de desenvolvimento permaneceram intactos:
aws s3api \
get-object \
--bucket terraform-reports-dev \
--key reports/current.csv \
dev-retained.csv
cat dev-retained.csv
Espere orders,12. Estes são estados locais independentes, não workspaces nem um backend compartilhado. A documentação de variáveis de entrada do Terraform explica a seleção de arquivos de variáveis com mais detalhes.

Limpe os dois armazenamentos criados
Nesta etapa, você destruirá os recursos de cada diretório raiz sem excluir o relatório de referência da equipe.
Cada diretório raiz precisa de suas próprias entradas durante a destruição. Revise o plano de exclusão do ambiente de desenvolvimento e, em seguida, destrua os recursos e digite yes. O objeto é removido antes de seu bucket porque o Terraform conhece a dependência entre eles.
terraform -chdir=/home/labex/project/report-dev plan -destroy -var-file=dev.tfvars
terraform -chdir=/home/labex/project/report-dev destroy -var-file=dev.tfvars
Agora remova apenas os recursos do diretório raiz de prévia, confirmando novamente com yes:
terraform -chdir=/home/labex/project/report-preview destroy -var-file=preview.tfvars
Cada destruição informa a remoção de dois recursos. Verifique se os dois mapeamentos estão vazios e se o relatório de referência não relacionado ainda existe:
terraform -chdir=/home/labex/project/report-dev state list
terraform -chdir=/home/labex/project/report-preview state list
aws s3api \
list-buckets \
--query 'Buckets[].Name'
aws s3api \
head-object \
--bucket team-reference-reports \
--key keep.txt \
--query ContentLength
Apenas o bucket de referência permanece. Uma listagem autenticada bem-sucedida comprova a ausência; uma falha de acesso ou de rede não comprovaria. Mantenha as credenciais preparadas até a conclusão da verificação final.
Resumo
Você reutilizou um modelo de bucket/objeto com dois arquivos de variáveis, leu os bytes reais dos relatórios e o Content-Type, manteve o estado de cada diretório raiz independente e limpou apenas seus dois ambientes.



