Deploy do gateway no Kubernetes com CI/CD
TLDR: Colocar o gateway (API gateway em Elixir) no cluster Kubernetes compartilhado, com namespaces e DNS geridos por Terraform neste repo e o deploy da imagem feito por GitHub Actions + Kustomize.
Contexto
O gateway é um API gateway dinâmico em Elixir. Rodando no Kubernetes ele ganha escala horizontal, alta disponibilidade, integração com a infraestrutura compartilhada e separação de ambientes (staging/production).
A divisão de responsabilidade que orienta toda a spec:
| Ferramenta | Responsabilidade | Frequência |
|---|---|---|
| Terraform (neste repo) | namespaces, DNS, RBAC, quotas | raramente |
| GitHub Actions | build, push da imagem, kubectl apply -k, rollout |
a cada push |
| Kustomize (no repo do gateway) | manifests base + patches por ambiente | a cada mudança de manifest |
Objetivos
- Namespaces
gateway-stagingegateway-productioncriados por Terraform. - Registros DNS no Cloudflare para as URLs de API e admin de cada ambiente.
- Pipeline de deploy reutilizável, seguindo o padrão do repo
commons. - Secrets de infraestrutura no GitHub, separados por ambiente.
Fora de escopo
- HPA/VPA, PodDisruptionBudget, Network Policies e Pod Security Standards — listados como melhoria futura.
- Observabilidade (Prometheus, Grafana, tracing, agregação de log).
- Deploy canário / blue-green e feature flags.
- Desativar o Heroku: esta infraestrutura sobe em paralelo e coexiste durante a transição.
Mudanças
infrastructure
- Novo stack
src/stacks/shared/gateway/terraform/:backend.tf,versions.tf,provider.tf(Kubernetes + Cloudflare),data.tf(remote state do cluster),variables.tf,namespaces.tf,dns.tf,outputs.tf. - Novos scripts
bin/stacks/shared/gateway/:apply.sh,plan.sh,status.sh,health.sh,outputs.sh,destroy.sh. makefiles/shared.mkganha os targetsshared.gateway.{apply,plan,status,health,outputs,destroy}.
commons
.github/workflows/deploy-k8s.yml— workflow reutilizável de deploy no Kubernetes.make/kubernetes/makefile— targets de build, push e deploy.scripts/kubernetes/deploy.sh— script de deploy.make/elixir/ci/makefile— novo targetelixir.ci.deploy.k8s.
gateway
Dockerfile.production(build multi-stage),k8s/base/(deployment, service, dois ingresses) ek8s/overlays/{staging,production}/com patches de réplica e recurso.- Workflows
deploy-staging.ymledeploy-production.yml. secrets.envpor overlay, não commitado (entra no.gitignore).
Convenções decididas aqui
- Namespace =
{app_name}-{environment}— calculado automaticamente pelo pipeline. - URL =
{environment}.{service}.{app}.{domain}, com produção sem o prefixo de ambiente:staging.api.gateway.ibft.app,staging.admin.gateway.ibft.app,api.gateway.ibft.app,admin.gateway.ibft.app. - Limites de recurso: staging 1 réplica (100m/500m CPU, 128Mi/512Mi memória); produção 3 réplicas (200m/1000m CPU, 256Mi/1Gi memória).
Fluxo de deploy
mermaid
graph TD
A["push em develop ou main"] --> B[".github/workflows/deploy-{env}.yml"]
B --> C["commons/.github/workflows/deploy-k8s.yml@v1"]
C --> D["make ci.deploy APP_NAME=gateway ENV={env}"]
D --> E["k8s.build → docker build Dockerfile.production"]
E --> F["k8s.push → push no registry"]
F --> G["k8s.deploy → kubectl apply -k overlays/{env}"]
G --> H["rollout no namespace gateway-{env}"]
Secrets no GitHub
| Escopo | Secret | Origem |
|---|---|---|
| Repositório | KUBE_CONFIG |
kubeconfig em base64 |
| Repositório | GH_ACTIONS_IBFTCORP_SSH_KEY |
chave SSH para submódulos privados |
| Ambiente (staging e production) | REDIS_PASSWORD, SECRET_KEY_BASE |
definidos via gh secret set |
Isolamento por namespace, TLS via cert-manager (Let’s Encrypt), ingress com redirect de SSL obrigatório, serviço interno em ClusterIP e container rodando como usuário não-root (UID 1000).
Como verificar
```bash # infraestrutura make shared.gateway.plan make shared.gateway.apply make shared.gateway.outputs make shared.gateway.health
aplicação (após o push disparar o Actions)
curl https://staging.api.gateway.ibft.app/health curl https://api.gateway.ibft.app/health ```
O health check deve mostrar 1 pod Running em gateway-staging e 3 em gateway-production.
Rollback: re-run do workflow anterior bem-sucedido, ou kubectl rollout undo deployment/gateway -n gateway-<env>, ou git revert do commit.
Documentação
CLAUDE.md— seção de estrutura.- Ver também remoção do terraform do gateway deste repo, que moveu esta infraestrutura para o repo do gateway.
Nota histórica: esta spec foi escrita quando o cluster compartilhado era DOKS e o registry era o DOCR. O cluster hoje é EKS e o registry é o ECR — ver migração do kubernetes compartilhado para EKS e migração do registry para ECR. O gateway não é mais gerido por Terraform neste repo.