Tipar fortemente uma variável.
→Primitivos: `string`, `number`, `bool`. Coleções: `list(<type>)`, `set(<type>)`, `map(<type>)`. Estruturais: `object({...})`, `tuple([...])`. Use `any` apenas quando for verdadeiramente polimórfico.
Referência↗
Restringir `environment` a dev/staging/prod.
→`variable "environment" { validation { condition = contains(["dev","staging","prod"], var.environment); error_message = "..." } }`. Múltiplos blocos `validation` permitidos; todos devem passar.
Referência↗
Gerar uma palavra-passe de base de dados sem que ela apareça em `terraform output`.
→`output "db_password" { value = ...; sensitive = true }`. O CLI mostra `(sensitive value)`. Ainda legível via `terraform output db_password` ou `-json` (intencionalmente — para scripts).
Referência↗
Calcular um valor uma vez e reutilizá-lo em vários recursos.
→`locals { common_tags = merge(var.tags, { Project = var.project }) }`. Referencie como `local.common_tags`. Não substituível de fora do módulo.
Referência↗
Procurar uma AMI existente sem a gerir.
→`data "aws_ami" "ubuntu" { most_recent = true; filter { ... } }`. Apenas leitura. Referencie atributos como `data.aws_ami.ubuntu.id`.
Referência↗
Criar N recursos semelhantes — escolher `count` ou `for_each`.
→`for_each` (com map ou set) quando os itens têm identidade estável (nomes de região, chaves de ambiente). `count` para "preciso de N cópias, a ordem não importa, a identidade é apenas um índice". Adicionar/remover no meio de `count` causa destroy/recreate; `for_each` preserva a identidade.
Referência↗
Criar um recurso por item numa lista de strings.
→`for_each = toset(["a", "b", "c"])`. `each.key` e `each.value` dão ambos a string. Para mapas: `for_each = var.users` — `each.key` = chave do map, `each.value` = valor do map.
Referência↗
Gerar um número variável de blocos aninhados (ex: regras de ingresso).
→`dynamic "ingress" { for_each = var.rules; content { from_port = ingress.value.from; ... } }`. O argumento `iterator` pode renomear o iterador se necessário.
Referência↗
Obter uma lista de atributos em todas as instâncias de um recurso `count`.
→`aws_instance.web[*].id` retorna uma lista de IDs. Funciona com `count` e `for_each` (mas `for_each` produz um map não ordenado, então `values(aws_instance.web)[*].id`).
Referência↗
Definir um valor com base numa condição.
→Ternário: `var.is_prod ? 5 : 1`. Ambas as ramificações devem produzir o mesmo tipo.
Referência↗
Combinar dois mapas; os valores do segundo vencem em caso de colisão de chaves.
→`merge(local.defaults, local.overrides)`. O mapa mais à direita vence. Útil para composição de tags.
Referência↗
Ler um valor de mapa com um padrão se a chave estiver em falta.
→`lookup(var.config, "region", "us-east-1")`. Retorna o valor padrão quando a chave não está presente. Para estruturas profundamente opcionais, prefira o `try()` opcional.
Referência↗
Colapsar listas aninhadas numa lista plana.
→`flatten([["a","b"], ["c"], [["d","e"]]])` → `["a","b","c","d","e"]`. Achata listas recursivamente; preserva a ordem.
Referência↗
Incorporar um mapa Terraform num documento de política IAM.
→`jsonencode({Version = "2012-10-17", Statement = [...]})`. Produz uma string JSON. Inverso: `jsondecode()`.
Referência↗
Renderizar um script user-data com template com valores de variáveis.
→`templatefile("init.sh.tpl", { region = var.region, env = var.env })`. O template usa a sintaxe `${region}`. Alternativa mais recente para renderização estática: `file()` + `format()`.
Referência↗
Esculpir CIDRs de subnet a partir de um range de VPC.
→`cidrsubnet("10.0.0.0/16", 8, 0)` → `10.0.0.0/24`. Primeiro arg = pai, segundo = bits a estender, terceiro = número da subnet.
Referência↗
Ler um valor que pode não existir; recorrer a um padrão.
→`try(yamldecode(file("config.yaml")), { defaults = true })`. Avalia da esquerda para a direita; retorna a primeira expressão sem erro.
Referência↗
Iterar sobre ficheiros que correspondem a um glob.
→`fileset(path.module, "configs/*.json")` retorna um conjunto de caminhos. Combine com `for_each` para gerir um recurso por ficheiro.
Referência↗
Mesmo provider em duas regiões (ex: AWS us-east-1 + us-west-2).
→Dois blocos `provider "aws" { alias = "..." }`. Recursos optam via `provider = aws.us_west`. Módulos aceitam aliases via `configuration_aliases`.
Referência↗
Executar um comando shell numa VM recém-criada.
→Provisioner `remote-exec` dentro de um recurso. Ferramenta de último recurso — prefira cloud-init, user data ou gestão de configuração. Os provisioners não são rastreados no estado e não são executados novamente em caso de drift.
Referência↗
Executar um comando que não corresponde a um recurso cloud (ex: invocação CLI).
→`resource "null_resource" "trigger" { triggers = { sha = sha1(file(".")) }; provisioner "local-exec" { command = "..." } }`. Re-executa quando `triggers` mudam.
Referência↗
Verificar continuamente um invariante de tempo de execução (ex: endpoint de saúde retorna 200) sem bloquear o apply.
→`check "endpoint" { data "http" "h" { url = "..." }; assert { condition = data.http.h.status_code == 200; error_message = "..." } }`. Executa em plan/apply; falha é um aviso, não um erro grave.
Por quê: `check` permite data sources com escopo utilizáveis apenas dentro da verificação. `precondition`/`postcondition` são erros graves em plan/apply.
Referência↗
Falhar o plano se uma AMI for muito antiga.
→`lifecycle { precondition { condition = data.aws_ami.x.creation_date > "2024-01-01"; error_message = "..." } }`. Falha grave, avaliada antes/depois, conforme apropriado.
Referência↗
Variável com um valor posicional de forma fixa.
→`type = tuple([string, number, bool])` exige exatamente três elementos nessa ordem. Diferente de uma lista (homogénea, comprimento variável).
Referência↗
Tipar fortemente uma entrada estruturada (ex: `database = { instance_class = string, allocated_storage = number }`).
→`type = object({ instance_class = string, allocated_storage = number, multi_az = optional(bool, false) })`. `optional(<type>, <default>)` torna os atributos opcionais.
Referência↗
Como são carregados os ficheiros `*.tfvars`?
→`terraform.tfvars` e `*.auto.tfvars` carregam automaticamente (ordem lexical para `auto`). Outros nomes exigem `-var-file=path.tfvars`.
Referência↗
Escrever testes automatizados para um módulo Terraform.
→Ficheiros `.tftest.hcl` com `run "name" { command = plan|apply, assert { condition = ..., error_message = ... } }`. `command = plan` não tem efeitos secundários; `command = apply` cria realmente recursos.
Referência↗
Passar variáveis para execuções de teste.
→O bloco `variables { ... }` ao nível do ficheiro aplica-se a todas as execuções. `variables { ... }` por execução substitui apenas para essa execução.
Referência↗