0 XP

DEVOPSQUEST

Minha Trilha
Módulo 7 · Terraform e Ansible

Módulos reutilizáveis: contratos, validação e evolução segura

Avançado 55 min+25 XPTerraformHCLGit

Objetivos desta aula

  • Desenhar uma interface pequena de módulo
  • Validar entradas antes do provisionamento
  • Expor outputs sem acoplar consumidores
  • Planejar mudanças de endereço com moved
  • Versionar e revisar atualizações de módulo

O módulo de rede já demonstrou reuso; agora vamos tratar um módulo como produto interno com contrato. Quem o consome precisa entender entradas, saídas e garantias sem ler todos os recursos. Um módulo que exige conhecer sua implementação apenas moveu a complexidade para outra pasta.

Escolha uma responsabilidade coesa. Neste exercício, modules/private-subnet cria uma subnet sem IP público automático e devolve seu ID. Ele não cria VPC, NAT ou banco escondidos; a composição dessas peças fica no módulo raiz, onde o ambiente é decidido.

Valide o que puder antes da API. Uma variável cidr com validation evita um erro básico de formato, mas não comprova ausência de sobreposição nem capacidade futura de endereçamento. Documente essas limitações e revise o desenho de rede junto com o plano.

Use outputs estáveis como interface: o consumidor depende de subnet_id, não de caminhos internos de recursos. Evite exportar objetos inteiros quando um ID basta. Isso reduz acoplamento e permite reorganizar a implementação sem obrigar cada ambiente a mudar.

O provider deve ser configurado no módulo raiz e recebido pelo filho, que declara seus requisitos. Assim dev e staging podem usar contas e regiões distintas sem credenciais embutidas no módulo. required_providers especifica compatibilidade, não autenticação.

Uma mudança de nome interno pode alterar o endereço no state sem alterar o recurso desejado. Um bloco moved informa a migração de endereço; não o use para esconder substituições reais. O plano deve mostrar a movimentação esperada e ausência de recriação indevida.

Versão fixa é decisão de atualização, não abandono de manutenção. Para módulo remoto, use versão de registry ou referência Git imutável revisada; para módulo local, a versão acompanha o commit do repositório. .terraform.lock.hcl fixa providers, não versões de módulos remotos.

Valide o contrato em um ambiente descartável: formato, validate, plano e saída esperada. Depois execute um segundo plano para conferir convergência. Antes de publicar uma mudança incompatível em subnet_id ou nas entradas obrigatórias, documente migração e combine a atualização com os consumidores.

Na prática

Contrato e implementação de modules/private-subnet/main.tf

hcl

# O provider será herdado do módulo raiz.
terraform {
  required_providers {
    aws = { source = "hashicorp/aws" }
  }
}
variable "vpc_id" {
  type = string
}
variable "az" {
  type = string
}
variable "cidr" {
  type = string
  validation {
    condition     = can(cidrnetmask(var.cidr))
    error_message = "Informe um CIDR IPv4 válido."
  }
}
resource "aws_subnet" "this" {
  vpc_id                  = var.vpc_id
  availability_zone       = var.az
  cidr_block              = var.cidr
  map_public_ip_on_launch = false
  # Privacidade também depende da tabela de rotas associada pelo módulo raiz.
}
output "subnet_id" {
  description = "ID da subnet para composição no módulo raiz."
  value       = aws_subnet.this.id
}

Migração de nome dentro do módulo

hcl

# Inclua apenas se uma versão anterior usava aws_subnet.private.
# Requer Terraform >= 1.1; mantenha o bloco durante a janela de migração.
moved {
  from = aws_subnet.private
  to   = aws_subnet.this
}
# Rode plan em cada consumidor e confira que não há destruição inesperada.

Por que isso importa

Interfaces previsíveis permitem atualizar infraestrutura de vários ambientes sem multiplicar correções manuais.

Erro comum

Renomear um resource sem migração e aceitar um plano de destruição por parecer apenas uma refatoração.

Dica de produção

Publique exemplos mínimos de consumo e uma lista de mudanças incompatíveis por versão do módulo.

Alerta de segurança

Não coloque access_key, secret_key ou credenciais de backend em módulos; autentique a execução por role.

Pergunta de entrevista

Como renomear um recurso dentro de um módulo sem recriá-lo nos ambientes consumidores?

Glossário

contrato de módulo
Entradas, saídas e garantias públicas para os consumidores.
módulo raiz
Configuração executada diretamente, que compõe módulos filhos e providers.
moved
Bloco declarativo de migração entre endereços de recursos no state.
acoplamento
Dependência de um consumidor em detalhes internos de outra parte.
mudança incompatível
Alteração que exige adaptação dos consumidores existentes.

Conexão com o CloudShop

Evoluir o módulo de rede do CloudShop com entradas validadas, outputs documentados e plano de migração sem recriação.

Quiz da aula

  1. 1. O que .terraform.lock.hcl fixa?

  2. 2. Qual recurso ajuda em uma renomeação de endereço no state?

  3. 3. Um módulo com map_public_ip_on_launch=false garante subnet privada?

Minhas anotações

Salvo automaticamente neste navegador.

AnteriorPróxima