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-staging e gateway-production criados 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.mk ganha os targets shared.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 target elixir.ci.deploy.k8s.

gateway

  • Dockerfile.production (build multi-stage), k8s/base/ (deployment, service, dois ingresses) e k8s/overlays/{staging,production}/ com patches de réplica e recurso.
  • Workflows deploy-staging.yml e deploy-production.yml.
  • secrets.env por 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

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.