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.
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.
| App | Tamanho | Regiões | ALB | Sidecars | Spot | Particularidades |
|---|---|---|---|---|---|---|
arglabs-workload | 0,25 vCPU / 512 MB, arm64 | us-east-1 (us-east-2 na base) | ext, sub-redes públicas, health check do Route53 | FireLens (imagem própria com saída para o S3) e ADOT (X-Ray) | dev/stg 100%; prd 2 on-demand, depois 50/50 | O app de exemplo; sobram 334 MB para o app depois dos sidecars |
arglabs-cloudteam-statuspage | 0,25 vCPU / 512 MB, arm64 | us-east-1 | int | nenhum | igual | Gatus, uma imagem FROM scratch, sem shell |
arglabs-cloudteam-dependencytrack | 2 vCPU / 4 GB, arm64 | us-east-1 | int | nenhum | igual | external_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
FARGATEeFARGATE_SPOTpor 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 doECS/ContainerInsights, 3 do Logs Insights e o widget de custo do Cost Explorer filtrado porapp_nameeenv. - 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
workloaddo repositório, que confia emecs-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
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.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.EKS proposto
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.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.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
TargetGroupBindingdo AWS Load Balancer Controller registra os pods nesse TG, em modoip. 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
workloaddo repositório ganha a confiança empods.eks.amazonaws.come umaws_eks_pod_identity_associationcom a ServiceAccount do app. Sem IRSA, e sem OIDC provider por cluster. - Secrets. Os
SECRET_*ficam emaio/<app>/<env>/app; umExternalSecret(External Secrets Operator) os materializa como um Secret do Kubernetes, e o Deployment os injeta como variáveis, mantendo oAPP_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 chartaws-for-fluent-bit), com uma configuração por cluster fazendo o que os3-output.conffaz hoje: JSON para o CloudWatch, e gzip paralogs/<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
AwsEcsResourceDetectorporAwsEksResourceDetectornotracing.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_idEstimativa: 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
| Onde | O que muda |
|---|---|
arglabs-tfmod-bigbang | Um 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-iam | O 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-aio | enable_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-sharedpipelines | Um 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-lotr | Nada: 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 regras | kubernetes_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ério | Managed node groups (Graviton) | EKS Fargate | EKS Auto Mode |
|---|---|---|---|
| arm64 (as imagens atuais) | sim t4g, m7g, c7g | não só x86, segundo a tabela oficial do EKS | sim um NodePool arm64 customizado |
| Spot | sim por node group | não | sim por NodePool; a taxa de 12% não recebe desconto |
| Tamanho mínimo | Um t4g.small (2 vCPU, 2 GB) já roda; t4g.medium para os apps pequenos, t4g.large para o Dependency-Track | 0,25 vCPU / 0,5 GB por pod, mais 256 MB de overhead por pod, arredondado para cima | Mais 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) | sim | não só sidecars; um log router embutido, só para CloudWatch, Firehose, Kinesis ou OpenSearch | sim em nós Bottlerocket imutáveis (sem escrita em /etc) |
| Sub-redes e NAT na rede do ARGLabs | Nó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 CloudWatch | Como os managed node groups |
| Container Insights | enhanced, 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,30 | enhanced |
| Add-ons incluídos | vpc-cni, coredns, kube-proxy, pod identity; o resto é add-on ou Helm | Os mesmos, mais o log router | LB Controller, EBS CSI, CNI, Karpenter e Pod Identity, gerenciados pela AWS |
| Upgrades de nós e AMI | Você dispara (um rolling update do node group) | A AWS aplica os patches, com evictions | A AWS, com vida máxima de 21 dias por nó |
| Acesso aos nós | SSM | Não existe nó | Sem SSH, sem SSM |
| Custo além do EC2 | O EBS do nó | Por pod, sem Spot, com overhead | 12% sobre o preço on-demand da instância |
| Veredito para o ARGLabs | opção 1 se for EKS | descartado | opçã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)
| Item | Preço (USD) | Fonte e observação |
|---|---|---|
| Fargate arm64 (ECS) | 0,03238 / vCPU-h; 0,00356 / GB-h | Preç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-h | Preços do AWS Fargate. Mais 256 MB por pod, arredondado para a próxima combinação |
| Cluster EKS | 73,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ês | 0,0336 e 0,0672 / h. Spot modelado com 60% de desconto. EBS gp3 de 20 GB: 1,60 por nó |
| Taxa do Auto Mode | 12% do on-demand | Os exemplos da página de preços do EKS; sem desconto de Spot ou Savings Plans |
| NAT gateway | 32,85 / mês por gateway | 0,045 / h, mais 0,045 / GB. Só no cenário Fargate (exige sub-redes privadas) |
| Container Insights | ECS 2,00; EKS 5,00; EKS Fargate 15,00 por cluster | Estimativas: 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 plane | 2,00 por cluster | Uma estimativa, a 0,50 / GB ingerido, com api e audit ligados |
| Pods de sistema no EKS Fargate | 9,01 por pod | coredns ×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)
| App | ECS arm64 | ECS on-demand | ECS Spot | EKS Fargate x86 (pod arredondado para cima) | EKS Fargate on-demand |
|---|---|---|---|---|---|
| workload (por região) | 0,25 vCPU / 0,5 GB | 7,21 | 2,52 | 0,25 vCPU / 1 GB | 10,63 |
| statuspage | 0,25 vCPU / 0,5 GB | 7,21 | 2,52 | 0,25 vCPU / 1 GB | 10,63 |
| dependencytrack | 2 vCPU / 4 GB | 57,67 | 20,18 | 2 vCPU / 5 GB | 75,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ário | Control plane | Compute | Pods de sistema | Observabilidade | Total | × ECS Spot |
|---|---|---|---|---|---|---|
| ECS Fargate arm64, on-demand (o que o prd faria) | 0,00 | 79,30 | 0,00 | 4,00 | 83,30 | 2,6 |
| ECS Fargate arm64, Spot (dev e stg hoje) | 0,00 | 27,75 | 0,00 | 4,00 | 31,75 | 1,0 |
| EKS managed node groups, Graviton, on-demand | 146,00 | 102,91 | 0,00 | 14,00 | 262,91 | 8,3 |
| EKS managed node groups, Graviton, Spot | 146,00 | 44,04 | 0,00 | 14,00 | 204,04 | 6,4 |
| EKS Auto Mode, on-demand | 146,00 | 114,69 | 0,00 | 14,00 | 274,69 | 8,7 |
| EKS Auto Mode, Spot (a taxa sobre o preço on-demand) | 146,00 | 55,82 | 0,00 | 14,00 | 215,82 | 6,8 |
| EKS Fargate x86, sem Spot (saída IPv6 validada, sem NAT) | 146,00 | 107,22 | 90,10 | 34,00 | 377,32 | 11,9 |
| EKS Fargate x86, com NAT (um NAT regional por região) | 146,00 | 172,92 | 90,10 | 34,00 | 443,02 | 14,0 |
Três ambientes e os casos de borda
| Leitura | ECS | EKS MNG | EKS Auto Mode | EKS Fargate |
|---|---|---|---|---|
| dev, stg e prd ligados (dev e stg em Spot onde existe, prd on-demand) | 146,80 | 670,99 | 706,33 | 1.131,96 |
| Um ambiente com “tudo desligado” e o cluster mantido (um cluster ECS vazio não custa nada) | 0,00 | 146,00 | 146,00 | 146,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,00 | 0,00 | 0,00 | 0,00 |
| Um cluster esquecido na sua versão (extended support), por cluster | 0,00 | +365,00 | +365,00 | +365,00 |
| Só o dev, uma região (us-east-1), Spot onde existe: o uso diário de hoje | 27,23 | 112,63 | 121,46 | 231,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 ECS | Equivalente no EKS | Esforço | Resultado |
|---|---|---|---|
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 kubelet | Médio: o dashboard e os alarmes reescritos com dimensões de namespace e pod | melhor 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 EKS | Médio | igual |
| 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 pods | Nenhum | igual |
| Autoscaling por target tracking em CPU e memória | HPA v2 com metrics-server, mínimo e máximo por ambiente | Baixo | igual |
| Autoscaling pelas requisições por target do ALB | KEDA com o scaler do CloudWatch (mais um operator, identidade e versão), ou métricas customizadas do HPA com o adapter do CloudWatch | Alto | pior |
| Step scaling de emergência (+50% / +100%) | Sem equivalente direto; as políticas behavior.scaleUp do HPA chegam perto | Baixo, com uma perda | pior |
| O circuit breaker de deploy e o rollback automático | RollingUpdate com readiness probe e progressDeadlineSeconds; um rollback automático exige Argo Rollouts ou um passo do pipeline | Médio | pior 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 regras | Alto | pior |
Logs: FireLens para stdout e S3, o Athena da conta com ecs_task_arn, ecs_task_definition, container_id | Um 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 mudam | Médio, no BigBang e no módulo | igual 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 task | Baixo | igual |
Tracing: o sidecar ADOT, X-Ray, trace.id em cada linha de log | Um sidecar ADOT injetado pelo operator, ou um collector por nó; AwsEksResourceDetector | Baixo | igual |
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 app | Alto | pior 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 role | Médio | pior |
| Alertas para SNS e Slack | O mesmo | Nenhum | igual |
| ECS Exec | kubectl exec com access entries; auditoria pelo audit log do control plane (pago) | Baixo | igual |
O health check do container (CMD-SHELL true) | Probes HTTP de liveness, readiness e startup: sem precisar de shell | Baixo | melhor resolve o status page FROM scratch |
| Saúde do cluster | Novo: 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 quebrar | Médio, novo | extra |
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
kubectldá 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
fluentbitessential em cada task, 50 MB reservados, uma imagem própria com os3-output.confembutido (aws_fluent_bit_init_file_2), as variáveisLOG_S3_*. - Ele faz duas coisas: imprime cada registro JSON no
awslogs(o que o console do ECS lê), e envia gzip paralogs/<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 chartaws-for-fluent-bit), uma configuração para todos os apps, lida de um ConfigMap: a imagemaio-<app>-fluentbite o passobuild_sidecarsdeixam 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_formatusa o namespace como<app>e mantém o layout do Athena. A tagkube.<ns>.<pod>.<container>substitui o$TAGdo 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 logslê o stdout do container diretamente.
O log router embutido do EKS Fargate
- Gerenciado pela AWS, sem pod para pagar, configurado por um ConfigMap
aws-loggingde 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
opentelemetryem cada task, 128 MB reservados,ecs-xray.yaml, OTLP no localhost 4317 e 4318; o app recebe as variáveisOTEL_*do módulo. - Ele não consegue baixar de
public.ecr.awsnas sub-redes apps, que não têm NAT: é por isso que oenable_otel_sidecarfica desligado comapp_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-dbvira uminitContainerliteral; odependsOn HEALTHYvira 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ável | Conteúdo | Dias |
|---|---|---|---|
| 1 | arglabs-tfmod-bigbang-eks-cluster | O cluster, access entries, add-ons, três modos de compute, LB Controller, ESO, ADOT, alarmes, um dashboard com o widget de custo, testes | 5 a 8 |
| 2 | BigBang, IAM e Athena | tfmod-eks-cluster.tf, os campos de platform, eks:* no deployer, as novas colunas e a query do bucket de logs | 2 a 3 |
| 3 | arglabs-tfmod-eks-app | Objetos do Kubernetes pelo provider, TargetGroupBinding, Pod Identity, ExternalSecret, HPA, o dashboard e os alarmes reescritos, testes | 6 a 10 |
| 4 | arglabs-workload | Um 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 arquivos | 3 a 4 |
| 5 | statuspage | Probes HTTP no lugar do health check desabilitado | 1 a 2 |
| 6 | dependencytrack | O init container, probes, três containers, os secrets do Aurora por ExternalSecret | 2 |
| 7 | sharedpipelines | O fluxo eks-app, rollout status, o runner alcançando o endpoint do EKS, uma imagem com kubectl | 1 a 2 |
| 8 | Validação, docs e blog | Testes ponta a ponta no dev, tempos, custos medidos, operations.md, um post | 3 a 5 |
| Total | 23 a 36 |
Ordem e riscos
- O módulo do cluster no dev, uma região,
compute_mode = mngem Spot. Valide a saída de rede das sub-redes escolhidas (ECR, STS, CloudWatch, X-Ray) antes de qualquer app. - O BigBang com
enable_eks_clustersó no dev; meça os tempos de apply e destroy no lotr. - O
tfmod-eks-appcom o workload; repita os testesECSAPP001eSECRETS001na versão EKS. - 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-devtem 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
arglabs-tfmod-bigbang-eks-clustercomcompute_mode = mnge os add-ons mínimos (vpc-cni, coredns, kube-proxy, pod identity, metrics-server, CloudWatch observability). Ainda sem LB Controller.- 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.
- O LB Controller e o
tfmod-eks-appcom o workload, um TargetGroupBinding no ALBext; repita os testes doTESTS.mdna trilha EKS. - 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.mdedocs/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.