Teste um contrato de módulo

ShellBeginner
Pratique Agora

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.

As entradas do módulo são verificadas por asserções em modo de planejamento antes de um plano de entrega, enquanto o armazenamento de referência é preservado.

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.