Pular para o conteúdo principal
Este guia orienta sobre a implantação completa da infraestrutura EKB EKS no AWS usando Terragrunt. Ele cobre instalação de ferramentas, configuração do ambiente e uma sequência de implantação em fases projetada para garantir a ordem adequada de dependências em todos os componentes da infraestrutura. As implantações são organizadas em nove fases:
  1. Gerenciamento de Estado — Inicializa o bucket S3 usado para armazenar o estado do Terraform do ambiente.
  2. Infraestrutura EKS — Provisiona a VPC, sub-redes, NAT gateways, funções IAM e o cluster EKS e node groups gerenciados.
  3. Armazenamento e Balanceamento de Carga — Implantar o EBS CSI driver para volumes persistentes e o AWS Load Balancer Controller para ingress ALB.
  4. Escalação Automática Karpenter — Configura provisionamento dinâmico de nós com suporte a instâncias Spot e tratamento de interrupção via SQS e EventBridge.
  5. Escalação Automática KEDA — Implantar o KEDA para escalação automática em nível de pod baseada em limites de CPU e memória.
  6. Serviços de Dados — Provisionar Supabase (auto-hospedado ou Cloud), ElastiCache Redis e Amazon MQ RabbitMQ.
  7. Serviços Odin — Implantar a pilha de aplicação EKB (Web, FastAPI, Celery, Automator) via Helm.
  8. Observabilidade SigNoz — Implantar rastreamento distribuído, métricas e agregação de logs via SigNoz e o agente k8s-infra.
  9. Implantação Final — Executar um terragrunt apply completo para reconciliar quaisquer recursos restantes.
Antes de começar, complete a lista de verificação de pré-requisitos com o cliente e certifique-se de que todos os placeholders <YOUR_*> no template do ambiente estejam preenchidos. Vários valores — incluindo o ID da VPC, endpoint do cluster EKS e endpoints Redis e RabbitMQ — só estão disponíveis após a conclusão de fases específicas, portanto o guia indica exatamente quando capturá-los e aplicá-los.

Pré-requisitos

  • AWS CLI configurada com permissões apropriadas
  • Terraform (>= 1.0)
  • Terragrunt (versão mais recente)
  • kubectl para gerenciamento do Kubernetes
  • helm para gerenciamento de charts Helm

Guia de Instalação

Instalando o Terragrunt

macOS (Homebrew)
Linux (apt)
Windows (Chocolatey)

Instalando o kubectl

macOS (Homebrew)
Linux
Windows (Chocolatey)

Instalando o Helm

macOS (Homebrew)
Linux
Windows (Chocolatey)

Verificando a Instalação

Configuração da AWS CLI


Criando um Novo Ambiente

Passo 1: Copie o Template do Ambiente

A pasta env-template-folder contém arquivos pré-estruturados com placeholders <YOUR_*> prontos para serem preenchidos. Copie-a inteiramente para criar sua nova pasta de ambiente.

Passo 2: Verifique se Todos os Placeholders Estão Presentes

Todos os placeholders seguem a convenção <YOUR_*>. Os passos abaixo orientam sobre como preenchê-los arquivo por arquivo.

Passo 3: Provisionar Certificados SSL (AWS ACM)

Antes de definir variáveis de ambiente, você precisa dos ARNs dos certificados. Use o Console AWS para solicitar certificados SSL no AWS Certificate Manager (ACM) para todos os domínios que seu ambiente servirá. Opção A: Certificado wildcard único (recomendado) Um único certificado wildcard cobre todos os subdomínios com um único ARN. Por exemplo, se seu domínio base for app.example.com, um único certificado *.app.example.com cobre: Opção B: Certificados por serviço Solicite um certificado por domínio se não puder usar um wildcard. Repita os passos abaixo para cada domínio: <YOUR_WEB_DOMAIN>, <YOUR_API_DOMAIN>, <YOUR_AUTOMATOR_DOMAIN>, <YOUR_SUPABASE_DOMAIN> (apenas se ENABLE_SUPABASE=true), <YOUR_SIGNOZ_DOMAIN> (apenas se ENABLE_SIGNOZ=true). Solicitando um certificado no Console AWS
  1. Abra o console do AWS Certificate Manager
  2. Mude para a região correta (canto superior direito) — deve corresponder a <YOUR_AWS_REGION>
  3. Clique em Request a certificateRequest a public certificateNext
  4. Em Fully qualified domain name, insira o wildcard (por exemplo, *.app.example.com) ou um domínio específico
  5. Defina Validation method como DNS validation
  6. Clique em Request — o certificado é criado no estado Pending validation
Adicionando o registro de validação DNS CNAME O ACM gera um registro CNAME que você deve adicionar ao seu provedor DNS para provar a titularidade do domínio. Obtenha os valores no Console ACM abrindo o certificado e expandindo o domínio em Domains.
Inclua o ponto final (.) no final dos valores CNAME se seu provedor DNS exigir.
Cloudflare
  1. Faça login no Cloudflare → selecione seu domínio → vá para DNSRecordsAdd record
  2. Defina Type como CNAME
  3. Cole o nome CNAME do ACM em Name e o valor CNAME do ACM em Target
  4. Defina Proxy status como DNS only (ícone de nuvem cinza) — o certificado não será validado através do proxy Cloudflare
  5. Clique em Save
Route 53
  1. Abra o console Route 53 → Hosted zones → selecione sua zona → Create record
  2. Defina Record type como CNAME
  3. Cole o nome CNAME do ACM em Record name (apenas a parte do subdomínio) e o valor em Value
  4. Defina TTL como 300 e clique em Create records
No ACM, você também pode clicar em Create records in Route 53 para que o ACM adicione o registro automaticamente se a hosted zone estiver na mesma conta.
Uma vez que o DNS propagar (tipicamente 1–5 minutos), o status do certificado muda para Issued. Copie o ARN do topo do certificado — ele se parece com arn:aws:acm:<regiao>:<account-id>:certificate/<uuid>. Mantenha o(s) ARN(s) à mão para o próximo passo.

Passo 4: Defina as Variáveis de Ambiente

Defina estas variáveis de ambiente do shell antes de executar quaisquer comandos Terragrunt. Elas são lidas diretamente por terragrunt.hcl via get_env().

Instâncias Spot e Cargas de Trabalho Estatais

As instâncias Spot são configuradas por NodePool em values/karpender.yaml, não via variáveis de ambiente. Cada NodePool declara sua própria estratégia de capacidade: O NodePool application usa famílias de instâncias m/c (geração 5+) com apenas On-Demand. Os pods do serviço Supabase são fixados aqui via nodeSelector: workload-type: "application" para garantir que nunca sejam interrompidos por um evento de reivindicação Spot. O NodePool database-dedicated nunca usa Spot. Ele usa consolidationPolicy: WhenEmpty para que o Karpenter não evicta um nó que ainda tem um pod em execução, tornando-o seguro para cargas de trabalho estatais como réplicas PostgreSQL e CloudNativePG. Diretrizes para aplicações estatais no Spot:
  • Não agende bancos de dados, filas persistentes ou qualquer pod com PersistentVolumeClaim em NodePools Spot.
  • Use um nodeSelector direcionando node-type: database-dedicated com a toleração correspondente database-workload: "true" para pods de banco de dados.
  • Use nodeSelector: workload-type: "application" para serviços sem estado面向 ao usuário que devem permanecer disponíveis sem interrupção.
  • Para cargas de trabalho em segundo plano (Web, API, Celery, Automator), o NodePool Spot general é apropriado — o tratador de interrupção SQS do Karpenter drena nós Spot graciosamente antes que a AWS os reivindique, e a contagem mínima de réplicas do KEDA (≥ 2) garante disponibilidade durante a substituição de nós.
  • Para desabilitar Spot globalmente, remova "spot" da lista de valores em cada NodePool dentro de values/karpenter.yaml.
Como o Karpenter lida com avisos de interrupção Spot: A AWS fornece um aviso de interrupção de 2 minutos antes de terminar uma instância Spot. O Karpenter usa EventBridge e SQS para agir automaticamente:
Isto é configurado no bloco karpenter em terragrunt.hcl:

Passo 5: Atualize os Valores Específicos do Ambiente

Faça uma busca e substituição em todos os arquivos na sua nova pasta de ambiente para os seguintes placeholders:

5.1 terragrunt.hcl — Configuração principal do cluster

5.2 state/terragrunt.hcl — Bucket de estado S3

5.3 values/infrastructure.yaml — AWS Load Balancer Controller

Obtenha o ID da VPC após a criação do cluster EKS antes de implantar o AWS Load Balancer Controller.

5.4 values/karpenter-values.yaml — Controlador Karpenter

Obtenha o endpoint do cluster EKS após a criação do cluster EKS e antes de implantar o Karpenter.

5.5 values/karpenter-nodeclasses.yaml — Classes de nós Karpenter

5.6 values/aws-ebs-csi-driver.yaml — EBS CSI Driver

5.7 values/karpenter.yaml — Karpenter NodePools

Os nomes das classes de nós (general, compute-intensive, memory-intensive, gpu, database) devem corresponder às entradas em karpenter-nodeclasses.yaml.

5.8 values/keda.yaml — Escalonador KEDA

Nenhum placeholder específico do ambiente é necessário. Limites de recursos e contagens de réplicas são pré-configurados com padrões sensatos. Revise e ajuste se necessário.

5.9 values/supabase.yaml — Aplicação Supabase (apenas se ENABLE_SUPABASE=true)

Todas as chaves abaixo devem ser geradas consistentemente e compartilhadas com ha-supabase-db.yaml. Gere-as uma vez e use os mesmos valores em ambos os arquivos.

5.10 values/ha-supabase-db.yaml — Supabase HA Database (apenas se ENABLE_HA_SUPABASE_DB=true)

Os segredos aqui devem corresponder a supabase.yaml. Use os mesmos valores gerados para postgresPassword, jwtSecret, anonKey e serviceRoleKey.
A classe de armazenamento (ebs-csi-gp2), contagens de instâncias e limites de recursos são pré-configurados. Ajuste postgres.storage.size e postgres.walStorage.size para o volume de dados esperado.

5.11 values/cloudnative-pg.yaml — Operador CloudNativePG (apenas se ENABLE_CNPG=true)

Nenhum placeholder específico do ambiente é necessário. Isto implanta apenas o controlador do operador CNPG. As configurações padrão (3 réplicas, limites de recursos) são adequadas para a maioria dos ambientes.

5.12 values/odin-services.yaml — Serviços de aplicação Odin

Os endpoints Redis e RabbitMQ só estão disponíveis após o Terraform criar esses recursos AWS. Os ARNs de certificado devem ser provisionados no ACM antes da implantação.
Configurações gerais: Supabase (dataServiceConfig) — auto-hospedado (ENABLE_SUPABASE=true): Supabase (dataServiceConfig) — Supabase Cloud (ENABLE_SUPABASE=false): Redis:
RabbitMQ:
ARNs de SSL / Certificado:
Chaves Supabase do frontend web — auto-hospedado (ENABLE_SUPABASE=true): Chaves Supabase do frontend web — Supabase Cloud (ENABLE_SUPABASE=false):

5.13 values/signoz.yaml — Observabilidade SigNoz (apenas se ENABLE_SIGNOZ=true)

5.14 values/signoz-k8s-infra.yaml — Métricas SigNoz K8s (apenas se ENABLE_SIGNOZ=true)

O endpoint do coletor OTel (signoz-otel-collector.monitoring.svc.cluster.local:4317) é pré-configurado assumindo que tanto SigNoz quanto k8s-infra são implantados no namespace monitoring. Nenhuma alteração é necessária, a menos que você use um nome de release personalizado.

Lembrete da Ordem de Implantação

Alguns valores só estão disponíveis após a implantação de certa infraestrutura. Siga esta ordem:
  1. Antes de qualquer implantação — Defina: <YOUR_ENV_NAME>, <YOUR_AWS_REGION>, <YOUR_AWS_ACCOUNT_ID>, <YOUR_ENVIRONMENT>, <YOUR_PROJECT>, <YOUR_VPC_CIDR>, todos os nomes de domínio, todos os ARNs de certificado, todos os valores do Supabase, <YOUR_TOOLKIT_ENCRYPTION_KEY>, nome de usuário/senha do RabbitMQ
  2. Após criação do cluster EKS — Defina: <YOUR_VPC_ID> (infrastructure.yaml), <YOUR_EKS_CLUSTER_ENDPOINT> (karpenter-values.yaml)
  3. Após terraform apply para serviços AWS — Defina: <YOUR_REDIS_HOST>, <YOUR_RABBITMQ_HOST> (odin-services.yaml)

Passo 6: Verifique se Não Há Placeholders Restantes

A saída esperada deve estar vazia ou conter apenas referências a recursos prestes a serem criados (VPC, Redis, MQ, EKS). Se houver placeholders restantes, consulte as subseções do Passo 5 acima. Lista de verificação de arquivos:

Fase 1: Configuração do Gerenciamento de Estado

Finalidade: Criação do bucket S3 para o estado do Terraform. O módulo de gerenciamento de estado de cada ambiente cria um bucket S3 com o padrão odin-terraform-state-{nome-do-ambiente}, configura criptografia, versionamento e bloqueio de acesso público, e usa estado local para o próprio módulo de estado (padrão de inicialização).

Fase 2: Implantação da Infraestrutura EKS

Finalidade: Rede principal (VPC, sub-redes, NAT gateway), funções e políticas IAM, cluster EKS e node groups gerenciados.

2.1 Execução Seca — Infraestrutura EKS

Infraestrutura Principal
Funções e Políticas IAM
Cluster EKS e Node Groups

Usando um Registro Docker Personalizado / Privado

Por padrão, as imagens EKB são puxadas do Docker Hub usando um segredo chamado regcred. Se o cliente hospeda imagens em um registro diferente, siga estes passos antes de implantar odin-services. Passo 1 — Criar o imagePullSecret no namespace alvo
Passo 2 — Definir o nome do segredo em values/odin-services.yaml
Passo 3 — Atualizar referências de imagem
Passo 4 — Verificar acesso de pull antes da implantação completa

2.2 Implantar Infraestrutura EKS

Passo 1: Infraestrutura Principal
Após este passo, atualize o vpcId em values/infrastructure.yaml antes de implantar o AWS Load Balancer Controller.
Passo 2: Cluster EKS e Funções e Políticas IAM
Passo 3: Node Groups e Add-ons
Após este passo, atualize CLUSTER_ENDPOINT em values/karpenter-values.yaml antes de implantar o Karpenter.
Verificar Conectividade do Cluster EKS

Fase 3: Armazenamento e Balanceamento de Carga

Finalidade: EBS CSI driver para volumes persistentes, AWS Load Balancer Controller rodando no node group gerenciado.

3.1 Execução Seca — Armazenamento e Balanceamento de Carga

EBS CSI Driver
AWS Load Balancer Controller

3.2 Implantar Armazenamento e Balanceamento de Carga

Passo 1: EBS CSI Driver
Verificação
Passo 2: AWS Load Balancer Controller
Verificação

Fase 4: Escalação Automática Karpenter

Finalidade: Funções IAM para Karpenter, tratamento de interrupção Spot, controlador Karpenter e node pools.

4.1 Execução Seca — Karpenter

Recursos IAM do Karpenter
Função Vinculada ao Serviço EC2 Spot (se instâncias Spot estiverem habilitadas)
Interrupção Spot do Karpenter (se habilitada em terragrunt.hcl)
Charts Helm do Karpenter
Karpenter NodePools e EC2NodeClasses
Um erro esperado pode aparecer durante o plan: API did not recognize GroupVersionKind from manifest (CRD may not be installed). Isto pode ser ignorado com segurança — o Kubernetes valida recursos contra a API ao vivo durante o plan, antes que os CRDs sejam instalados.

4.2 Implantar Karpenter

Passo 1: Recursos IAM do Karpenter
Verificação
Passo 2: Função Vinculada ao Serviço EC2 Spot (se instâncias Spot estiverem habilitadas)
A função vinculada ao serviço EC2 Spot é por conta (apenas uma por conta AWS) e deve existir antes que o Karpenter possa iniciar instâncias Spot.
Opção A: Deixe o Terraform criá-la (recomendado para novas implantações)
Opção B: Importar se a função já existir
Passo 3: Interrupção Spot do Karpenter (se habilitada em terragrunt.hcl)
Verificação
Passo 4: Chart Helm do Karpenter
Verificação
Passo 5: Manifestos Kubernetes do Karpenter
Verificação

Fase 5: Escalação Automática KEDA

Finalidade: KEDA para escalação automática em nível de aplicação.

5.1 Execução Seca — KEDA

5.2 Implantar KEDA

Verificação

Fase 6: Serviços de Dados

Finalidade: Supabase (banco de dados), ElastiCache (Redis), RabbitMQ (fila de mensagens).
Implante primeiro o operador CloudNativePG, depois o cluster HA Supabase DB, e então a aplicação Supabase. O cluster DB deve estar pronto antes que o Supabase inicie.

6.1 Execução Seca — Serviços de Dados

Passo 1: Operador CloudNativePG (se habilitado)
Passo 2: HA Supabase DB (se habilitado)
Passo 3: Aplicação Supabase (se habilitada)
Passo 4: Serviços AWS — ElastiCache e RabbitMQ (se habilitados)

6.2 Implantar Serviços de Dados

Passo 1: Operador CloudNativePG (se habilitado)
Passo 2: HA Supabase DB (se habilitado)
Verificar o pooler PgBouncer e credenciais após a implantação:
Use o ClusterIP do pooler (ou EXTERNAL-IP se LoadBalancer) como valor de SUPABASE_POSTGRES_HOST em values/odin-services.yaml e como secret.db.postgresHost em values/supabase.yaml. Passo 3: Aplicação Supabase (se habilitada) Todos os pods do serviço Supabase rodam exclusivamente no NodePool application do Karpenter (apenas On-Demand) para prevenir interrupções Spot.
Passo 4: Serviços AWS — ElastiCache e RabbitMQ (se habilitados)
Verificação
Antes de implantar os Serviços Odin, atualize values/odin-services.yaml com o endpoint Redis, endpoint RabbitMQ e todos os ARNs de certificado obtidos nesta fase.

Fase 7: Serviços Odin

Finalidade: Implantação de aplicação via Helm.
Antes de implantar, reduza temporariamente o fastapiBackend para uma única réplica para a execução inicial de migração do banco de dados — defina replicaCount: 1, workers: 1 e keda.minReplicas: 1. Uma vez que a migração seja concluída com sucesso, reverta esses valores para seus padrões de produção antes de reimplementar.

7.1 Execução Seca — Serviços Odin

7.2 Implantar Serviços Odin

Verificação

Fase 8: Observabilidade SigNoz

Finalidade: Monitoramento de logs e métricas.

8.1 Execução Seca — Charts SigNoz

8.2 Implantar Charts SigNoz

Verificação

Fase 9: Implantação Final

9.1 Implantação Completa

Este apply final lida com quaisquer recursos restantes não direcionados explicitamente nas fases anteriores.

9.2 Verificar Implantação


Solução de Problemas

Problemas de lock de estado
Karpenter não funciona
Problemas com balanceador de carga
Problemas com charts Helm

Limpeza


Monitoramento e Logging


Referência Rápida — Todos os Comandos de Implantação

Substitua nome-do-seu-ambiente pelo nome do seu ambiente real ao longo de todo o processo. Sempre execute execuções secas (terragrunt plan) primeiro para validar sua configuração antes de aplicar alterações.