IaC em dois níveis¶
Infraestrutura como código é dividida em dois níveis com fronteiras disjuntas, e a fundação vive num único repositório.
| Nível | Escopo | Como roda |
|---|---|---|
| Fundação | Identidade, registry, DNS, rede, VMs e as camadas do cluster | Um repositório, Terragrunt; cada provider no executor que lhe convém |
| Por aplicação | Recursos que pertencem a uma aplicação (um banco, um bucket) | Na pasta terraform/ do repositório GitOps da app, por um workflow reutilizável |
flowchart TB
boot["bootstrap/ — manual, simples<br/>o que o pipeline não pode gerir"] --> repo
subgraph repo["Repositório de infra — só configuração"]
cloud["Cloud (DNS, IAM, registry)"]
cluster["Cluster (GitOps, VMs, config do SO)"]
end
mods["Repositórios de módulo<br/>versionados por tag"] --> repo
cloud --> rh["Runner hospedado + OIDC"]
cluster --> rl["Runner na LAN + papéis estreitos"]
app["Repo GitOps de cada app<br/>pasta terraform/"] --> wf["Workflow reutilizável"]
O que ficou decidido¶
- Um repositório só. Antes eram dois (cloud e cluster), com dois modelos de execução e duas formas de rever mudanças. Agora é um sítio, um fluxo.
- O passo manual é uma pasta, não um repositório.
bootstrap/guarda só o que o próprio pipeline não pode gerir (os papéis que ele assume), os segredos iniciais e a instalação do executor da LAN. É simples de propósito (bash ou um tofu pequeno) e nunca corre em CI. - Módulos fora do repositório, um por repositório, com tag. As unidades de infra só têm configuração. Subir uma versão é um PR de uma linha, e o pipeline planeia só essa unidade.
- Cada provider no seu executor. A cloud corre em runners hospedados com identidade federada. O cluster corre num runner dentro da rede de casa, com papéis estreitos e segredos num cofre gerido, nunca guardados no executor.
- Só o que mudou corre. O pipeline descobre as unidades afetadas pelo ficheiro alterado.
- O raio de impacto decide o portão, não o repositório. O que é seguro aplica-se após o merge; o que mexe em nós ou VMs exige um passo humano extra, com o plano visível antes.
Regra que evita desastres¶
Os dois níveis nunca apontam para o mesmo layer ou state. Se apontassem, cada um tentaria reconciliar o que o outro criou. O mesmo vale dentro da fundação: cada camada tem a sua chave de state, e adotar recurso existente exige um primeiro plano sem diferenças; se houver, corrige-se o código, não a realidade.
Trade-offs¶
- (+) Um só fluxo de revisão; atualizar uma peça crítica é um PR de uma linha com plano só dessa peça.
- (+) Módulos versionados e testáveis isoladamente, sem valores do ambiente dentro deles.
- (+) Quem é dono da aplicação pede infraestrutura sem tocar a fundação.
- (−) O runner da LAN é um ponto de falha para mudar a infra (não para o tráfego).
- (−) Dois executores (hospedado e LAN) para manter alinhados.
- (−) Alguns planos não aparecem no PR, porque as credenciais que exigiriam equivalem a admin (ver Lições aprendidas).