Pular para o conteúdo
ARGLabs no EKS em vez de ECS: esforço, custo e veredito

ARGLabs no EKS em vez de ECS: esforço, custo e veredito

Escrito pelo Claude Code em 14/10/2026, a partir dos repositórios do ARGLabs. Os preços são de tabela on-demand da us-east-1 a 730 horas por mês, e a base é o dev, duas regiões, a stack completa. São estimativas, não faturas. O post de 2024 ECS ou EKS escolheu o ECS a partir dos requisitos; este põe números nessa escolha. Os dois partem de A nuvem como sistema operacional.

O que mudaria para o arglabs-workload, o statuspage e o dependencytrack se saíssem do ECS Fargate para um cluster EKS, como seria o repositório desse cluster, quanto custaria em EC2, Fargate e Auto Mode, e o que acontece com os sidecars e com o monitoramento que o arglabs-tfmod-ecs-app entrega hoje.

1. Resumo executivo

Migrar tudo para o EKS não vale a pena. Na parte do custo que depende do orquestrador, o dev em duas regiões custa hoje cerca de USD 32 por mês no Fargate Spot, e iria para USD 204 a 275 no EKS com nós Graviton, ou USD 377 no EKS Fargate. São dois control planes por ambiente (USD 146) antes de um único pod. Chegar à paridade com o que o arglabs-tfmod-ecs-app faz hoje leva de 23 a 36 dias de trabalho, e dois pilares do monitoramento mudam de natureza: as métricas das tasks e o widget de custo por app.

Se o objetivo é aprender e escrever sobre EKS, o caminho certo é uma trilha paralela e estacionável (enable_eks_cluster só no dev, uma região, um managed node group Graviton em Spot ou Auto Mode), mantendo o ECS como padrão da plataforma. O detalhe que mais surpreende: o EKS Fargate não roda arm64, e toda imagem do ARGLabs é arm64, construída em um runner ARM.

Custo mensal, dev, 2 regiões
32 → 204
USD por mês, a parte que depende do orquestrador: ECS Spot hoje contra o EKS mais barato (managed node groups Graviton em Spot), 6,4 vezes.
Esforço de migração
23 a 36
dias de trabalho para a paridade funcional dos três apps, do BigBang e do pipeline.
Monitoramento a refazer
9 de 24
widgets do dashboard mudam de fonte; os 15 do ALB continuam iguais. Autoscaling, logs e o widget de custo mudam de mecanismo.
EKS Fargate
só x86
sem Graviton, sem Spot, só sub-redes privadas, mais 256 MB por pod. Descartado para o ARGLabs.

2. O que existe hoje

Três aplicações rodam como serviços ECS Fargate na conta aio, cada uma no seu repositório, conectadas aos ALBs que o BigBang criou. O cluster ECS é um namespace vazio e gratuito, criado pelo arglabs-tfmod-bigbang-ecs-cluster (130 linhas de Terraform) com o Container Insights enhanced no dev, stg e prd.

AppTamanhoRegiõesALBSidecarsSpotParticularidades
arglabs-workload0,25 vCPU / 512 MB, arm64us-east-1 (us-east-2 na base)ext, sub-redes públicas, health check do Route53FireLens (imagem própria com saída para o S3) e ADOT (X-Ray)dev/stg 100%; prd 2 on-demand, depois 50/50O app de exemplo; sobram 334 MB para o app depois dos sidecars
arglabs-cloudteam-statuspage0,25 vCPU / 512 MB, arm64us-east-1intnenhumigualGatus, uma imagem FROM scratch, sem shell
arglabs-cloudteam-dependencytrack2 vCPU / 4 GB, arm64us-east-1intnenhumigualexternal_container_definition: frontend, apiserver e um init container wait-for-db com dependsOn HEALTHY e SUCCESS; Aurora

O que o arglabs-tfmod-ecs-app entrega por app e região

3.427 linhas de Terraform (2.200 sem o variables.tf), 133 variáveis, 798 linhas de testes. Tudo chega junto com a aplicação; nada é instalado no cluster:

  • Service e task definition no Fargate, capacity providers FARGATE e FARGATE_SPOT por service (min_ondemand, spot_weight), um circuit breaker com rollback, as estratégias nativas ROLLING, BLUE_GREEN, CANARY e LINEAR, ECS Exec.
  • Um target group e duas regras de listener no ALB compartilhado (host e /<app>/*), um registro regional no Route53 e, no repositório, o nome ponderado sem região com um health check.
  • Autoscaling por CPU e memória (target tracking a 70%), step scaling de emergência e contagem de requisições por target.
  • 8 alarmes (CPU alta, memória alta, emergência e 5 do ALB, desligados com threshold 0), notificando o tópico SNS de alertas da conta.
  • Um dashboard de 24 widgets: 15 do ALB, 2 do AWS/ECS, 3 do ECS/ContainerInsights, 3 do Logs Insights e o widget de custo do Cost Explorer filtrado por app_name e env.
  • Sidecars: FireLens (Fluent Bit, com a configuração embutida na imagem aio-<app>-fluentbit, saída para stdout mais S3 no bucket de logs da conta, particionada para o Athena) e ADOT (OTLP no localhost, X-Ray).
  • IAM: a execution role (ECR, logs, Secrets Manager) e a task role (X-Ray, Exec, EMF), mais a role workload do repositório, que confia em ecs-tasks.amazonaws.com.

O pipeline não tem nada específico de ECS: o deploy é um terraform apply (wait_for_steady_state = false), e as imagens são arm64, construídas no runner self-hosted linux.arm64 e enviadas só para o ECR da conta dev. Isso é uma boa notícia para uma migração: o build, o lotr e os scripts continuam iguais.

A rede é dual-stack, e as sub-redes apps não têm NAT (saída só por IPv6, pelo egress-only gateway, mais o endpoint do S3), e é por isso que as tasks rodam em public com um IPv4 público. O deployer da conta não tem eks:*, nem iam:*OpenIDConnectProvider*, nem xray:*, e está proibido de criar NAT gateways e endpoints de VPC.

3. Como ficaria no EKS, mantendo o modelo do ARGLabs

A regra do ARGLabs é que o BigBang entrega a plataforma e o time traz junto com o app tudo o que importa. No EKS isso significa um cluster por região e por ambiente, criado pelo BigBang, e um módulo de app que cria os objetos do Kubernetes pelo provider kubernetes do Terraform, sem Helm manual e sem kubectl apply no pipeline.

ECS hoje

Repositório do app · tfmod-ecs-app.tfService, task definition, sidecars, TG e regras no ALB, Route53, autoscaling, alarmes, dashboard, widget de custo, execution e task roles, secrets injetados pelo ECS.Tudo chega com o app; nada é instalado no cluster.
BigBang · arglabs-tfmod-bigbangUm cluster ECS vazio e gratuito, os ALBs int e ext, a zona DNS, o tópico de alertas, o bucket de logs com Athena, o CloudTrail, o dashboard de custo, o deployer.
AWSFargate, ELB, CloudWatch, X-Ray, Secrets Manager

EKS proposto

Repositório do app · tfmod-eks-app.tfNamespace, Deployment, Service, HPA, PDB, uma ServiceAccount com Pod Identity, ExternalSecret, TargetGroupBinding; TG e regras no ALB, Route53, alarmes, dashboard, widget de custo.Os providers kubernetes e helm leem o state da configuração.
BigBang · tfmod-eks-cluster.tf (novo)O cluster EKS (USD 73 por mês), access entries, logs do control plane; add-ons: vpc-cni, coredns, kube-proxy, o pod identity agent, metrics-server, CloudWatch observability (Container Insights e Fluent Bit), o AWS LB Controller, External Secrets, ADOT; node groups Graviton, ou Fargate profiles, ou Auto Mode.Mais o que já existe: ALBs, DNS, SNS, o bucket de logs, CloudTrail.
AWSEC2 ou Fargate, ELB, CloudWatch, X-Ray, Secrets Manager
Onde cada coisa vive. A camada do app continua no repositório do app; a camada da plataforma deixa de ser um namespace vazio. No EKS, a camada do BigBang ganha um control plane com calendário de versões e uma lista de add-ons com matriz de compatibilidade.

As decisões que mantêm o modelo

  • O ALB compartilhado continua. O target group e as regras do listener permanecem no Terraform do app (código reaproveitado do ecs-app), e um TargetGroupBinding do AWS Load Balancer Controller registra os pods nesse TG, em modo ip. O controller não cria nem toca no ALB. Os 15 widgets e os 5 alarmes do ALB continuam idênticos.
  • Uma identidade por app. A role workload do repositório ganha a confiança em pods.eks.amazonaws.com e um aws_eks_pod_identity_association com a ServiceAccount do app. Sem IRSA, e sem OIDC provider por cluster.
  • Secrets. Os SECRET_* ficam em aio/<app>/<env>/app; um ExternalSecret (External Secrets Operator) os materializa como um Secret do Kubernetes, e o Deployment os injeta como variáveis, mantendo o APP_SECRET_KEYS. Quem lê o Secrets Manager passa a ser a identidade do operator, não a execution role.
  • Logs. O Fluent Bit vira um DaemonSet da conta (parte do add-on amazon-cloudwatch-observability, ou do chart aws-for-fluent-bit), com uma configuração por cluster fazendo o que o s3-output.conf faz hoje: JSON para o CloudWatch, e gzip para logs/<app>/YYYY/MM/DD/ no bucket da conta, com o namespace como nome do app.
  • Traces. ADOT pela injeção de sidecar do operator (uma annotation no pod), ou um collector por nó. O app só troca AwsEcsResourceDetector por AwsEksResourceDetector no tracing.py.
  • Ambientes efêmeros (dev-*) viram namespaces no cluster dev em vez de stacks inteiras: mais baratos e mais rápidos que hoje. É o único ponto em que o EKS simplifica algo que o ECS faz com esforço.

4. Os repositórios: cluster, BigBang e módulo do app

arglabs-tfmod-bigbang-eks-cluster (novo, usado só pelo BigBang)

Um cluster por chamada, em uma região, com o nome <scope>-eks-<region short>-<env> (aio-eks-use1-dev), seguindo o padrão do arglabs-tfmod-bigbang-ecs-cluster, mas com um arquivo por grupo de recursos:

terraform/
  terraform.tf              aws >= 6.x, kubernetes, helm, tls
  variables.tf              name, region, kubernetes_version, compute_mode
                            (mng | fargate | auto), node_*, fargate_*,
                            subnet_ids, enable_* per add-on, log retention
  eks-cluster.tf            aws_eks_cluster: authentication_mode API,
                            public endpoint with an allowlist (or private),
                            ip_family ipv4, control plane logs, upgrade_policy
                            STANDARD (avoids extended support by mistake)
  eks-access.tf             access entries: deployer (cluster admin),
                            AWSReservedSSO_AdministratorAccess_* (admin),
                            PowerUserAccess (view), the pipeline runner
  eks-addons.tf             vpc-cni, coredns, kube-proxy, eks-pod-identity-agent,
                            metrics-server, amazon-cloudwatch-observability
  eks-nodegroup.tf          compute_mode = mng: Graviton managed node group,
                            launch template, Spot or on-demand, 1 to N nodes per AZ
  eks-fargate-profile.tf    compute_mode = fargate: one profile per namespace,
                            built-in logging (ConfigMap aws-logging)
  eks-automode.tf           compute_mode = auto: compute_config, a custom
                            arm64 and Spot NodePool
  helm-lb-controller.tf     AWS Load Balancer Controller (Pod Identity),
                            not needed with Auto Mode
  helm-external-secrets.tf  External Secrets Operator + ClusterSecretStore
  helm-adot.tf              ADOT operator and collector (X-Ray)
  iam.tf                    cluster role, node role, add-on roles
                            (Pod Identity associations)
  log_group.tf              /aws/eks/<name>/cluster, retention per env
  cloudwatch_alarms.tf      nodes NotReady, pods Pending, API server 5xx
  cloudwatch_dashboard.tf   the cluster's Container Insights + cost widget
                            (arglabs-tfmod-cost-widget, service Amazon EKS)
  outputs.tf                cluster_name, endpoint, certificate_authority,
                            oidc_issuer, version, node_security_group_id

Estimativa: 1.800 a 2.500 linhas de Terraform, mais testes. Um helm_release e o provider kubernetes na mesma root que cria o cluster é o ponto fraco conhecido desse tipo de módulo (o provider precisa do endpoint antes de ele existir). O BigBang já separa a criação da conta da configuração, e o mesmo corte resolve aqui: o cluster em um apply, os add-ons Helm no seguinte, ou tudo como aws_eks_addon onde existir um add-on gerenciado.

Mudanças no arglabs-tfmod-bigbang e nos vizinhos

OndeO que muda
arglabs-tfmod-bigbangUm novo tfmod-eks-cluster.tf com enable_eks_cluster (padrão false) e eks_compute_mode; novos campos de platform por região: eks_cluster_name, eks_cluster_endpoint, eks_cluster_ca, eks_oidc_issuer, eks_version; a tabela logs do Athena ganha as colunas kubernetes_namespace, kubernetes_pod_name, kubernetes_container_name e kubernetes_pod_id, e a query lines-per-task ganha uma irmã por pod.
arglabs-tfmod-bigbang-iamO deployer ganha eks:* (cluster, node groups, add-ons, access entries e associações do Pod Identity) e, só se o IRSA for usado, iam:CreateOpenIDConnectProvider e afins. ec2:*, iam:PassRole e iam:CreateServiceLinkedRole já existem. Ele continua sem poder criar NAT gateways.
arglabs-bigbang-aioenable_eks_cluster = { dev = true, stg = false, prd = false } para a trilha paralela; o apply do BigBang demora de 12 a 18 minutos a mais enquanto o cluster está ligado (uma estimativa: criar um cluster EKS leva de 10 a 15 minutos).
arglabs-cloudteam-sharedpipelinesUm novo fluxo eks-app (uma cópia do ecs-app) com um passo opcional kubectl rollout status depois do apply, e uma imagem com kubectl. O runner self-hosted precisa alcançar o endpoint da API do EKS (público, com o IP do runner na allowlist, ou privado, com o runner na VPC).
arglabs-lotrNada: a ordem bigbang, dependencytrack, workload, statuspage continua.

arglabs-tfmod-eks-app: o irmão do ecs-app

Reaproveitado do arglabs-tfmod-ecs-app (cerca de 60%)Novo
alb_tg.tf, alb_rule.tf, route53.tf, sg.tf, os 5 alarmes e 15 widgets do ALB, cost_widget.tf, log_group.tf, a estrutura de variáveis por ambiente, os testes de TG e regraskubernetes_namespace, kubernetes_service_account + aws_eks_pod_identity_association, kubernetes_deployment_v1 (o app, um sidecar ADOT opcional, init containers, probes, requests e limits, terminationGracePeriodSeconds), kubernetes_service_v1, kubernetes_horizontal_pod_autoscaler_v2, kubernetes_pod_disruption_budget_v1, kubernetes_manifest para TargetGroupBinding e ExternalSecret, um dashboard reescrito (Container Insights por pod), alarmes de pod (restarts, pending, OOMKilled), KEDA opcional para a contagem de requisições

No repositório do app, o tfmod-eks-app.tf seria mais um arquivo estacionável, com a mesma invariante dos outros: não referencia nenhum outro tf*.tf, lê o cluster do platform, e o iam-role-workload.tf ganha o segundo service principal. Os SECRET_*, os ENV_* e o contrato da imagem não mudam.

5. EC2 (managed node groups), Fargate ou Auto Mode

CritérioManaged node groups (Graviton)EKS FargateEKS Auto Mode
arm64 (as imagens atuais)sim t4g, m7g, c7gnão só x86, segundo a tabela oficial do EKSsim um NodePool arm64 customizado
Spotsim por node groupnãosim por NodePool; a taxa de 12% não recebe desconto
Tamanho mínimoUm t4g.small (2 vCPU, 2 GB) já roda; t4g.medium para os apps pequenos, t4g.large para o Dependency-Track0,25 vCPU / 0,5 GB por pod, mais 256 MB de overhead por pod, arredondado para cimaMais de 1 vCPU e um tamanho medium ou maior: t4g.medium é o menor (USD 27,47 com a taxa)
DaemonSets (Fluent Bit, CloudWatch agent, ADOT)simnão só sidecars; um log router embutido, só para CloudWatch, Firehose, Kinesis ou OpenSearchsim em nós Bottlerocket imutáveis (sem escrita em /etc)
Sub-redes e NAT na rede do ARGLabsNós nas sub-redes públicas com um IPv4 público, como as tasks hoje; ou nas sub-redes apps com saída IPv6 (a validar para ECR e STS)só sub-redes privadas e as sub-redes apps não têm NAT. Exige NAT (USD 33 por gateway por mês) ou saída só IPv6 validada para ECR, STS e CloudWatchComo os managed node groups
Container Insightsenhanced, por observação (cerca de USD 3 a 10 para um cluster pequeno)enhanced não suportado ADOT lendo o kubelet, métricas customizadas a USD 0,30enhanced
Add-ons incluídosvpc-cni, coredns, kube-proxy, pod identity; o resto é add-on ou HelmOs mesmos, mais o log routerLB Controller, EBS CSI, CNI, Karpenter e Pod Identity, gerenciados pela AWS
Upgrades de nós e AMIVocê dispara (um rolling update do node group)A AWS aplica os patches, com evictionsA AWS, com vida máxima de 21 dias por nó
Acesso aos nósSSMNão existe nóSem SSH, sem SSM
Custo além do EC2O EBS do nóPor pod, sem Spot, com overhead12% sobre o preço on-demand da instância
Veredito para o ARGLabsopção 1 se for EKSdescartadoopção 2 menos operação, um pouco mais caro

O que descarta o Fargate não é só o preço. Hoje a plataforma inteira é arm64, do runner linux.arm64 ao cpu_architecture = "ARM64", e o CLAUDE.md já registra a falta de um build x86 como uma lacuna. O EKS Fargate obrigaria a usar imagens x86 (emulação QEMU no runner ARM, ou um segundo runner), só para pagar mais e perder o Spot.

6. Custos

Comparar totais não ajuda: Aurora, Valkey, SQS, SNS, os buckets, Lambda, CloudFront, os ALBs, CloudTrail e DNS custam o mesmo nos dois modelos. As tabelas abaixo isolam a parte que depende do orquestrador: o control plane, o compute dos apps, os pods de sistema e a observabilidade do cluster. O resto da stack completa, pela estimativa de Arglabs, pelo Claude, fica entre USD 180 e 220 por mês no dev com tudo ligado, e some com o lotr_destroy_all.

Premissas e preços (us-east-1, 730 horas por mês)

ItemPreço (USD)Fonte e observação
Fargate arm64 (ECS)0,03238 / vCPU-h; 0,00356 / GB-hPreços do AWS Fargate. O Spot é “até 70% de desconto”: o modelo usa 65%
Fargate x86 (EKS Fargate, a única opção)0,04048 / vCPU-h; 0,004445 / GB-hPreços do AWS Fargate. Mais 256 MB por pod, arredondado para a próxima combinação
Cluster EKS73,00 / mês (0,10 / h)Preços do AWS EKS. Extended support: 0,60 / h, 438,00 / mês
t4g.medium (2 vCPU, 4 GB) e t4g.large (2 vCPU, 8 GB)24,53 e 49,06 / mês0,0336 e 0,0672 / h. Spot modelado com 60% de desconto. EBS gp3 de 20 GB: 1,60 por nó
Taxa do Auto Mode12% do on-demandOs exemplos da página de preços do EKS; sem desconto de Spot ou Savings Plans
NAT gateway32,85 / mês por gateway0,045 / h, mais 0,045 / GB. Só no cenário Fargate (exige sub-redes privadas)
Container InsightsECS 2,00; EKS 5,00; EKS Fargate 15,00 por clusterEstimativas: ECS enhanced a 0,07 / métrica (o blog: 2 a 5 para 2 clusters); EKS enhanced a 0,21 por milhão de observações; Fargate sem enhanced, métricas customizadas a 0,30
Logs do control plane2,00 por clusterUma estimativa, a 0,50 / GB ingerido, com api e audit ligados
Pods de sistema no EKS Fargate9,01 por podcoredns ×2, LB controller, metrics-server, ADOT: cada um cai no mínimo x86 de 0,25 vCPU / 0,5 GB

Ficaram de fora da comparação por serem iguais nos dois: X-Ray (USD 5 por milhão de traces), alarmes (0,10), dashboards (3,00 além dos três gratuitos), o widget de custo (0,01 por chamada ao Cost Explorer), os ALBs, o DNS. Rede e transferência de dados não foram modeladas.

Quanto cada app custa por mês (USD)

AppECS arm64ECS on-demandECS SpotEKS Fargate x86 (pod arredondado para cima)EKS Fargate on-demand
workload (por região)0,25 vCPU / 0,5 GB7,212,520,25 vCPU / 1 GB10,63
statuspage0,25 vCPU / 0,5 GB7,212,520,25 vCPU / 1 GB10,63
dependencytrack2 vCPU / 4 GB57,6720,182 vCPU / 5 GB75,33

Nos cenários com nós, a us-east-1 usa um t4g.large e um t4g.medium, em duas AZs, e a us-east-2 um t4g.medium (só o workload, como a task única de hoje). O Dependency-Track pede 2 vCPU e 4 GB, o que nenhum t4g.medium comporta (4 GiB no total, cerca de 3,4 alocáveis). No Kubernetes ele roda com requests de 1 vCPU e 3,5 GB e limits de 2 vCPU e 4 GB no t4g.large, e os dois apps pequenos dividem os nós com cerca de 1,5 GB de agentes e pods de sistema. Essa diferença entre requests e limits é uma vantagem real do Kubernetes, porque no Fargate você paga pela task inteira. Mesmo com ela, o EKS perde.

Dev, 2 regiões, stack completa: a parte que depende do orquestrador (USD por mês)

CenárioControl planeComputePods de sistemaObservabilidadeTotal× ECS Spot
ECS Fargate arm64, on-demand (o que o prd faria)0,0079,300,004,0083,302,6
ECS Fargate arm64, Spot (dev e stg hoje)0,0027,750,004,0031,751,0
EKS managed node groups, Graviton, on-demand146,00102,910,0014,00262,918,3
EKS managed node groups, Graviton, Spot146,0044,040,0014,00204,046,4
EKS Auto Mode, on-demand146,00114,690,0014,00274,698,7
EKS Auto Mode, Spot (a taxa sobre o preço on-demand)146,0055,820,0014,00215,826,8
EKS Fargate x86, sem Spot (saída IPv6 validada, sem NAT)146,00107,2290,1034,00377,3211,9
EKS Fargate x86, com NAT (um NAT regional por região)146,00172,9290,1034,00443,0214,0
Control planeCompute dos appsPods de sistemaObservabilidade
ECS Fargate arm64, on-demand
o que o prd faria
83,30
ECS Fargate arm64, Spot
dev e stg hoje
31,75
EKS managed node groups, on-demand
262,91
EKS managed node groups, Spot
204,04
EKS Auto Mode, on-demand
274,69
EKS Auto Mode, Spot
a taxa sobre o preço on-demand
215,82
EKS Fargate x86, sem Spot
saída IPv6 validada, sem NAT
377,32
EKS Fargate x86, com NAT
um NAT regional por região
443,02
USD por mês, dev, duas regiões, só a parte que depende do orquestrador: a tabela acima, desenhada. Passe o mouse sobre um segmento para ver o valor.

Três ambientes e os casos de borda

LeituraECSEKS MNGEKS Auto ModeEKS Fargate
dev, stg e prd ligados (dev e stg em Spot onde existe, prd on-demand)146,80670,99706,331.131,96
Um ambiente com “tudo desligado” e o cluster mantido (um cluster ECS vazio não custa nada)0,00146,00146,00146,00
Um ambiente com tudo desligado e o cluster destruído pelo lotr (o apply da infraestrutura demora de 12 a 18 minutos a mais, uma estimativa)0,000,000,000,00
Um cluster esquecido na sua versão (extended support), por cluster0,00+365,00+365,00+365,00
Só o dev, uma região (us-east-1), Spot onde existe: o uso diário de hoje27,23112,63121,46231,64

A ordem de grandeza não muda com as premissas. Mesmo com o Container Insights em zero e o Spot a 70%, o EKS mais barato fica acima de USD 180 por mês no dev com duas regiões, porque USD 146 disso são os dois control planes. Em uma região, a diferença é um valor fixo de USD 73 mais o menor nó, contra uma task Spot de USD 2,52.

7. Monitoramento, item por item

O que o ecs-app entrega hoje, o que faria o mesmo no EKS, o esforço, e se o resultado é melhor, igual ou pior. “Pior” aqui significa mais peças para manter pelo mesmo resultado, não que o Kubernetes monitore mal.

Hoje no ECSEquivalente no EKSEsforçoResultado
CPU e memória do service (AWS/ECS, 2 widgets, 2 alarmes)Container Insights enhanced pelo CloudWatch agent (um DaemonSet) ou as métricas do metrics-server; no Fargate, o ADOT lendo o kubeletMédio: o dashboard e os alarmes reescritos com dimensões de namespace e podmelhor por pod e container, não só por service
Tasks em execução, desejadas e pendentes, I/O de rede, armazenamento efêmero (ECS/ContainerInsights, 3 widgets)pod_number_of_running_pods, pod_network_* e node_filesystem_* do Container Insights do EKSMédioigual
Os 15 widgets e 5 alarmes do ALB (latência, erros, hosts, conexões, TLS, requisições por AZ)Os mesmos: o Terraform continua criando o TG, e o TargetGroupBinding só registra os podsNenhumigual
Autoscaling por target tracking em CPU e memóriaHPA v2 com metrics-server, mínimo e máximo por ambienteBaixoigual
Autoscaling pelas requisições por target do ALBKEDA com o scaler do CloudWatch (mais um operator, identidade e versão), ou métricas customizadas do HPA com o adapter do CloudWatchAltopior
Step scaling de emergência (+50% / +100%)Sem equivalente direto; as políticas behavior.scaleUp do HPA chegam pertoBaixo, com uma perdapior
O circuit breaker de deploy e o rollback automáticoRollingUpdate com readiness probe e progressDeadlineSeconds; um rollback automático exige Argo Rollouts ou um passo do pipelineMédiopior sem Argo
Estratégias nativas BLUE_GREEN, CANARY e LINEAR (sem CodeDeploy)Argo Rollouts com roteamento de tráfego pelo ALB (exige um Ingress gerenciado pelo controller, que conflita com o TG do Terraform), ou dois TGs e dois TargetGroupBindings com pesos nas regrasAltopior
Logs: FireLens para stdout e S3, o Athena da conta com ecs_task_arn, ecs_task_definition, container_idUm DaemonSet de Fluent Bit com o filtro kubernetes: as colunas do app sem mudança, metadados kubernetes.namespace_name, pod_name, container_name, pod_id; as colunas do BigBang e a query lines-per-task mudamMédio, no BigBang e no móduloigual com o kubectl logs de brinde
Widgets do Logs Insights (Deploys / New Tasks por stream, distribuição de níveis, últimas linhas)As mesmas queries sobre o grupo do Fluent Bit, com um stream por pod em vez de por taskBaixoigual
Tracing: o sidecar ADOT, X-Ray, trace.id em cada linha de logUm sidecar ADOT injetado pelo operator, ou um collector por nó; AwsEksResourceDetectorBaixoigual
O widget de custo por app (Cost Explorer filtrado pela tag app_name, propagada da task definition)O Cost Explorer não enxerga o pod: em nós compartilhados o custo pertence ao EC2 do nó. Exige o Split Cost Allocation Data do EKS (CUR 2.0 pelo Data Exports, consultado com o Athena, com o namespace e os labels do pod como dimensões) ou o Kubecost / OpenCost. O widget atual, que chama o Cost Explorer filtrado pela tag app_name, deixa de ver o custo do appAltopior o widget quebra como está
O dashboard de secrets (CloudTrail: leituras por role, falhas, mudanças)O mesmo, mas o principal das leituras passa a ser a identidade do External Secrets Operator: a métrica de “quem leu” perde o detalhe por app, a menos que cada app ganhe o seu próprio SecretStore com a sua própria roleMédiopior
Alertas para SNS e SlackO mesmoNenhumigual
ECS Execkubectl exec com access entries; auditoria pelo audit log do control plane (pago)Baixoigual
O health check do container (CMD-SHELL true)Probes HTTP de liveness, readiness e startup: sem precisar de shellBaixomelhor resolve o status page FROM scratch
Saúde do clusterNovo: nós NotReady, pods Pending e CrashLoopBackOff, a versão e os add-ons a atualizar, o API server. Nada disso existe no ECS, porque lá não há nada que quebrarMédio, novoextra

Onde o EKS monitora melhor

  • Prometheus e Grafana são o padrão do ecossistema. O Amazon Managed Service for Prometheus com o managed collector, e o Amazon Managed Grafana, dão métricas por pod, por namespace e por app, com dashboards prontos (kube-prometheus-stack). O custo: o AMP por amostra ingerida e o AMG por usuário ativo, mais uma stack a manter versionada.
  • O Container Insights enhanced do EKS dá uma visão de pods, nós e namespaces no console, com mais detalhe que a do ECS.
  • O kubectl dá uma visão ao vivo (describe, logs, top, events) que no ECS exige o console ou várias chamadas de CLI.

Nada disso é gratuito nem automático: cada peça é um add-on ou um chart com a sua própria versão. O ecs-app chega ao resultado de hoje só com recursos da AWS no Terraform do app.

8. Os sidecars nas duas opções

FireLens hoje

  • Um container fluentbit essential em cada task, 50 MB reservados, uma imagem própria com o s3-output.conf embutido (aws_fluent_bit_init_file_2), as variáveis LOG_S3_*.
  • Ele faz duas coisas: imprime cada registro JSON no awslogs (o que o console do ECS lê), e envia gzip para logs/<app>/YYYY/MM/DD/ no bucket da conta.
  • Uma falha na saída para o S3 derruba a task (essential).
  • O custo: memória em cada task, e mais uma imagem para construir e escanear (SBOM).

Fluent Bit no EKS com nós

  • Um DaemonSet por cluster (o add-on amazon-cloudwatch-observability, ou o chart aws-for-fluent-bit), uma configuração para todos os apps, lida de um ConfigMap: a imagem aio-<app>-fluentbit e o passo build_sidecars deixam de existir.
  • Memória por nó (cerca de 100 a 150 MB) em vez de por task; o app fica com os seus 50 MB.
  • O filtro kubernetes adiciona o namespace, o pod e o container; o s3_key_format usa o namespace como <app> e mantém o layout do Athena. A tag kube.<ns>.<pod>.<container> substitui o $TAG do FireLens.
  • Um Fluent Bit doente afeta os logs de todos os apps do nó, não de uma task.
  • A saída para stdout deixa de fazer sentido: o kubectl logs lê o stdout do container diretamente.

O log router embutido do EKS Fargate

  • Gerenciado pela AWS, sem pod para pagar, configurado por um ConfigMap aws-logging de no máximo 5.300 caracteres, só com seções Filter, Output e Parser.
  • Saídas permitidas: CloudWatch, Firehose, Kinesis e OpenSearch. Sem S3 direto: o caminho até o Athena vira Firehose com particionamento dinâmico (um custo por GB, e prefixos diferentes do layout de hoje).
  • Sem stdout, sem plugins extras.

ADOT hoje

  • Um container opentelemetry em cada task, 128 MB reservados, ecs-xray.yaml, OTLP no localhost 4317 e 4318; o app recebe as variáveis OTEL_* do módulo.
  • Ele não consegue baixar de public.ecr.aws nas sub-redes apps, que não têm NAT: é por isso que o enable_otel_sidecar fica desligado com app_network = apps.

ADOT no EKS

  • Com nós, dois modos. O operator com injeção de sidecar (a annotation sidecar.opentelemetry.io/inject): o mesmo desenho de hoje, 128 MB por pod, localhost. Ou um collector por nó (um DaemonSet), com o app apontando para o IP do nó (status.hostIP): memória por nó, um salto de rede a mais, mais simples de operar.
  • No Fargate, só sidecar (sem DaemonSets), somando ao tamanho do pod e ao arredondamento.
  • A identidade para o X-Ray vem do Pod Identity da ServiceAccount, não de uma task role.
  • A imagem continua vindo de public.ecr.aws, então o problema de saída das sub-redes apps é o mesmo, resolvido por nós em uma sub-rede pública ou espelhando a imagem no ECR.

O caso do Dependency-Track

  • O wait-for-db vira um initContainer literal; o dependsOn HEALTHY vira as readiness e startup probes do apiserver, e o frontend simplesmente espera pelo Service.
  • O projeto publica um chart Helm oficial, que no EKS tentaria tirar o app do padrão do tfmod-eks-app. Essa decisão precisa ser tomada antes de começar.

Resumindo: com nós, os sidecars de log e de trace podem virar agentes do cluster e devolver 178 MB a cada pod de workload, ao custo de um ponto de falha compartilhado e mais peças para atualizar. No Fargate, o desenho continua como hoje, mais caro e com menos saídas.

9. Esforço de migração

Dias de trabalho focado (uma pessoa mais o Claude) para chegar ao que existe hoje. O ecs-app levou meses de iteração no pipeline; os números abaixo assumem que o código e os testes dele são reaproveitados sempre que servirem.

#EntregávelConteúdoDias
1arglabs-tfmod-bigbang-eks-clusterO cluster, access entries, add-ons, três modos de compute, LB Controller, ESO, ADOT, alarmes, um dashboard com o widget de custo, testes5 a 8
2BigBang, IAM e Athenatfmod-eks-cluster.tf, os campos de platform, eks:* no deployer, as novas colunas e a query do bucket de logs2 a 3
3arglabs-tfmod-eks-appObjetos do Kubernetes pelo provider, TargetGroupBinding, Pod Identity, ExternalSecret, HPA, o dashboard e os alarmes reescritos, testes6 a 10
4arglabs-workloadUm tfmod-eks-app.tf estacionável, a confiança na role workload, tracing.py, o skill configure, CLAUDE.md, TESTS.md, a validate matrix com 11 arquivos3 a 4
5statuspageProbes HTTP no lugar do health check desabilitado1 a 2
6dependencytrackO init container, probes, três containers, os secrets do Aurora por ExternalSecret2
7sharedpipelinesO fluxo eks-app, rollout status, o runner alcançando o endpoint do EKS, uma imagem com kubectl1 a 2
8Validação, docs e blogTestes ponta a ponta no dev, tempos, custos medidos, operations.md, um post3 a 5
Total23 a 36

Ordem e riscos

  1. O módulo do cluster no dev, uma região, compute_mode = mng em Spot. Valide a saída de rede das sub-redes escolhidas (ECR, STS, CloudWatch, X-Ray) antes de qualquer app.
  2. O BigBang com enable_eks_cluster só no dev; meça os tempos de apply e destroy no lotr.
  3. O tfmod-eks-app com o workload; repita os testes ECSAPP001 e SECRETS001 na versão EKS.
  4. statuspage e dependencytrack por último, o segundo com a decisão entre o chart Helm e o módulo.
  • Rede: nós em uma sub-rede pública com um IPv4 público repetem a postura de hoje; sub-redes apps só IPv6 exigem validar os endpoints dual-stack. O Fargate não tem a primeira opção.
  • O runner e a API do EKS: o runner é self-hosted e interno; o endpoint público com allowlist é o caminho simples, enquanto o privado exige o runner na VPC.
  • Nomes: o limite de 64 caracteres dos nomes de role continua valendo; aio-workload-eks-cost-widget-lambda-role-use1-dev tem 49.
  • Calendário: pelo menos um upgrade de versão do Kubernetes por ano, com os add-ons alinhados, ou USD 365 a mais por cluster por mês.
  • Dois vocabulários na mesma root: recursos da AWS e objetos do Kubernetes no mesmo apply funcionam, mas um cluster indisponível faz o plan inteiro falhar.

10. Prós e contras

ECS, como está

  • Um cluster gratuito, sem versão e sem add-ons: o BigBang entrega um namespace vazio e tudo chega junto com o app.
  • Spot por service (min_ondemand, spot_weight), arm64 de ponta a ponta.
  • Monitoramento construído com recursos da AWS no Terraform do app: 24 widgets, alarmes, um widget de custo por app, um dashboard de secrets.
  • Estratégias de deploy nativas com rollback.
  • Uma fronteira de custo clara: uma tag na task definition, e o Cost Explorer responde.
  • Contras: sem catálogo Helm, sem operators, sem namespaces para ambientes efêmeros (cada branch é uma stack), um ecossistema de ferramentas menor, e menos valor de aprendizado para quem precisa de Kubernetes no mercado de trabalho.

EKS

  • A API padrão do mercado, portabilidade, Helm e operators (o próprio Dependency-Track tem um chart), Argo CD como capacidade gerenciada (a partir de USD 22 por mês).
  • Namespaces como ambientes efêmeros: mais rápidos e baratos que hoje.
  • Observabilidade por pod, e o ecossistema Prometheus e Grafana.
  • Probes HTTP resolvem as imagens sem shell.
  • Requests menores que os limits empacotam pods em menos nós; no Fargate você paga pela task inteira.
  • Contras: USD 73 por cluster por mês antes de qualquer pod (146 por ambiente em duas regiões); um calendário de versões; dezenas de peças versionadas (CNI, coredns, kube-proxy, LB controller, metrics-server, ESO, ADOT, Fluent Bit, KEDA, Argo); o widget de custo por app deixa de funcionar sem o Split Cost Allocation; o Spot pertence ao nó, não ao service; o Fargate é só x86, sem Spot; o deployer precisa de novas permissões; dois vocabulários de infraestrutura.

Quando o EKS valeria a pena

  • Se a maior parte do que roda viesse de charts Helm ou precisasse de operators (bancos de dados no cluster, filas, CRDs).
  • Se houvesse dezenas de serviços por conta e ambiente: o control plane se dilui, e os ambientes efêmeros como namespaces compensam.
  • Se o time já falasse Kubernetes, e a plataforma fosse usada por times que esperam kubectl.
  • Se o objetivo fosse um laboratório e conteúdo: uma trilha EKS no ARGLabs dá um bom post, e o seu custo no dev com uma região fica perto de USD 113 por mês enquanto estiver ligada.

Nenhuma das quatro descreve o ARGLabs hoje: três serviços pequenos, uma pessoa, uso diário só no dev, e a tese pública do projeto é justamente que o ECS na conta do próprio time torna desnecessário o cluster compartilhado.

11. Veredito e recomendação

Não migre. A paridade custaria de 23 a 36 dias de trabalho, multiplicaria por 6,4 a parte do custo que depende do orquestrador, refaria 9 dos 24 widgets e quebraria o widget de custo por app, tudo para operar um control plane com calendário próprio. O que o EKS faria melhor (ambientes efêmeros como namespaces, probes, observabilidade por pod) não compensa o que se perde.

Se o EKS entrar, deve ser uma trilha paralela, não uma migração. Um enable_eks_cluster no BigBang, ligado só no dev e em uma região, com um managed node group Graviton em Spot (opção 1) ou Auto Mode (opção 2, menos operação, 5% a 6% mais caro), e um tfmod-eks-app.tf estacionável no workload ao lado do tfmod-ecs-app.tf. A mesma imagem, o mesmo pipeline e o mesmo ALB nas duas trilhas é a demonstração mais honesta da diferença, e o lotr desliga a trilha quando ela não está em uso.

O caminho incremental, se for em frente

  1. arglabs-tfmod-bigbang-eks-cluster com compute_mode = mng e os add-ons mínimos (vpc-cni, coredns, kube-proxy, pod identity, metrics-server, CloudWatch observability). Ainda sem LB Controller.
  2. O BigBang dev com o cluster na us-east-1; meça o apply, o destroy e o custo real por 30 dias no dashboard de custo.
  3. O LB Controller e o tfmod-eks-app com o workload, um TargetGroupBinding no ALB ext; repita os testes do TESTS.md na trilha EKS.
  4. Só então decida sobre statuspage e dependencytrack, e escreva o post com números medidos no lugar das estimativas daqui.

12. Fontes e premissas

  • Amazon EKS pricing: USD 0,10 por cluster-hora (standard), 0,60 (extended), os exemplos da taxa do Auto Mode (12% do on-demand), capabilities (Argo CD a USD 0,03 por hora).
  • AWS Fargate pricing: x86 a 0,000011244 por vCPU-segundo e 0,000001235 por GB-segundo; arm64 a 0,0000089944 e 0,0000009889; Spot até 70% de desconto; mínimo de 1 minuto.
  • EKS on AWS Fargate, considerations: sem DaemonSets, sem Spot, só sub-redes privadas, só targets IP, e a linha da tabela “Can run workloads that require Arm processors: No”.
  • Fargate logging: o ConfigMap aws-logging, as suas seções e os destinos permitidos.
  • EKS Auto Mode e as suas instâncias gerenciadas: as famílias suportadas (t4g incluída), “more than 1 CPU, instance size is not nano, micro or small”, vida máxima de 21 dias, sem SSH nem SSM.
  • IPv6 on EKS clusters: a família é escolhida na criação, pods só IPv6 com NAT no nó para IPv4, o LB Controller em modo IP.
  • TargetGroupBinding: registrar pods em um target group criado fora do Kubernetes.
  • Kubernetes version lifecycle on EKS: 14 meses de standard support; 1.34 até 2026-12-02, 1.35 até 2027-03-27, 1.36 até 2027-08-02 (as datas da 1.35 e da 1.36 vieram de fontes secundárias).
  • CloudWatch pricing: Container Insights enhanced para EKS a 0,21 por milhão de observações; ECS enhanced a 0,07 por métrica; métricas customizadas 0,30; alarmes 0,10; dashboards 3,00; X-Ray 5,00 por milhão de traces.
  • EC2 t4g.medium a USD 0,0336 por hora (us-east-1, on-demand, de agregadores de preços consultados em 2026-10-14; confira na calculadora da AWS antes de orçar).
  • Fatos do ARGLabs: arglabs-workload/CLAUDE.md e docs/operations.md, arglabs-tfmod-ecs-app, arglabs-tfmod-bigbang, arglabs-tfmod-bigbang-iam, arglabs-account-sharednetwork, arglabs-bigbang-aio, e o post Arglabs, pelo Claude, seção “Quanto custa”.

Estimativas, não preços: o Container Insights por cluster, os logs do control plane, o Spot a 65% (Fargate) e 60% (EC2), o número de pods de sistema no Fargate, as linhas de Terraform do novo módulo e os dias de esforço. Transferência de dados, Route53 e os custos que são iguais nos dois modelos ficaram de fora. Os preços foram lidos nas páginas oficiais em 2026-10-14; o modelo é um pequeno script Python que recalcula as tabelas e o gráfico quando uma premissa muda.

Última atualização em