Introdução
Uma configuração pode estar formatada e ser estruturalmente válida e, ainda assim, identificar incorretamente um ambiente de relatórios. Sua equipe precisa de verificações executáveis para as entradas, saídas e tags planejadas de um pequeno módulo de armazenamento antes de confiar em um plano de entrega.
Você escreverá um contrato de módulo, testará dois ambientes suportados e uma entrada não suportada e fará um defeito real de negócio interromper o job. Você deve compreender variáveis/saídas de módulos e as verificações obrigatórias de formatação/validação do laboratório anterior. O armazenamento de referência existente deve permanecer inalterado.
Relação com certificações
| Certificação | Tarefa do exame | Prática |
|---|---|---|
| DevOps Engineer – Professional (DOP-C02) | Tarefa 1.2 | Prática básica de integração de asserções executáveis de módulos a uma verificação automatizada de qualidade obrigatória. |

Defina o contrato de entradas
Nesta etapa, você definirá quais entradas de ambiente o módulo de armazenamento aceita. A validação de entradas rejeita uma solicitação não suportada antes de criar um plano de recursos.
Entre no módulo fornecido e carregue as ferramentas preparadas.
cd /home/labex/project/report-module
source environment.sh
Leia sua interface e a implementação dos recursos.
cat variables.tf main.tf outputs.tf pipeline.json
environment seleciona preview ou review; bucket_prefix diferencia os nomes de armazenamento de um chamador. O nome do bucket combina as duas entradas, e a tag Environment e a saída devem identificar o ambiente solicitado. Os arquivos fornecidos main.tf, outputs.tf, provider.tf e run-job.py devem ser preservados: mantenha seu conteúdo final inalterado. Seu trabalho deve ficar em variables.tf, tests/ e pipeline.json.
Adicione um bloco validation a environment. contains verifica se o valor pertence à lista suportada; uma condition falsa produz a mensagem de erro fornecida. O here-document com delimitador entre aspas escreve HCL literal.
cat > variables.tf <<'EOF'
variable "environment" {
type = string
default = "preview"
validation {
condition = contains(["preview", "review"], var.environment)
error_message = "Choose preview or review."
}
}
variable "bucket_prefix" {
type = string
default = "delivery-contract"
}
EOF
Formate sua alteração.
terraform fmt
Tente uma solicitação não suportada. -var fornece um valor para esta invocação. Este comando retorna intencionalmente o código de saída nativo 1; ele deve informar Choose preview or review., em vez de propor um bucket de production.
terraform plan -input=false -var=environment=production
A validação define a interface aceita. Na próxima etapa, os testes exercitarão os dois valores aceitos e essa rejeição esperada.
Escreva asserções e observe uma falha real
Nesta etapa, você usará o comando nativo terraform test para verificar o comportamento planejado do módulo. A formatação e a validação podem aceitar uma saída fixa no código, mas incorreta; uma asserção compara o resultado calculado com a entrada solicitada.
O Terraform lê arquivos .tftest.hcl em tests/. Cada run é um cenário de teste independente. O command = plan explícito avalia um plano sem aplicá-lo. Mantenha os arquivos de teste em tests/, no formato .tftest.hcl. Neste laboratório, cada execução deve usar o modo de planejamento e o provedor/módulo fornecido; módulos alternativos, mocks de provedor e overrides estão fora da tarefa. Mantenha bucket_prefix herdado da entrada da suíte: não o atribua em variáveis de teste no nível do arquivo ou da execução, para que um chamador possa selecionar outro prefixo legítimo. Estes testes verificam valores conhecidos do plano, não a criação efetiva, as permissões em execução ou uma aplicação implantada.
Crie o diretório de testes. mkdir -p o cria se necessário e aceita um diretório já existente.
mkdir -p tests
Escreva asserções para o ambiente padrão e o alternativo. var se refere às entradas da execução, referências a recursos inspecionam valores planejados, e output se refere às saídas do módulo. expect_failures exige que a validação da variável indicada falhe; ele não transforma erros arbitrários de provedor ou rede em testes bem-sucedidos.
cat > tests/contract.tftest.hcl <<'EOF'
run "preview_contract" {
command = plan
assert {
condition = output.environment == var.environment
error_message = "The output must identify the requested environment."
}
assert {
condition = aws_s3_bucket.reports.bucket == "${var.bucket_prefix}-${var.environment}"
error_message = "The bucket name must use the requested prefix and environment."
}
assert {
condition = aws_s3_bucket.reports.tags.Environment == var.environment
error_message = "The planned tag must identify the requested environment."
}
}
run "review_contract" {
command = plan
variables { environment = "review" }
assert {
condition = output.environment == var.environment
error_message = "The alternate environment must not use the default label."
}
assert {
condition = aws_s3_bucket.reports.bucket == "${var.bucket_prefix}-${var.environment}"
error_message = "The alternate bucket must use its requested inputs."
}
assert {
condition = aws_s3_bucket.reports.tags.Environment == var.environment
error_message = "The alternate environment tag must match its input."
}
}
run "unsupported_environment" {
command = plan
variables { environment = "production" }
expect_failures = [var.environment]
}
EOF
Formate recursivamente os testes e os arquivos do módulo.
terraform fmt -recursive
Execute a suíte de testes.
terraform test
Espere três execuções aprovadas e um resumo de sucesso. Nenhum bucket de teste é implantado. Os valores de entrada e saída vêm de um plano efetivo do Terraform usando o provedor configurado.
Comprove que suas asserções detectam um defeito plausível. Substitua temporariamente apenas a saída de ambiente por um rótulo padrão fixo; preserve a saída do nome do bucket.
cat > outputs.tf <<'EOF'
output "environment" {
value = "preview"
}
output "bucket_name" {
value = aws_s3_bucket.reports.bucket
}
EOF
Execute a suíte novamente. Este comando retorna intencionalmente o código de saída nativo 1. A asserção do ambiente alternativo deve falhar, mostrando que um HCL válido ainda pode violar o contrato do módulo.
terraform test
Restaure a implementação de saída fornecida a partir do Git. Isso remove seu defeito temporário, preservando a validação e os testes que você escreveu.
git restore -- outputs.tf
Execute a implementação corrigida com as mesmas asserções.
terraform test
Todas as execuções devem passar novamente. Os testes devem aceitar entradas legítimas, em vez de apenas reconhecer uma saída padrão.
Faça os testes interromperem o job de entrega
Nesta etapa, você posicionará os testes de módulos entre as verificações estáticas obrigatórias e o planejamento. O executor fornecido faz parte da preparação; edite a configuração das etapas, em vez de alterar run-job.py.
Adicione test depois de fmt/validate e antes de plan.
cat > pipeline.json <<'EOF'
{"stages":["fmt","validate","test","plan"]}
EOF
Execute o job completo.
python3 run-job.py
As quatro etapas devem passar. O plano final pode retornar o código nativo 2 porque este módulo não foi aplicado; o executor trata isso como uma prévia bem-sucedida. Um teste com falha deve, em vez disso, interromper o job antes de sua etapa de planejamento. Não existe uma etapa de aplicação.
Execute a suíte com outro prefixo de bucket legítimo. Este -var altera a entrada da suíte sem editar o módulo nem seus testes.
terraform test -var=bucket_prefix=audit-contract
As mesmas três execuções devem passar. Para este exercício, mantenha bucket_prefix herdado do chamador em cada execução: não o atribua em blocos variables no nível do arquivo de teste ou da execução. Essas atribuições sobrescrevem as entradas de teste da CLI e impediriam que este comando exercitasse o prefixo solicitado. As substituições de ambiente continuam necessárias para exercitar os dois ambientes suportados. Asserções construídas a partir das entradas solicitadas continuam funcionando quando o chamador escolhe outro nome válido.
Leia o relatório de referência existente diretamente do armazenamento. Estes buckets preparados pertencem a outro ambiente; não os destrua nem modifique.
aws s3 cp s3://delivery-reference-reports/report.txt -
Ele ainda deve dizer reference report v1. Verifique também os dados vizinhos.
aws s3 cp s3://delivery-reference-neighbor/keep.txt -
Espere preserve contract neighbor. Seus testes não criaram recursos de armazenamento, portanto não há uma pilha de testes para destruir. Mantenha o contrato de entradas, os testes e a configuração do pipeline para a verificação final; o defeito temporário de saída já foi removido.
Resumo
Você definiu um contrato de entradas suportadas, usou testes nativos do Terraform em modo de planejamento para comparar saídas e tags planejadas com as entradas e observou uma falha real de asserção. Em seguida, integrou os testes à verificação de qualidade obrigatória da entrega, preservando os dados existentes e o estado de negócio.
Testes em modo de planejamento não comprovam o comportamento implantado. Etapas posteriores de entrega combinam essas verificações com um plano concreto revisado e uma aplicação efetiva controlada. Consulte a referência oficial de Terraform test e a documentação de configuração de testes para conhecer os mecanismos praticados aqui.



