<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kauê Matos</title>
    <description>The latest articles on DEV Community by Kauê Matos (@ikauedev).</description>
    <link>https://dev.to/ikauedev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1062408%2F843972aa-ce36-4413-b3e0-c21c6a5ba925.png</url>
      <title>DEV Community: Kauê Matos</title>
      <link>https://dev.to/ikauedev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ikauedev"/>
    <language>en</language>
    <item>
      <title>Amazon EKS na prática: arquitetura, funcionamento e boas práticas</title>
      <dc:creator>Kauê Matos</dc:creator>
      <pubDate>Tue, 13 Oct 2026 10:07:54 +0000</pubDate>
      <link>https://dev.to/ikauedev/amazon-eks-na-pratica-arquitetura-funcionamento-e-boas-praticas-3m</link>
      <guid>https://dev.to/ikauedev/amazon-eks-na-pratica-arquitetura-funcionamento-e-boas-praticas-3m</guid>
      <description>&lt;h3&gt;
  
  
  Introdução: o que é o EKS e por que usar
&lt;/h3&gt;

&lt;p&gt;Rodar Kubernetes por conta própria exige manter etcd, API server, scheduler e controllers em alta disponibilidade, aplicar patches e fazer upgrades sem derrubar nada. O EKS tira esse peso das suas costas: o &lt;strong&gt;control plane&lt;/strong&gt; é gerenciado, distribuído em várias Zonas de Disponibilidade e atualizado pela AWS.&lt;/p&gt;

&lt;p&gt;O EKS roda Kubernetes upstream e é certificado como conforme, então manifests, Helm charts e ferramentas do ecossistema funcionam sem adaptação. A diferença está na integração com a AWS: IAM, VPC, ELB, EBS/EFS, CloudWatch, ECR e Secrets Manager.&lt;/p&gt;

&lt;p&gt;Por que adotar o EKS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alta disponibilidade do control plane, com SLA de 99,95% da AWS.&lt;/li&gt;
&lt;li&gt;Integração nativa com IAM, VPC, Load Balancers e observabilidade.&lt;/li&gt;
&lt;li&gt;Ecossistema Kubernetes: Helm, ArgoCD, Prometheus, Istio e operadores.&lt;/li&gt;
&lt;li&gt;Flexibilidade de compute: EC2, Fargate, Spot e Karpenter.&lt;/li&gt;
&lt;li&gt;Portabilidade: o mesmo manifest roda em outro Kubernetes, com menos lock-in.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O ponto de atenção é a complexidade. Para uma aplicação simples em containers, ECS pode ser suficiente. O EKS compensa quando há muitos serviços, necessidade de portabilidade, um ecossistema Kubernetes já adotado ou requisitos avançados de rede e escalabilidade.&lt;/p&gt;

&lt;h3&gt;
  
  
  Arquitetura do cluster: control plane e data plane
&lt;/h3&gt;

&lt;p&gt;Um cluster EKS se divide em duas partes: o &lt;strong&gt;control plane&lt;/strong&gt;, que a AWS gerencia, e o &lt;strong&gt;data plane&lt;/strong&gt;, onde seus pods rodam.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Control plane (gerenciado pela AWS).&lt;/strong&gt; Roda em uma VPC da própria AWS, separada da sua conta, e inclui:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API server: ponto de entrada de todo kubectl e de todos os componentes. Pode ter endpoint público, privado ou ambos.&lt;/li&gt;
&lt;li&gt;etcd: banco chave-valor com o estado do cluster, replicado em três Zonas de Disponibilidade.&lt;/li&gt;
&lt;li&gt;Scheduler: decide em qual nó cada pod vai rodar.&lt;/li&gt;
&lt;li&gt;Controller manager: reconcilia o estado desejado com o estado real.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A AWS provisiona ao menos duas instâncias de API server e três de etcd em AZs diferentes e substitui automaticamente as que falharem. A comunicação com seus nós passa por ENIs (Elastic Network Interfaces) criadas nas suas subnets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data plane (sob sua responsabilidade).&lt;/strong&gt; São os nós dentro da sua VPC. Em cada nó rodam:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;kubelet: agente que mantém os pods no estado desejado.&lt;/li&gt;
&lt;li&gt;kube-proxy: mantém as regras de rede que implementam os Services.&lt;/li&gt;
&lt;li&gt;containerd: o container runtime.&lt;/li&gt;
&lt;li&gt;VPC CNI: plugin que dá a cada pod um IP real da VPC.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Add-ons gerenciados.&lt;/strong&gt; O EKS instala e atualiza componentes essenciais como add-ons: VPC CNI, CoreDNS, kube-proxy, EBS CSI Driver e o Pod Identity Agent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O caminho de um deploy:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O usuário ou o pipeline executa kubectl apply ou um deploy via Helm.&lt;/li&gt;
&lt;li&gt;A requisição chega ao API server, autenticada via IAM e autorizada via RBAC.&lt;/li&gt;
&lt;li&gt;O manifest é gravado no etcd.&lt;/li&gt;
&lt;li&gt;O scheduler escolhe um nó para o pod.&lt;/li&gt;
&lt;li&gt;O kubelet do nó puxa a imagem do ECR e inicia o container.&lt;/li&gt;
&lt;li&gt;O VPC CNI atribui um IP da VPC ao pod, e o kube-proxy atualiza as regras do Service.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Modelos de compute: managed node groups, Fargate e Karpenter
&lt;/h3&gt;

&lt;p&gt;O EKS oferece formas diferentes de prover capacidade, e é comum combiná-las no mesmo cluster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Managed node groups&lt;/strong&gt; são a escolha padrão. A AWS cria as instâncias EC2 num Auto Scaling Group, usa AMIs otimizadas (Amazon Linux 2023 ou Bottlerocket) e faz upgrades com drenagem controlada dos nós. Indicado para cargas gerais, quando você quer controle sobre o tipo de instância. Em contrapartida, você dimensiona os grupos e escolhe as instâncias.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS Fargate&lt;/strong&gt; roda cada pod em seu próprio ambiente isolado, sem nós para administrar. Você define quais pods usam Fargate por meio de Fargate profiles (namespace + labels). Indicado para cargas esporádicas ou com isolamento por pod. Limitações: não suporta DaemonSets nem GPU, e o custo por vCPU costuma ser maior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Karpenter&lt;/strong&gt; observa pods em estado Pending, escolhe a instância mais adequada ao pedido de CPU e memória e a cria em segundos. Também consolida nós subutilizados e remove os ociosos. Indicado para eficiência de custo, uso de Spot e diversidade de instâncias. Exige configurar NodePools e EC2NodeClasses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Self-managed nodes&lt;/strong&gt; deixam toda a operação com você: indicados só para casos especiais, como AMI customizada.&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;EKS Auto Mode&lt;/strong&gt; vai além e automatiza o gerenciamento de compute, rede e armazenamento para você.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rede: VPC CNI, subnets, Services e Ingress
&lt;/h3&gt;

&lt;p&gt;No EKS, &lt;strong&gt;cada pod recebe um IP real da VPC&lt;/strong&gt;, sem overlay nem encapsulamento. Isso é feito pelo plugin Amazon VPC CNI e é o que torna a rede do EKS diferente da maioria dos clusters Kubernetes. O diagrama mostra um cluster em duas AZs (sa-east-1a e sa-east-1b), com um worker node por AZ.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzemlhps3n7rbmhrcpzlk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzemlhps3n7rbmhrcpzlk.png" alt=" " width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Topologia da VPC&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Subnets públicas (10.0.0.0/24 e 10.0.1.0/24): abrigam o Application Load Balancer e os NAT Gateways, com saída pelo Internet Gateway.&lt;/li&gt;
&lt;li&gt;Subnets privadas (10.0.32.0/19 e 10.0.64.0/19): abrigam os worker nodes e os pods. Os /19 oferecem milhares de IPs, o que importa porque cada pod consome um.&lt;/li&gt;
&lt;li&gt;Route tables privadas: tráfego local para 10.0.0.0/16 e 0.0.0.0/0 pelo NAT Gateway da mesma AZ.&lt;/li&gt;
&lt;li&gt;ENIs do control plane: o EKS cria interfaces cross-account nas suas subnets para que o API server converse com o kubelet (porta 10250) e os nós com a API (443).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Como o VPC CNI funciona.&lt;/strong&gt; Cada worker node tem uma ENI primária (eth0) e ENIs secundárias (eth1…) com IPs reservados para pods, o warm pool. Quando um pod é agendado, o plugin aws-node entrega um desses IPs, cria o par veth e adiciona uma rota /32 no namespace de rede do host. O número máximo de pods por nó depende do tipo da instância: ENIs × IPs por ENI. Quando isso limita, a prefix delegation atribui blocos /28 por ENI e aumenta bastante a densidade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Os sete fluxos de comunicação do diagrama:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Entrada: Internet → IGW → ALB nas subnets públicas → direto no IP do pod. Isso é possível porque o AWS Load Balancer Controller usa target-type: ip, sem passar por NodePort.&lt;/li&gt;
&lt;li&gt;Pod ↔ pod no mesmo nó: via veth e rotas /32 no host. O tráfego não sai do nó.&lt;/li&gt;
&lt;li&gt;Pod ↔ pod entre nós ou AZs: sai pela ENI e é roteado nativamente pela VPC, sem encapsulamento.&lt;/li&gt;
&lt;li&gt;Saída para a internet: pod → NAT Gateway → IGW, com SNAT para o Elastic IP.&lt;/li&gt;
&lt;li&gt;Serviços AWS: ECR, S3, STS e CloudWatch Logs via VPC Endpoints, com credenciais por IRSA ou Pod Identity.&lt;/li&gt;
&lt;li&gt;Control plane: o kubelet fala com a API pelas ENIs cross-account, e o kubectl de dev ou CI/CD usa o endpoint público ou privado na porta 443.&lt;/li&gt;
&lt;li&gt;Services e DNS: o pod acessa o ClusterIP (172.20.0.0/16), o kube-proxy faz DNAT para os IPs reais dos pods, e o CoreDNS resolve *.svc.cluster.local.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Services, Ingress e segurança de rede.&lt;/strong&gt; Os Services são IPs virtuais: o ClusterIP não existe na VPC, só nas regras de iptables ou IPVS gravadas pelo kube-proxy. Para expor ao mundo, o AWS Load Balancer Controller transforma um Ingress em ALB (HTTP/HTTPS) e um Service do tipo LoadBalancer em NLB (TCP/UDP). A segurança de rede opera em três camadas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Security Groups do nó e do cluster, no nível da VPC.&lt;/li&gt;
&lt;li&gt;Security Groups for Pods (opcional), que aplicam SGs diretamente a pods específicos.&lt;/li&gt;
&lt;li&gt;Network Policies, via VPC CNI ou Calico, para regras entre pods dentro do cluster.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Segurança e identidade: IAM, IRSA, Pod Identity e RBAC
&lt;/h3&gt;

&lt;p&gt;O EKS usa duas camadas de controle: o &lt;strong&gt;IAM&lt;/strong&gt; decide quem é você na AWS, e o &lt;strong&gt;RBAC&lt;/strong&gt; do Kubernetes decide o que você pode fazer dentro do cluster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Acesso ao cluster.&lt;/strong&gt; As pessoas e pipelines se autenticam com IAM e são mapeados a permissões do Kubernetes. O mecanismo moderno são as EKS Access Entries, que substituem o antigo ConfigMap aws-auth: você associa um principal IAM a uma access policy ou a grupos RBAC, tudo pela API da AWS e versionável em Terraform.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Acesso dos pods à AWS.&lt;/strong&gt; Pods não devem usar as credenciais do nó, porque todos os pods do nó herdariam as mesmas permissões. Há dois mecanismos para dar a cada workload um papel IAM próprio:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IRSA (IAM Roles for Service Accounts): usa o provedor OIDC do cluster e uma ServiceAccount anotada com o ARN da role. Boa escolha para clusters existentes e ampla compatibilidade.&lt;/li&gt;
&lt;li&gt;EKS Pod Identity: add-on com agente no nó, associação feita pela API do EKS, sem OIDC por cluster. Indicado para novos clusters, com gestão mais simples e roles reutilizáveis entre clusters.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Em ambos os casos vale o princípio do menor privilégio: uma role por aplicação, com apenas as ações que ela precisa.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Boas práticas de segurança:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Endpoint privado do API server, ou público restrito por CIDR.&lt;/li&gt;
&lt;li&gt;Nós em subnets privadas, com acesso à AWS por VPC Endpoints.&lt;/li&gt;
&lt;li&gt;Secrets no AWS Secrets Manager, montados via Secrets Store CSI Driver, e criptografia de envelope com KMS.&lt;/li&gt;
&lt;li&gt;Pod Security Standards para impedir containers privilegiados.&lt;/li&gt;
&lt;li&gt;Network Policies para restringir comunicação entre namespaces.&lt;/li&gt;
&lt;li&gt;Imagens do ECR com scan habilitado.&lt;/li&gt;
&lt;li&gt;Audit logs do control plane enviados ao CloudWatch.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Integrando o EKS ao banco: exemplo com RDS
&lt;/h3&gt;

&lt;p&gt;Bancos de dados raramente rodam dentro do cluster: o padrão é usar um serviço gerenciado como o Amazon RDS numa subnet de banco separada e deixar os pods se conectarem a ele pela rede da VPC.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Security Groups: o SG do banco libera a porta (5432 no PostgreSQL) apenas para o SG dos nós ou, com Security Groups for Pods, apenas para o SG dos pods da aplicação.&lt;/li&gt;
&lt;li&gt;Endpoint estável: a aplicação usa o endpoint DNS do RDS, guardado num ConfigMap ou num Service do tipo ExternalName. Assim o nome interno fica independente do endpoint real.&lt;/li&gt;
&lt;li&gt;Credenciais: usuário e senha no Secrets Manager, lidos pelo pod com IRSA ou Pod Identity, sem senha em manifest.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Observabilidade, escalabilidade e custos
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Observabilidade.&lt;/strong&gt; Um cluster em produção precisa de logs, métricas e traces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logs do control plane (api, audit, authenticator, controllerManager, scheduler): habilitados por cluster e enviados ao CloudWatch Logs.&lt;/li&gt;
&lt;li&gt;Container Insights: métricas de CPU, memória e rede por nó, pod e namespace.&lt;/li&gt;
&lt;li&gt;Prometheus e Grafana: o Amazon Managed Service for Prometheus e o Amazon Managed Grafana evitam operar essa stack.&lt;/li&gt;
&lt;li&gt;Traces: OpenTelemetry com AWS X-Ray ou outro backend compatível.&lt;/li&gt;
&lt;li&gt;Alarmes: pods em CrashLoopBackOff, nós NotReady e falhas de agendamento.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Escalabilidade.&lt;/strong&gt; Há três níveis de escala, e eles trabalham juntos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;HPA (Horizontal Pod Autoscaler): ajusta o número de réplicas por CPU, memória ou métricas customizadas.&lt;/li&gt;
&lt;li&gt;Karpenter ou Cluster Autoscaler: adiciona ou remove nós conforme pods pendentes ou capacidade ociosa.&lt;/li&gt;
&lt;li&gt;KEDA: escala por eventos externos, como o tamanho de uma fila SQS.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Defina sempre requests e limits de recursos: sem eles o scheduler decide às cegas, e o HPA por utilização não funciona.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Custos.&lt;/strong&gt; O custo do EKS tem três componentes: a taxa fixa por hora do cluster, as instâncias EC2 ou o Fargate, e itens associados como NAT Gateway, load balancers, transferência entre AZs e volumes EBS. Para reduzir:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spot para cargas tolerantes a interrupção.&lt;/li&gt;
&lt;li&gt;Karpenter com consolidação de nós.&lt;/li&gt;
&lt;li&gt;Graviton para muitas cargas, com bom custo-benefício.&lt;/li&gt;
&lt;li&gt;VPC Endpoints para reduzir o tráfego pelo NAT Gateway.&lt;/li&gt;
&lt;li&gt;Right-sizing de requests, com VPA ou Goldilocks.&lt;/li&gt;
&lt;li&gt;Manter o cluster em versão suportada: versões antigas entram em suporte estendido, cobrado a mais.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Provisionando com Terraform e fazendo deploy com GitHub Actions
&lt;/h3&gt;

&lt;p&gt;Em produção o cluster deve ser código: versionado, revisado e reproduzível.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Terraform.&lt;/strong&gt; O caminho mais comum é o módulo terraform-aws-modules/eks/aws junto com o módulo de VPC. O exemplo é um esqueleto: confira versões e parâmetros na documentação dos módulos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;"vpc"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"terraform-aws-modules/vpc/aws"&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eks-vpc"&lt;/span&gt;
  &lt;span class="nx"&gt;cidr&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"10.0.0.0/16"&lt;/span&gt;
  &lt;span class="nx"&gt;azs&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"sa-east-1a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"sa-east-1b"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="nx"&gt;public_subnets&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"10.0.0.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"10.0.1.0/24"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;private_subnets&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"10.0.32.0/19"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"10.0.64.0/19"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="nx"&gt;enable_nat_gateway&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;"eks"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"terraform-aws-modules/eks/aws"&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"meu-cluster"&lt;/span&gt;

  &lt;span class="nx"&gt;vpc_id&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vpc_id&lt;/span&gt;
  &lt;span class="nx"&gt;subnet_ids&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;private_subnets&lt;/span&gt;

  &lt;span class="nx"&gt;endpoint_public_access&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

  &lt;span class="nx"&gt;eks_managed_node_groups&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;instance_types&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"m6i.large"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="nx"&gt;min_size&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
      &lt;span class="nx"&gt;max_size&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
      &lt;span class="nx"&gt;desired_size&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Boas práticas: state remoto em S3 com lock, módulos com versão fixa e plano revisado em pull request antes do apply.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub Actions.&lt;/strong&gt; O pipeline típico faz build da imagem, publica no ECR e atualiza o Deployment. Use OIDC entre o GitHub e a AWS, sem chaves de longa duração guardadas como secret.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;id-token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
  &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/configure-aws-credentials@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;role-to-assume&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arn:aws:iam::&amp;lt;conta&amp;gt;:role/github-deploy&lt;/span&gt;
          &lt;span class="na"&gt;aws-region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sa-east-1&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/amazon-ecr-login@v2&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ecr&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build e push&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;IMAGE=${{ steps.ecr.outputs.registry }}/api:${{ github.sha }}&lt;/span&gt;
          &lt;span class="s"&gt;docker build -t $IMAGE .&lt;/span&gt;
          &lt;span class="s"&gt;docker push $IMAGE&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;aws eks update-kubeconfig --name meu-cluster&lt;/span&gt;
          &lt;span class="s"&gt;kubectl set image deployment/api api=$IMAGE&lt;/span&gt;
          &lt;span class="s"&gt;kubectl rollout status deployment/api&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A role do pipeline recebe acesso ao cluster por uma Access Entry. Em ambientes maiores, vale considerar GitOps com ArgoCD ou Flux, em que o cluster puxa o estado desejado do Git.&lt;/p&gt;

&lt;h3&gt;
  
  
  Boas práticas e conclusão
&lt;/h3&gt;

&lt;p&gt;O EKS entrega um control plane confiável e deixa para você as decisões que definem a qualidade da operação: rede, identidade, compute e observabilidade. Checklist de produção:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cluster em pelo menos duas AZs, com nós em subnets privadas.&lt;/li&gt;
&lt;li&gt;Subnets com IPs suficientes para os pods (CIDR /19 ou maior, ou prefix delegation).&lt;/li&gt;
&lt;li&gt;Add-ons gerenciados (VPC CNI, CoreDNS, kube-proxy, EBS CSI) atualizados.&lt;/li&gt;
&lt;li&gt;Access Entries para pessoas e pipelines, e IRSA ou Pod Identity para pods, sempre com menor privilégio.&lt;/li&gt;
&lt;li&gt;Endpoint do API server restrito, secrets fora do etcd e criptografia com KMS.&lt;/li&gt;
&lt;li&gt;Requests e limits em todos os workloads, com HPA e Karpenter ou Cluster Autoscaler.&lt;/li&gt;
&lt;li&gt;PodDisruptionBudgets e topologySpreadConstraints para sobreviver a upgrades e falhas de AZ.&lt;/li&gt;
&lt;li&gt;Logs do control plane, Container Insights e alarmes configurados.&lt;/li&gt;
&lt;li&gt;Infraestrutura em Terraform e deploys por pipeline com OIDC ou GitOps.&lt;/li&gt;
&lt;li&gt;Upgrades de versão planejados, um minor por vez, testados antes em ambiente não produtivo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O EKS não é o caminho mais simples para rodar containers, mas é um dos mais completos quando o objetivo é um ambiente padronizado, seguro e escalável. Entender a arquitetura, em especial a rede baseada em ENIs e IPs reais da VPC, é o que separa um cluster que apenas funciona de um que se opera com previsibilidade.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>aws</category>
      <category>cloud</category>
      <category>cloudcomputing</category>
    </item>
    <item>
      <title>Backstage o portal de desenvolvedores da CNCF, como funciona por dentro</title>
      <dc:creator>Kauê Matos</dc:creator>
      <pubDate>Thu, 08 Oct 2026 00:59:33 +0000</pubDate>
      <link>https://dev.to/ikauedev/backstage-o-portal-de-desenvolvedores-da-cncf-como-funciona-por-dentro-1c2l</link>
      <guid>https://dev.to/ikauedev/backstage-o-portal-de-desenvolvedores-da-cncf-como-funciona-por-dentro-1c2l</guid>
      <description>&lt;p&gt;O Backstage é um framework open source para construir portais de desenvolvedores: uma interface única onde times encontram seus serviços, criam novos projetos a partir de modelos padronizados, leem a documentação e acessam as ferramentas de infraestrutura que usam no dia a dia. Ele não é um produto pronto para instalar e usar; é uma base que você monta, estende com plugins e hospeda por conta própria.&lt;/p&gt;

&lt;p&gt;O projeto nasceu dentro do Spotify, para domar a quantidade crescente de serviços e ferramentas internas. Foi aberto ao público em março de 2020, doado à CNCF (Cloud Native Computing Foundation) como projeto Sandbox em setembro de 2020 e promovido ao nível Incubating em março de 2022. Hoje é uma das bases mais usadas para o que o mercado chama de &lt;strong&gt;Internal Developer Portal&lt;/strong&gt; (IDP).&lt;/p&gt;

&lt;p&gt;Tecnicamente, o Backstage é uma aplicação TypeScript: um frontend em React e um backend em Node.js, ligados por um sistema de plugins. Este artigo percorre o problema que ele resolve, sua arquitetura, os três pilares (Catalog, Templates e TechDocs), o modelo de plugins, autenticação, deploy e o que esperar da adoção.&lt;/p&gt;

&lt;h2&gt;
  
  
  O problema que o Backstage resolve
&lt;/h2&gt;

&lt;p&gt;O Backstage ataca a carga cognitiva de quem desenvolve software em uma organização com muitos times, serviços e ferramentas. Em empresas que adotam microsserviços e nuvem, as mesmas perguntas se repetem o tempo todo, e a resposta fica espalhada em wikis, planilhas, chats e na cabeça de poucas pessoas.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Quem é dono deste serviço?&lt;/strong&gt; E onde está o repositório, o pipeline, o dashboard e o canal de plantão?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Como crio um novo serviço seguindo o padrão da empresa?&lt;/strong&gt; Cada time acaba montando o seu, com variações de pipeline, segurança e observabilidade.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Onde está a documentação, e ela está atualizada?&lt;/strong&gt; Wikis desconectadas do código envelhecem rápido.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quais serviços dependem de qual API?&lt;/strong&gt; Sem esse mapa, avaliar o impacto de uma mudança vira investigação manual.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A resposta do Backstage é centralizar esses metadados em um catálogo vivo, alimentado pelos próprios repositórios, e expor sobre ele ações e visões: criar, documentar, observar e operar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Onde entra o platform engineering
&lt;/h3&gt;

&lt;p&gt;O Backstage é a camada de interface de uma &lt;strong&gt;plataforma interna de desenvolvedores&lt;/strong&gt;. Um time de plataforma oferece capacidades prontas (pipelines, ambientes, templates, observabilidade) e o portal é a vitrine de autoatendimento delas. A ideia central são os &lt;strong&gt;golden paths&lt;/strong&gt;: caminhos recomendados e já configurados que tornam o jeito certo de fazer também o jeito mais fácil. Quem quiser sair do caminho pode, mas quem seguir ganha velocidade e segurança por padrão.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arquitetura
&lt;/h2&gt;

&lt;p&gt;O Backstage tem uma arquitetura em camadas: um frontend React que roda no navegador, um backend Node.js que concentra a lógica, as credenciais e o acesso a dados, e as fontes externas que o backend consulta em nome do usuário.&lt;/p&gt;

&lt;p&gt;[embedded content: arquitetura do Backstage · 3 camadas]&lt;/p&gt;

&lt;p&gt;O navegador conversa apenas com o backend, e é o backend que acessa o PostgreSQL, o armazenamento do TechDocs e os sistemas externos, o que mantém tokens e segredos fora do alcance do usuário.&lt;/p&gt;

&lt;h3&gt;
  
  
  As peças
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; uma aplicação de página única em React. Cada plugin registra suas páginas e seus componentes, e o app os compõe em rotas, abas de entidade e cartões.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; um processo Node.js (TypeScript) que hospeda os plugins de servidor. Cada plugin é isolado: tem seus endpoints, seu esquema de banco e seus serviços injetados (logger, banco, configuração, autenticação).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Banco de dados:&lt;/strong&gt; guarda o estado do catálogo, o histórico das tarefas do Scaffolder e dados de outros plugins. PostgreSQL em produção.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Armazenamento de objetos:&lt;/strong&gt; opcional, usado pelo TechDocs para servir a documentação já gerada.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sistemas externos:&lt;/strong&gt; repositórios Git, clusters Kubernetes, ferramentas de CI/CD, provedores de identidade e nuvens, acessados por plugins e integrações configuradas no &lt;code&gt;app-config.yaml&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Os dois processos costumam ser publicados juntos: o backend serve também os arquivos estáticos do frontend, e todo o conjunto vira uma única imagem de contêiner. Em instalações maiores, é possível separar frontend e backend ou dividir o backend em vários serviços por plugin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Software Catalog
&lt;/h2&gt;

&lt;p&gt;O Software Catalog é o coração do Backstage: um inventário central de tudo o que a organização constrói e opera, com donos, relações e links para as ferramentas de cada item. Os outros pilares dependem dele para saber de qual serviço se está falando.&lt;/p&gt;

&lt;h3&gt;
  
  
  O modelo de entidades
&lt;/h3&gt;

&lt;p&gt;Cada item do catálogo é uma &lt;strong&gt;entidade&lt;/strong&gt;, descrita por um arquivo YAML com &lt;code&gt;apiVersion&lt;/code&gt;, &lt;code&gt;kind&lt;/code&gt;, &lt;code&gt;metadata&lt;/code&gt; e &lt;code&gt;spec&lt;/code&gt;. Os tipos (&lt;code&gt;kind&lt;/code&gt;) padrão são:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Kind&lt;/th&gt;
&lt;th&gt;Representa&lt;/th&gt;
&lt;th&gt;Exemplo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Component&lt;/td&gt;
&lt;td&gt;Uma unidade de software&lt;/td&gt;
&lt;td&gt;Serviço, website, biblioteca&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API&lt;/td&gt;
&lt;td&gt;Uma interface exposta por um componente&lt;/td&gt;
&lt;td&gt;OpenAPI, gRPC, GraphQL, AsyncAPI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resource&lt;/td&gt;
&lt;td&gt;Infraestrutura da qual componentes dependem&lt;/td&gt;
&lt;td&gt;Banco, fila, bucket S3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;System&lt;/td&gt;
&lt;td&gt;Conjunto de componentes, APIs e recursos que formam um produto&lt;/td&gt;
&lt;td&gt;Sistema de pagamentos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Domain&lt;/td&gt;
&lt;td&gt;Agrupamento de sistemas de uma área de negócio&lt;/td&gt;
&lt;td&gt;Financeiro&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Group&lt;/td&gt;
&lt;td&gt;Time ou unidade organizacional&lt;/td&gt;
&lt;td&gt;Time de plataforma&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User&lt;/td&gt;
&lt;td&gt;Pessoa&lt;/td&gt;
&lt;td&gt;Desenvolvedor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Location&lt;/td&gt;
&lt;td&gt;Ponteiro para outros arquivos de descritor&lt;/td&gt;
&lt;td&gt;Repositório com vários YAMLs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;As entidades se ligam por relações como &lt;code&gt;ownedBy&lt;/code&gt;, &lt;code&gt;dependsOn&lt;/code&gt;, &lt;code&gt;providesApi&lt;/code&gt;, &lt;code&gt;consumesApi&lt;/code&gt; e &lt;code&gt;partOf&lt;/code&gt;. É isso que permite responder, por exemplo, quais componentes consomem uma API que será descontinuada.&lt;/p&gt;

&lt;h3&gt;
  
  
  O descritor catalog-info.yaml
&lt;/h3&gt;

&lt;p&gt;Por convenção, cada repositório guarda na raiz um &lt;code&gt;catalog-info.yaml&lt;/code&gt; que descreve seu componente. O metadado vive junto do código, versionado e revisado como qualquer outra mudança.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;backstage.io/v1alpha1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Component&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;servico-pagamentos&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;API de processamento de pagamentos&lt;/span&gt;
  &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;github.com/project-slug&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;minha-org/servico-pagamentos&lt;/span&gt;
    &lt;span class="na"&gt;backstage.io/techdocs-ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dir:.&lt;/span&gt;
  &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;java&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;spring-boot&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;service&lt;/span&gt;
  &lt;span class="na"&gt;lifecycle&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;production&lt;/span&gt;
  &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;group:time-pagamentos&lt;/span&gt;
  &lt;span class="na"&gt;system&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;plataforma-financeira&lt;/span&gt;
  &lt;span class="na"&gt;providesApis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;api-pagamentos&lt;/span&gt;
  &lt;span class="na"&gt;dependsOn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;resource:default/postgres-pagamentos&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As &lt;strong&gt;annotations&lt;/strong&gt; são o mecanismo de ligação com plugins: a de &lt;code&gt;github.com/project-slug&lt;/code&gt; faz o plugin do GitHub saber qual repositório mostrar na página da entidade, e a de &lt;code&gt;backstage.io/techdocs-ref&lt;/code&gt; indica onde está a documentação.&lt;/p&gt;

&lt;h3&gt;
  
  
  Como o catálogo é alimentado
&lt;/h3&gt;

&lt;p&gt;O backend do catálogo roda um processo contínuo de ingestão em três etapas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Entity providers&lt;/strong&gt; descobrem descritores. Há providers para GitHub, GitLab, Bitbucket, Azure DevOps, AWS S3 e outros, e eles podem varrer uma organização inteira procurando &lt;code&gt;catalog-info.yaml&lt;/code&gt;. Também é possível registrar uma URL manualmente na interface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Processors&lt;/strong&gt; validam cada entidade, resolvem referências, emitem relações e podem enriquecê-la com dados externos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stitching&lt;/strong&gt; consolida o resultado final de cada entidade e o grava no banco, de onde o frontend lê.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O catálogo atualiza em ciclos periódicos, então uma mudança no YAML aparece no portal após alguns minutos, sem ação manual. Dados de organização (grupos e usuários) costumam vir de um provedor de identidade, como Microsoft Entra ID, Okta, LDAP ou GitHub, para manter os donos sincronizados com a realidade.&lt;/p&gt;

&lt;h2&gt;
  
  
  Software Templates
&lt;/h2&gt;

&lt;p&gt;Os Software Templates (o plugin &lt;em&gt;Scaffolder&lt;/em&gt;) transformam um formulário em um repositório novo, já configurado, e registrado no catálogo. O desenvolvedor escolhe um modelo, preenche alguns campos e, minutos depois, tem código, pipeline, documentação e dono definidos, sem abrir chamado para o time de plataforma.&lt;/p&gt;

&lt;h3&gt;
  
  
  Como um template é definido
&lt;/h3&gt;

&lt;p&gt;Um template é uma entidade do catálogo com &lt;code&gt;kind: Template&lt;/code&gt;. Ele declara os &lt;strong&gt;parâmetros&lt;/strong&gt; (que viram um formulário gerado a partir de JSON Schema) e os &lt;strong&gt;passos&lt;/strong&gt; (ações executadas em sequência).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scaffolder.backstage.io/v1beta3&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Template&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;servico-spring-boot&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Novo serviço Spring Boot&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Cria um serviço Java com pipeline e docs prontos&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;group:time-plataforma&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;service&lt;/span&gt;

  &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Informações do serviço&lt;/span&gt;
      &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;nome&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;dono&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;nome&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
          &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Nome do serviço&lt;/span&gt;
        &lt;span class="na"&gt;dono&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
          &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Time responsável&lt;/span&gt;
          &lt;span class="na"&gt;ui:field&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;OwnerPicker&lt;/span&gt;
          &lt;span class="na"&gt;ui:options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;allowedKinds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Group&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Destino&lt;/span&gt;
      &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;repoUrl&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;repoUrl&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
          &lt;span class="na"&gt;ui:field&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;RepoUrlPicker&lt;/span&gt;
          &lt;span class="na"&gt;ui:options&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;allowedHosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;github.com&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

  &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fetch&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Gerar código a partir do esqueleto&lt;/span&gt;
      &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fetch:template&lt;/span&gt;
      &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./skeleton&lt;/span&gt;
        &lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;nome&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ parameters.nome }}&lt;/span&gt;
          &lt;span class="na"&gt;dono&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ parameters.dono }}&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;publish&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Criar repositório&lt;/span&gt;
      &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;publish:github&lt;/span&gt;
      &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;repoUrl&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ parameters.repoUrl }}&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ parameters.nome }}&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;register&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Registrar no catálogo&lt;/span&gt;
      &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;catalog:register&lt;/span&gt;
      &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;repoContentsUrl&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps['publish'].output.repoContentsUrl }}&lt;/span&gt;
        &lt;span class="na"&gt;catalogInfoPath&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/catalog-info.yaml&lt;/span&gt;

  &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;links&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Repositório&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps['publish'].output.remoteUrl }}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Abrir no catálogo&lt;/span&gt;
        &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;catalog&lt;/span&gt;
        &lt;span class="na"&gt;entityRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps['register'].output.entityRef }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Peças do mecanismo
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Esqueleto (skeleton):&lt;/strong&gt; uma pasta de arquivos com marcadores &lt;code&gt;${{ values.nome }}&lt;/code&gt;, renderizada pela ação &lt;code&gt;fetch:template&lt;/code&gt; (engine Nunjucks). É nele que ficam o Dockerfile, o workflow de CI, o &lt;code&gt;catalog-info.yaml&lt;/code&gt; e a estrutura de documentação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ações:&lt;/strong&gt; funções que o backend executa, como &lt;code&gt;fetch:template&lt;/code&gt;, &lt;code&gt;publish:github&lt;/code&gt;, &lt;code&gt;publish:gitlab&lt;/code&gt; e &lt;code&gt;catalog:register&lt;/code&gt;. É possível escrever ações customizadas, por exemplo para criar um recurso em nuvem ou abrir um ticket.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Campos de formulário:&lt;/strong&gt; componentes como &lt;code&gt;OwnerPicker&lt;/code&gt; e &lt;code&gt;RepoUrlPicker&lt;/code&gt; dão uma experiência guiada, e há suporte a campos customizados.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execução e log:&lt;/strong&gt; cada execução vira uma tarefa com log em tempo real na interface, o que facilita diagnosticar falhas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O valor para a organização está no que o esqueleto embute: padrões de segurança, observabilidade, estrutura de pipeline e metadados de catálogo nascem corretos em todo serviço novo. Atualizar o template melhora os próximos projetos, mas não altera os já criados, ponto que costuma exigir uma estratégia à parte de manutenção.&lt;/p&gt;

&lt;h2&gt;
  
  
  TechDocs
&lt;/h2&gt;

&lt;p&gt;O TechDocs aplica a ideia de &lt;em&gt;docs-like-code&lt;/em&gt;: a documentação técnica fica em Markdown dentro do mesmo repositório do código e aparece no portal, na página do componente. Quem muda o código muda a documentação no mesmo pull request, o que reduz o envelhecimento.&lt;/p&gt;

&lt;h3&gt;
  
  
  Como funciona
&lt;/h3&gt;

&lt;p&gt;O TechDocs usa o &lt;strong&gt;MkDocs&lt;/strong&gt; como gerador de site estático, com o plugin &lt;code&gt;techdocs-core&lt;/code&gt;. A configuração fica em um &lt;code&gt;mkdocs.yml&lt;/code&gt; na raiz do repositório, e a entidade aponta para ele pela annotation &lt;code&gt;backstage.io/techdocs-ref&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# mkdocs.yml&lt;/span&gt;
&lt;span class="na"&gt;site_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;servico-pagamentos&lt;/span&gt;
&lt;span class="na"&gt;nav&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Início&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;index.md&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Arquitetura&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arquitetura.md&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Runbooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;runbooks.md&lt;/span&gt;
&lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;techdocs-core&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Duas estratégias de build
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Estratégia&lt;/th&gt;
&lt;th&gt;Quem gera o site&lt;/th&gt;
&lt;th&gt;Quando usar&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Basic (&lt;code&gt;techdocs.builder: local&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;O próprio backend do Backstage, sob demanda&lt;/td&gt;
&lt;td&gt;Testes e instalações pequenas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recommended (&lt;code&gt;techdocs.builder: external&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Um pipeline de CI, a cada mudança, publicando em um armazenamento&lt;/td&gt;
&lt;td&gt;Produção&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Na estratégia recomendada, o CI roda a CLI &lt;code&gt;techdocs-cli generate&lt;/code&gt; e &lt;code&gt;techdocs-cli publish&lt;/code&gt;, enviando o site gerado para um armazenamento de objetos (AWS S3, Google Cloud Storage, Azure Blob Storage ou OpenStack Swift). O Backstage apenas lê dali. Isso tira a carga de build do backend e permite escalar a leitura de forma independente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefícios e cuidados
&lt;/h3&gt;

&lt;p&gt;O resultado é uma documentação com busca integrada ao portal, navegação lateral e a mesma autenticação do restante da plataforma. O cuidado é cultural: o plugin entrega a infraestrutura, mas a qualidade do conteúdo continua dependendo de cada time. Um bom começo é incluir no template um &lt;code&gt;docs/&lt;/code&gt; mínimo, com seções para visão geral, arquitetura e runbook de operação.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plugins e ecossistema
&lt;/h2&gt;

&lt;p&gt;Tudo no Backstage é plugin, inclusive o Catalog, o Scaffolder e o TechDocs. Essa é a decisão de design que o torna extensível: o portal é uma casca que carrega plugins, e cada plugin traz sua interface, sua lógica de servidor ou os dois.&lt;/p&gt;

&lt;h3&gt;
  
  
  Como um plugin é composto
&lt;/h3&gt;

&lt;p&gt;Um plugin típico tem duas metades. O &lt;strong&gt;plugin de frontend&lt;/strong&gt; é um pacote React que registra páginas, abas e cartões na interface. O &lt;strong&gt;plugin de backend&lt;/strong&gt; é um serviço Node.js que expõe endpoints, acessa o banco, chama APIs externas e guarda credenciais, para que o navegador nunca as veja. Um plugin de frontend costuma consultar o seu backend, e esse backend consulta a ferramenta externa, por exemplo o GitHub, o Kubernetes ou o PagerDuty.&lt;/p&gt;

&lt;p&gt;O backend atual é montado com o &lt;strong&gt;novo sistema de backend&lt;/strong&gt;, em que o plugin é registrado com &lt;code&gt;backend.add(...)&lt;/code&gt; e dependências como logger, banco, cache e configuração são injetadas como serviços. O Backstage também evolui um novo sistema de frontend baseado em extensões, mas parte dos plugins da comunidade ainda usa o modelo anterior, então vale conferir a compatibilidade antes de adotar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Plugins populares
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Categoria&lt;/th&gt;
&lt;th&gt;Exemplos&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Código e CI/CD&lt;/td&gt;
&lt;td&gt;GitHub Actions, GitLab, Jenkins, CircleCI, Argo CD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infraestrutura&lt;/td&gt;
&lt;td&gt;Kubernetes, Terraform, AWS, Azure, Google Cloud&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Observabilidade e incidentes&lt;/td&gt;
&lt;td&gt;Grafana, Datadog, Prometheus, PagerDuty, Sentry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Segurança&lt;/td&gt;
&lt;td&gt;SonarQube, Snyk, relatórios de vulnerabilidades&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qualidade e maturidade&lt;/td&gt;
&lt;td&gt;Tech Insights, scorecards&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custos&lt;/td&gt;
&lt;td&gt;Cost Insights&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Busca&lt;/td&gt;
&lt;td&gt;Pesquisa unificada sobre catálogo e docs (Lunr, PostgreSQL ou Elasticsearch)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;O diretório de plugins no site do projeto lista centenas de opções, mantidas pelo Spotify, por fornecedores e pela comunidade. A qualidade varia: antes de depender de um plugin, verifique a data do último commit, a compatibilidade com a versão do Backstage em uso e se ele já migrou para o novo sistema de backend.&lt;/p&gt;

&lt;h3&gt;
  
  
  Criando o seu
&lt;/h3&gt;

&lt;p&gt;O CLI do Backstage gera o esqueleto de um plugin com &lt;code&gt;yarn new&lt;/code&gt;. O caminho comum em empresas é escrever plugins internos para exibir dados proprietários, como o status de uma plataforma interna ou o painel de custos do time, e ligar a página à entidade do catálogo por uma annotation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Autenticação e permissões
&lt;/h2&gt;

&lt;p&gt;O Backstage separa duas perguntas: quem é você (autenticação) e o que você pode fazer (autorização). A primeira vem pronta com vários provedores; a segunda é um framework que você configura.&lt;/p&gt;

&lt;h3&gt;
  
  
  Autenticação
&lt;/h3&gt;

&lt;p&gt;O plugin de autenticação oferece provedores como GitHub, GitLab, Google, Microsoft Entra ID, Okta, Auth0, AWS ALB, OneLogin, além de OIDC e SAML genéricos. Ao concluir o login, um &lt;strong&gt;sign-in resolver&lt;/strong&gt; associa a identidade externa a uma entidade &lt;code&gt;User&lt;/code&gt; do catálogo, e é essa ligação que dá ao usuário seus grupos e, portanto, seus donos e permissões. Um resolver mal escrito, que associe a pessoa errada, é uma das falhas de configuração mais sérias, e vale revisá-lo com cuidado.&lt;/p&gt;

&lt;p&gt;Por padrão, um projeto novo permite acesso como convidado, útil só em desenvolvimento. Em produção, desative esse acesso e configure o provedor corporativo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Autorização com o Permission Framework
&lt;/h3&gt;

&lt;p&gt;Sem configuração extra, qualquer usuário autenticado pode fazer quase tudo. O framework de permissões muda isso: os plugins declaram &lt;strong&gt;permissões&lt;/strong&gt; (ler uma entidade, executar um template, remover do catálogo), e uma &lt;strong&gt;política&lt;/strong&gt; em código decide, para cada requisição, se o usuário recebe &lt;code&gt;ALLOW&lt;/code&gt;, &lt;code&gt;DENY&lt;/code&gt; ou uma decisão condicional.&lt;/p&gt;

&lt;p&gt;Um exemplo comum é restringir quem pode apagar entidades ao time de plataforma, ou limitar que templates aparecem para cada time. As condicionais permitem regras como "o usuário só edita entidades de que é dono", avaliadas no banco com eficiência.&lt;/p&gt;

&lt;h3&gt;
  
  
  Segurança do portal como um todo
&lt;/h3&gt;

&lt;p&gt;O Backstage guarda tokens de integração (GitHub, nuvem, Kubernetes) e enxerga metadados sensíveis de toda a empresa, o que o torna um alvo valioso. Mantenha o portal atrás do SSO corporativo, guarde credenciais em um gerenciador de segredos, use permissões mínimas nos tokens de integração e acompanhe as atualizações de segurança do projeto, que lança versões com frequência mensal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalação e deploy
&lt;/h2&gt;

&lt;p&gt;Uma instância do Backstage é um projeto seu, gerado por um CLI, e não um pacote que você instala. Você cria o app, o versiona em um repositório próprio e o atualiza para acompanhar as versões do projeto.&lt;/p&gt;

&lt;h3&gt;
  
  
  Criando e rodando localmente
&lt;/h3&gt;

&lt;p&gt;O pré-requisito é uma versão LTS do Node.js e o Yarn. O comando abaixo gera a estrutura do monorepo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @backstage/create-app@latest
&lt;span class="nb"&gt;cd &lt;/span&gt;meu-portal
yarn start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O projeto gerado tem dois pacotes principais: &lt;code&gt;packages/app&lt;/code&gt; (frontend) e &lt;code&gt;packages/backend&lt;/code&gt; (backend). No modo de desenvolvimento, o frontend responde em &lt;code&gt;localhost:3000&lt;/code&gt; e o backend em &lt;code&gt;localhost:7007&lt;/code&gt;. A configuração fica em &lt;code&gt;app-config.yaml&lt;/code&gt;, com variantes como &lt;code&gt;app-config.production.yaml&lt;/code&gt; e &lt;code&gt;app-config.local.yaml&lt;/code&gt; sobrepondo valores por ambiente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Banco de dados
&lt;/h3&gt;

&lt;p&gt;O desenvolvimento usa SQLite em memória, e produção exige &lt;strong&gt;PostgreSQL&lt;/strong&gt;. Cada plugin de backend usa seu próprio banco lógico, e o Backstage cria o que for preciso. Em nuvem, um banco gerenciado (como Amazon RDS ou Aurora PostgreSQL) resolve backup, alta disponibilidade e atualização.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# app-config.production.yaml&lt;/span&gt;
&lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://backstage.minha-empresa.com&lt;/span&gt;
&lt;span class="na"&gt;backend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://backstage.minha-empresa.com&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pg&lt;/span&gt;
    &lt;span class="na"&gt;connection&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${POSTGRES_HOST}&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${POSTGRES_PORT}&lt;/span&gt;
      &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${POSTGRES_USER}&lt;/span&gt;
      &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${POSTGRES_PASSWORD}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Empacotando e publicando
&lt;/h3&gt;

&lt;p&gt;O caminho usual é gerar uma imagem de contêiner. O projeto traz um Dockerfile de exemplo em &lt;code&gt;packages/backend&lt;/code&gt;, e o build típico compila o TypeScript, empacota o backend e embute o frontend estático para ser servido por ele.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--immutable&lt;/span&gt;
yarn tsc
yarn build:backend
docker build &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; packages/backend/Dockerfile &lt;span class="nt"&gt;--tag&lt;/span&gt; meu-portal:1.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A imagem roda em qualquer orquestrador: Kubernetes (com Helm chart, que a comunidade mantém), Amazon ECS ou EKS, Cloud Run e similares. Em um deploy típico, um balanceador termina o TLS, o serviço roda em duas ou mais réplicas, o PostgreSQL é gerenciado, os segredos vêm de um gerenciador (e não do &lt;code&gt;app-config.yaml&lt;/code&gt;) e os arquivos do TechDocs ficam em um bucket de objetos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Atualizações
&lt;/h3&gt;

&lt;p&gt;O Backstage publica uma versão a cada mês, e o comando &lt;code&gt;yarn backstage-cli versions:bump&lt;/code&gt; atualiza todos os pacotes &lt;code&gt;@backstage/*&lt;/code&gt; de uma vez. Atualizar com regularidade custa menos que acumular meses de mudanças, e o site do projeto traz um &lt;em&gt;upgrade helper&lt;/em&gt; que mostra o diff entre duas versões do projeto gerado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adoção na prática
&lt;/h2&gt;

&lt;p&gt;O maior risco do Backstage não é técnico: é tratá-lo como um projeto de instalação em vez de um produto interno. O código é aberto e gratuito, mas o custo real está em manter, evoluir e convencer pessoas a usá-lo.&lt;/p&gt;

&lt;h3&gt;
  
  
  O custo de ser dono do portal
&lt;/h3&gt;

&lt;p&gt;Um portal útil costuma exigir uma equipe dedicada, com conhecimento de TypeScript, React e Node.js. Cabe a ela atualizar versões todo mês, manter plugins internos, resolver quebras de compatibilidade e atender os times usuários. Organizações pequenas, sem um time de plataforma, costumam subestimar esse esforço.&lt;/p&gt;

&lt;h3&gt;
  
  
  Armadilhas frequentes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Catálogo desatualizado.&lt;/strong&gt; Um catálogo com donos errados e serviços mortos perde a confiança em semanas. Automatize a descoberta, valide os descritores no CI e exija um dono para cada entidade.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Começar largo demais.&lt;/strong&gt; Instalar dezenas de plugins antes de resolver uma dor concreta gera um portal cheio e sem uso. Comece com o catálogo e um template para o caso mais frequente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ausência de incentivo.&lt;/strong&gt; Se a documentação e os templates do portal não são o caminho mais fácil, as pessoas continuam usando wikis e planilhas. O portal precisa economizar tempo desde o primeiro uso.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Template sem manutenção.&lt;/strong&gt; Serviços criados a partir de um template não recebem suas atualizações; planeje como propagar correções (por exemplo, com ferramentas de atualização automática de dependências e pipelines reutilizáveis).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confundir portal com plataforma.&lt;/strong&gt; O Backstage é a interface. As capacidades por trás dele, como pipelines, ambientes e observabilidade, ainda precisam existir.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Como medir o sucesso
&lt;/h3&gt;

&lt;p&gt;Indicadores úteis incluem a porcentagem de serviços no catálogo com dono definido, o tempo para criar um serviço novo e colocá-lo em produção, o uso ativo semanal do portal e a satisfação dos desenvolvedores em pesquisas curtas. Esses números sustentam a continuidade do investimento.&lt;/p&gt;

&lt;h3&gt;
  
  
  Alternativas e opções gerenciadas
&lt;/h3&gt;

&lt;p&gt;Quem quer o resultado sem montar o portal pode olhar soluções que oferecem o Backstage hospedado ou alternativas de mercado. As principais opções são:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Opção&lt;/th&gt;
&lt;th&gt;Perfil&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Red Hat Developer Hub&lt;/td&gt;
&lt;td&gt;Distribuição corporativa baseada no Backstage, com suporte&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Roadie&lt;/td&gt;
&lt;td&gt;Backstage gerenciado como serviço&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Port, Cortex, OpsLevel&lt;/td&gt;
&lt;td&gt;Portais de mercado (não baseados em Backstage), com configuração mais guiada e menos código&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A escolha entre montar ou comprar depende de equipe disponível, necessidade de customização e orçamento. Verifique recursos e preços atuais direto com cada fornecedor, pois mudam com frequência.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;O Backstage entrega um portal de desenvolvedores montado sobre três ideias simples: um catálogo alimentado pelo código, templates que codificam os caminhos recomendados e documentação que mora junto do código. O resto é plugin. Sua força é a extensibilidade e o respaldo da CNCF; seu custo é a necessidade de tratá-lo como um produto interno, com equipe, roadmap e métricas.&lt;/p&gt;

&lt;p&gt;Um caminho prático para começar:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Gere um app com &lt;code&gt;npx @backstage/create-app&lt;/code&gt; e rode localmente.&lt;/li&gt;
&lt;li&gt;Registre dois ou três serviços reais com &lt;code&gt;catalog-info.yaml&lt;/code&gt; e conecte o provider do seu repositório de código.&lt;/li&gt;
&lt;li&gt;Crie um template para o tipo de serviço mais comum na empresa.&lt;/li&gt;
&lt;li&gt;Ative o TechDocs com build externo em um bucket de objetos.&lt;/li&gt;
&lt;li&gt;Troque o acesso de convidado pelo SSO corporativo e defina uma política de permissões básica.&lt;/li&gt;
&lt;li&gt;Meça o uso e expanda os plugins só onde houver dor concreta.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Referências
&lt;/h3&gt;

&lt;p&gt;Comandos, nomes de pacotes e recursos mudam entre versões; confirme sempre na documentação oficial.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://backstage.io/docs/overview/what-is-backstage" rel="noopener noreferrer"&gt;Site e documentação do Backstage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/backstage/backstage" rel="noopener noreferrer"&gt;Repositório do Backstage no GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cncf.io/projects/backstage/" rel="noopener noreferrer"&gt;Backstage na CNCF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://backstage.io/docs/features/software-catalog/system-model" rel="noopener noreferrer"&gt;Modelo de entidades do catálogo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>devops</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Docker Scout e Trivy segurança de imagens de contêiner na prática</title>
      <dc:creator>Kauê Matos</dc:creator>
      <pubDate>Wed, 07 Oct 2026 22:49:56 +0000</pubDate>
      <link>https://dev.to/ikauedev/docker-scout-e-trivy-seguranca-de-imagens-de-conteiner-na-pratica-3f7f</link>
      <guid>https://dev.to/ikauedev/docker-scout-e-trivy-seguranca-de-imagens-de-conteiner-na-pratica-3f7f</guid>
      <description>&lt;p&gt;Trivy e Docker Scout resolvem o mesmo problema central: descobrir, antes da produção, quais vulnerabilidades, licenças e dependências estão dentro das suas imagens de contêiner. Eles chegam a esse objetivo por caminhos diferentes, e entender essa diferença define qual usar, ou se usar os dois.&lt;/p&gt;

&lt;p&gt;Uma imagem Docker raramente contém apenas o seu código. Ela carrega um sistema operacional base, bibliotecas do sistema, o runtime da linguagem (JRE, Node.js, Python) e dezenas ou centenas de dependências transitivas. Cada camada é uma superfície de ataque herdada, e a maior parte dessas vulnerabilidades não está no código que você escreveu.&lt;/p&gt;

&lt;p&gt;Este artigo explica como cada ferramenta funciona, mostra os comandos do dia a dia, compara os dois lado a lado e apresenta um pipeline de CI/CD com GitHub Actions que aplica ambos. Os exemplos usam Java/Spring Boot e Node.js apenas como cenário; os comandos valem para qualquer stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conceitos fundamentais
&lt;/h2&gt;

&lt;p&gt;Sete conceitos aparecem em toda conversa sobre scan de imagens, e confundi-los é a origem da maioria dos relatórios mal interpretados.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Conceito&lt;/th&gt;
&lt;th&gt;O que é&lt;/th&gt;
&lt;th&gt;Por que importa no scan&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CVE&lt;/td&gt;
&lt;td&gt;Identificador público de uma vulnerabilidade (ex.: CVE-2024-XXXX)&lt;/td&gt;
&lt;td&gt;É a unidade que os scanners reportam&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CVSS&lt;/td&gt;
&lt;td&gt;Nota de severidade de 0 a 10 (Low, Medium, High, Critical)&lt;/td&gt;
&lt;td&gt;Base para filtros como &lt;code&gt;--severity HIGH,CRITICAL&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EPSS&lt;/td&gt;
&lt;td&gt;Probabilidade estimada de exploração real nos próximos 30 dias&lt;/td&gt;
&lt;td&gt;Ajuda a priorizar: CVSS alto com EPSS baixo pode esperar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KEV&lt;/td&gt;
&lt;td&gt;Catálogo da CISA de vulnerabilidades já exploradas ativamente&lt;/td&gt;
&lt;td&gt;Tratar como prioridade máxima, independentemente do CVSS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SBOM&lt;/td&gt;
&lt;td&gt;Inventário de componentes da imagem (formatos SPDX e CycloneDX)&lt;/td&gt;
&lt;td&gt;Permite reavaliar vulnerabilidades sem reescanear a imagem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VEX&lt;/td&gt;
&lt;td&gt;Declaração de que uma CVE existe no componente, mas não é explorável no seu contexto&lt;/td&gt;
&lt;td&gt;Forma auditável de suprimir falsos positivos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Provenance&lt;/td&gt;
&lt;td&gt;Atestado de como, onde e por quem a imagem foi construída (SLSA)&lt;/td&gt;
&lt;td&gt;Prova a origem da imagem na cadeia de suprimentos&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Duas ideias completam o quadro. A &lt;strong&gt;base image&lt;/strong&gt; é a imagem do &lt;code&gt;FROM&lt;/code&gt;: ela costuma responder pela maior parte das CVEs de um relatório, e trocá-la tende a render mais que corrigir dependências uma a uma. Já a &lt;strong&gt;SCA&lt;/strong&gt; (Software Composition Analysis) é a técnica por trás dos dois scanners: identificar pacotes instalados (via &lt;code&gt;dpkg&lt;/code&gt;, &lt;code&gt;apk&lt;/code&gt;, &lt;code&gt;rpm&lt;/code&gt;) e dependências de aplicação (&lt;code&gt;pom.xml&lt;/code&gt;, &lt;code&gt;package-lock.json&lt;/code&gt;, &lt;code&gt;go.mod&lt;/code&gt;) e cruzá-los com bases de vulnerabilidades.&lt;/p&gt;

&lt;p&gt;Um ponto sutil: um scanner só encontra o que consegue inventariar. Binários copiados à mão ou compilados estaticamente sem metadados passam despercebidos, o que justifica gerar SBOM no build e não apenas escanear a imagem pronta.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trivy em detalhe
&lt;/h2&gt;

&lt;p&gt;O Trivy é um scanner de segurança open source (licença Apache 2.0), mantido pela Aqua Security, distribuído como um único binário Go. Seu diferencial é a amplitude: o mesmo comando cobre imagens, sistemas de arquivos, repositórios Git, manifestos Kubernetes e arquivos de infraestrutura como código.&lt;/p&gt;

&lt;h3&gt;
  
  
  Como ele funciona
&lt;/h3&gt;

&lt;p&gt;O Trivy extrai o conteúdo da imagem, identifica os pacotes do SO e das linguagens e consulta um banco local de vulnerabilidades (o &lt;code&gt;trivy-db&lt;/code&gt;), baixado do registry no primeiro uso e atualizado periodicamente. Como a comparação acontece na sua máquina ou no runner de CI, ele funciona sem enviar a imagem para nenhum serviço externo, e pode operar offline com o banco em cache.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tipos de scan
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scanner&lt;/th&gt;
&lt;th&gt;O que detecta&lt;/th&gt;
&lt;th&gt;Flag&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Vulnerabilidades&lt;/td&gt;
&lt;td&gt;CVEs em pacotes do SO e de linguagens&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--scanners vuln&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Misconfiguration&lt;/td&gt;
&lt;td&gt;Erros em Dockerfile, Terraform, Kubernetes, Helm, CloudFormation&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--scanners misconfig&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secrets&lt;/td&gt;
&lt;td&gt;Chaves de API, tokens e senhas embutidos&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--scanners secret&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Licenças&lt;/td&gt;
&lt;td&gt;Licenças de dependências (ex.: GPL, AGPL)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--scanners license&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Alvos
&lt;/h3&gt;

&lt;p&gt;O primeiro argumento define o alvo: &lt;code&gt;image&lt;/code&gt;, &lt;code&gt;fs&lt;/code&gt; (diretório local), &lt;code&gt;repo&lt;/code&gt; (repositório remoto), &lt;code&gt;rootfs&lt;/code&gt;, &lt;code&gt;config&lt;/code&gt; (IaC), &lt;code&gt;k8s&lt;/code&gt; (cluster) e &lt;code&gt;sbom&lt;/code&gt; (reescanear um SBOM existente).&lt;/p&gt;

&lt;h3&gt;
  
  
  Comandos do dia a dia
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Scan básico de uma imagem&lt;/span&gt;
trivy image minha-app:1.0.0

&lt;span class="c"&gt;# Somente HIGH e CRITICAL, ignorando CVEs sem correção disponível&lt;/span&gt;
trivy image &lt;span class="nt"&gt;--severity&lt;/span&gt; HIGH,CRITICAL &lt;span class="nt"&gt;--ignore-unfixed&lt;/span&gt; minha-app:1.0.0

&lt;span class="c"&gt;# Falhar o comando (exit code 1) quando houver achados: ideal para CI&lt;/span&gt;
trivy image &lt;span class="nt"&gt;--exit-code&lt;/span&gt; 1 &lt;span class="nt"&gt;--severity&lt;/span&gt; CRITICAL minha-app:1.0.0

&lt;span class="c"&gt;# Saída em JSON, SARIF ou template próprio&lt;/span&gt;
trivy image &lt;span class="nt"&gt;--format&lt;/span&gt; json &lt;span class="nt"&gt;--output&lt;/span&gt; relatorio.json minha-app:1.0.0
trivy image &lt;span class="nt"&gt;--format&lt;/span&gt; sarif &lt;span class="nt"&gt;--output&lt;/span&gt; trivy.sarif minha-app:1.0.0

&lt;span class="c"&gt;# Gerar SBOM em CycloneDX e reescanear depois, sem a imagem&lt;/span&gt;
trivy image &lt;span class="nt"&gt;--format&lt;/span&gt; cyclonedx &lt;span class="nt"&gt;--output&lt;/span&gt; sbom.cdx.json minha-app:1.0.0
trivy sbom sbom.cdx.json

&lt;span class="c"&gt;# Escanear o código-fonte e dependências do projeto&lt;/span&gt;
trivy fs &lt;span class="nt"&gt;--scanners&lt;/span&gt; vuln,secret,misconfig &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# Validar IaC (Terraform, Kubernetes, Dockerfile)&lt;/span&gt;
trivy config ./infra

&lt;span class="c"&gt;# Resumo de um cluster Kubernetes&lt;/span&gt;
trivy k8s &lt;span class="nt"&gt;--report&lt;/span&gt; summary cluster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Suprimindo achados com critério
&lt;/h3&gt;

&lt;p&gt;O arquivo &lt;code&gt;.trivyignore&lt;/code&gt; lista CVEs a ignorar, e as versões recentes aceitam data de expiração e comentário por entrada, o que evita exceções eternas. Para um registro mais formal, o Trivy também consome documentos &lt;strong&gt;VEX&lt;/strong&gt; (OpenVEX, CSAF, CycloneDX VEX) via &lt;code&gt;--vex&lt;/code&gt;. Para configuração persistente, use um &lt;code&gt;trivy.yaml&lt;/code&gt; em vez de repetir flags.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# .trivyignore
# Não explorável: a função vulnerável não é chamada pela aplicação
CVE-2024-00000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Banco de dados e desempenho em CI
&lt;/h3&gt;

&lt;p&gt;O download do banco a cada execução é o principal gargalo e a causa mais comum de falhas por limite de requisições em runners compartilhados. Três práticas ajudam: cachear o diretório de cache do Trivy entre execuções, usar &lt;code&gt;--skip-db-update&lt;/code&gt; quando o banco já estiver presente e espelhar o banco em um registry interno, apontando com &lt;code&gt;--db-repository&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trivy Operator
&lt;/h3&gt;

&lt;p&gt;No Kubernetes, o &lt;strong&gt;Trivy Operator&lt;/strong&gt; roda dentro do cluster e gera relatórios como recursos customizados (&lt;code&gt;VulnerabilityReport&lt;/code&gt;, &lt;code&gt;ConfigAuditReport&lt;/code&gt;, &lt;code&gt;ExposedSecretReport&lt;/code&gt;). Isso cobre o que o scan de CI não vê: imagens que ficaram vulneráveis depois do deploy, porque uma CVE nova foi publicada.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker Scout em detalhe
&lt;/h2&gt;

&lt;p&gt;O Docker Scout é a solução de análise da cadeia de suprimentos integrada ao ecossistema Docker: ele aparece no Docker Desktop, no Docker Hub, na CLI (&lt;code&gt;docker scout&lt;/code&gt;) e em uma GitHub Action oficial. Em vez de apenas listar CVEs, ele conecta vulnerabilidades à imagem base, às políticas da organização e à evolução da imagem no tempo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Como ele funciona
&lt;/h3&gt;

&lt;p&gt;O Scout gera um índice de componentes (um SBOM) da imagem e o cruza com um banco de vulnerabilidades próprio, que agrega várias fontes de advisories e é atualizado continuamente. Quando a imagem está em um repositório com o Scout habilitado, a análise é guardada e reavaliada conforme novas CVEs surgem, sem exigir um novo scan manual. Para imagens locais, o mesmo motor roda sob demanda pela CLI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comandos do dia a dia
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Visão geral rápida: vulnerabilidades e base image&lt;/span&gt;
docker scout quickview minha-app:1.0.0

&lt;span class="c"&gt;# Lista detalhada de CVEs, filtrando por severidade e correção disponível&lt;/span&gt;
docker scout cves &lt;span class="nt"&gt;--only-severity&lt;/span&gt; critical,high &lt;span class="nt"&gt;--only-fixed&lt;/span&gt; minha-app:1.0.0

&lt;span class="c"&gt;# Escanear o diretório local, sem construir a imagem&lt;/span&gt;
docker scout cves &lt;span class="nt"&gt;--type&lt;/span&gt; fs &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# Recomendações de atualização da base image&lt;/span&gt;
docker scout recommendations minha-app:1.0.0

&lt;span class="c"&gt;# Comparar duas versões e ver apenas o que mudou&lt;/span&gt;
docker scout compare &lt;span class="nt"&gt;--to&lt;/span&gt; minha-app:1.0.0 minha-app:1.1.0

&lt;span class="c"&gt;# Exportar SBOM&lt;/span&gt;
docker scout sbom &lt;span class="nt"&gt;--format&lt;/span&gt; spdx minha-app:1.0.0

&lt;span class="c"&gt;# Avaliar a imagem contra as políticas da organização&lt;/span&gt;
docker scout policy minha-app:1.0.0 &lt;span class="nt"&gt;--org&lt;/span&gt; minha-org

&lt;span class="c"&gt;# Saída SARIF e exit code para CI&lt;/span&gt;
docker scout cves &lt;span class="nt"&gt;--format&lt;/span&gt; sarif &lt;span class="nt"&gt;--output&lt;/span&gt; scout.sarif &lt;span class="nt"&gt;--exit-code&lt;/span&gt; &lt;span class="nt"&gt;--only-severity&lt;/span&gt; critical,high minha-app:1.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Recomendações de base image
&lt;/h3&gt;

&lt;p&gt;Esse é o recurso mais característico. O &lt;code&gt;docker scout recommendations&lt;/code&gt; compara a base atual com alternativas e propõe dois caminhos: &lt;strong&gt;atualizar&lt;/strong&gt; para uma versão mais nova da mesma tag (menos CVEs com mudança mínima) ou &lt;strong&gt;trocar&lt;/strong&gt; por outra variante (por exemplo, de uma imagem completa para uma &lt;code&gt;slim&lt;/code&gt;). O relatório mostra quantas vulnerabilidades cada opção elimina, o que transforma a conversa sobre trocar de base image de opinião em número.&lt;/p&gt;

&lt;h3&gt;
  
  
  Políticas
&lt;/h3&gt;

&lt;p&gt;O Scout avalia a imagem contra políticas e mostra o resultado como conforme ou não conforme. As políticas padrão cobrem, entre outras verificações, vulnerabilidades críticas e altas com correção disponível, vulnerabilidades de alto perfil, bases desatualizadas, licenças copyleft, presença de atestados de cadeia de suprimentos e usuário não root por padrão. Cada política pode ser ajustada ou criada sob medida na organização.&lt;/p&gt;

&lt;h3&gt;
  
  
  SBOM e provenance
&lt;/h3&gt;

&lt;p&gt;O Scout lê os atestados que o BuildKit anexa à imagem. Para alimentá-lo com dados melhores, gere SBOM e provenance no build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker buildx build &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sbom&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--provenance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;max &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tag&lt;/span&gt; minha-org/minha-app:1.0.0 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--push&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com isso, a análise passa a usar o SBOM gerado no próprio build, mais fiel ao conteúdo real que a inferência feita depois, e a política de atestados fica satisfeita.&lt;/p&gt;

&lt;h3&gt;
  
  
  Limitações a considerar
&lt;/h3&gt;

&lt;p&gt;O Scout é focado em imagens e dependências: ele não analisa IaC (Terraform, manifestos Kubernetes) nem procura secrets embutidos. Os recursos de monitoramento contínuo, políticas e integração com Docker Hub dependem do plano da organização, então confira o plano vigente antes de basear um processo nele.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker Scout vs Trivy
&lt;/h2&gt;

&lt;p&gt;O Trivy é a escolha por amplitude e independência de plataforma; o Scout é a escolha por integração com o fluxo Docker e por orientação de ação (base image e políticas). A tabela resume as diferenças.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Critério&lt;/th&gt;
&lt;th&gt;Trivy&lt;/th&gt;
&lt;th&gt;Docker Scout&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Modelo&lt;/td&gt;
&lt;td&gt;Open source (Apache 2.0), binário único&lt;/td&gt;
&lt;td&gt;Recurso do ecossistema Docker, com planos por organização&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Escopo&lt;/td&gt;
&lt;td&gt;Vulnerabilidades, misconfiguration, secrets, licenças, IaC, Kubernetes&lt;/td&gt;
&lt;td&gt;Vulnerabilidades, licenças, SBOM, políticas, recomendações de base image&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alvos&lt;/td&gt;
&lt;td&gt;Imagem, filesystem, repositório, cluster, SBOM, IaC&lt;/td&gt;
&lt;td&gt;Imagem e diretório local&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Execução&lt;/td&gt;
&lt;td&gt;Local ou em CI, com possibilidade de operar offline com banco em cache&lt;/td&gt;
&lt;td&gt;CLI local, Docker Desktop, Docker Hub e GitHub Action&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recomendação de base image&lt;/td&gt;
&lt;td&gt;Não nativa&lt;/td&gt;
&lt;td&gt;Sim, com comparação de opções&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Políticas&lt;/td&gt;
&lt;td&gt;Via flags, exit code e Rego para misconfiguration&lt;/td&gt;
&lt;td&gt;Políticas nativas com status de conformidade&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monitoramento contínuo&lt;/td&gt;
&lt;td&gt;Trivy Operator no Kubernetes ou reexecução agendada&lt;/td&gt;
&lt;td&gt;Reavaliação automática em repositórios habilitados&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Formatos de saída&lt;/td&gt;
&lt;td&gt;Table, JSON, SARIF, CycloneDX, SPDX, template&lt;/td&gt;
&lt;td&gt;Texto, SARIF, SPDX, CycloneDX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Registry&lt;/td&gt;
&lt;td&gt;Qualquer um&lt;/td&gt;
&lt;td&gt;Melhor experiência com Docker Hub; funciona com outros registries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ponto forte&lt;/td&gt;
&lt;td&gt;Cobertura ampla e neutra&lt;/td&gt;
&lt;td&gt;Orientação de correção e integração com Docker&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Quando usar cada um
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trivy&lt;/strong&gt; quando o pipeline envolve IaC, Kubernetes ou detecção de secrets, quando é preciso rodar em ambiente isolado ou quando se quer uma ferramenta neutra em relação a registry e nuvem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker Scout&lt;/strong&gt; quando a equipe já vive no Docker Desktop e no Docker Hub, quando o objetivo é decidir qual base image adotar ou quando políticas por organização e comparação entre versões são prioridade.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Os dois&lt;/strong&gt; quando se quer cobertura ampla no CI (Trivy) e orientação de remediação para o time de desenvolvimento (Scout). Resultados podem divergir, porque cada ferramenta usa suas próprias fontes de dados e regras de correspondência. Divergência não indica erro de um dos lados: investigue o pacote e a fonte do advisory antes de decidir.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Integração em CI/CD com GitHub Actions
&lt;/h2&gt;

&lt;p&gt;O padrão mais útil é construir a imagem uma vez, escaneá-la com os dois, publicar o relatório no GitHub e só então fazer o push. O pipeline abaixo bloqueia o merge quando há vulnerabilidade crítica com correção disponível e envia os resultados para a aba Security do repositório.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build-and-scan&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;
  &lt;span class="na"&gt;security-events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;   &lt;span class="c1"&gt;# necessário para enviar SARIF&lt;/span&gt;
  &lt;span class="na"&gt;pull-requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;     &lt;span class="c1"&gt;# comentário do Scout no PR&lt;/span&gt;

&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;IMAGE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;minha-org/minha-app:${{ github.sha }}&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;scan&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@&amp;lt;commit-sha&amp;gt;&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/setup-buildx-action@&amp;lt;commit-sha&amp;gt;&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build (sem push)&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/build-push-action@&amp;lt;commit-sha&amp;gt;&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
          &lt;span class="na"&gt;load&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
          &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ env.IMAGE }}&lt;/span&gt;
          &lt;span class="na"&gt;sbom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
          &lt;span class="na"&gt;provenance&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mode=max&lt;/span&gt;

      &lt;span class="c1"&gt;# --- Trivy: cobertura ampla, falha o job em CRITICAL com correção ---&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Trivy (imagem)&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aquasecurity/trivy-action@&amp;lt;commit-sha&amp;gt;&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;image-ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ env.IMAGE }}&lt;/span&gt;
          &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sarif&lt;/span&gt;
          &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;trivy.sarif&lt;/span&gt;
          &lt;span class="na"&gt;severity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CRITICAL,HIGH&lt;/span&gt;
          &lt;span class="na"&gt;ignore-unfixed&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
          &lt;span class="na"&gt;exit-code&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;0'&lt;/span&gt;   &lt;span class="c1"&gt;# o SARIF sempre é gerado; o gate vem no próximo passo&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Trivy (gate)&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aquasecurity/trivy-action@&amp;lt;commit-sha&amp;gt;&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;image-ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ env.IMAGE }}&lt;/span&gt;
          &lt;span class="na"&gt;severity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CRITICAL&lt;/span&gt;
          &lt;span class="na"&gt;ignore-unfixed&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
          &lt;span class="na"&gt;exit-code&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1'&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Enviar SARIF do Trivy&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always()&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github/codeql-action/upload-sarif@&amp;lt;commit-sha&amp;gt;&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;sarif_file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;trivy.sarif&lt;/span&gt;
          &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;trivy&lt;/span&gt;

      &lt;span class="c1"&gt;# --- Docker Scout: orientação de correção e comparação com main ---&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Login no Docker Hub&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/login-action@&amp;lt;commit-sha&amp;gt;&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DOCKERHUB_USER }}&lt;/span&gt;
          &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DOCKERHUB_TOKEN }}&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Docker Scout&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/scout-action@&amp;lt;commit-sha&amp;gt;&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cves,recommendations&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ env.IMAGE }}&lt;/span&gt;
          &lt;span class="na"&gt;only-severities&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;critical,high&lt;/span&gt;
          &lt;span class="na"&gt;sarif-file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scout.sarif&lt;/span&gt;
          &lt;span class="na"&gt;write-comment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
          &lt;span class="na"&gt;github-token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Enviar SARIF do Scout&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always()&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github/codeql-action/upload-sarif@&amp;lt;commit-sha&amp;gt;&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;sarif_file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scout.sarif&lt;/span&gt;
          &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker-scout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pontos de atenção no pipeline
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fixe as actions por commit SHA&lt;/strong&gt;, como nos &lt;code&gt;&amp;lt;commit-sha&amp;gt;&lt;/code&gt; acima, em vez de tags móveis. Uma action de scanner roda com acesso ao seu runner e aos seus secrets, então ela própria é parte da cadeia de suprimentos que você quer proteger.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separe o relatório do gate.&lt;/strong&gt; Gerar o SARIF com &lt;code&gt;exit-code: 0&lt;/code&gt; e aplicar o bloqueio em um passo próprio garante que o relatório chegue ao GitHub mesmo quando o build falha.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escaneie antes do push.&lt;/strong&gt; Construir com &lt;code&gt;load: true&lt;/code&gt;, escanear e só depois publicar impede que uma imagem reprovada chegue ao registry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cacheie o banco do Trivy&lt;/strong&gt; com &lt;code&gt;actions/cache&lt;/code&gt; para evitar falhas por limite de requisições e reduzir o tempo do job.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reescaneie periodicamente.&lt;/strong&gt; Um workflow agendado (&lt;code&gt;schedule&lt;/code&gt;) sobre as imagens já publicadas detecta CVEs descobertas depois do deploy, que o scan no momento do build não pode ver.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Boas práticas e armadilhas comuns
&lt;/h2&gt;

&lt;p&gt;O scanner mostra o problema, mas quem reduz o risco é a imagem que você constrói. As práticas abaixo têm o maior retorno.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reduza a superfície antes de escanear
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use bases mínimas&lt;/strong&gt;: variantes &lt;code&gt;slim&lt;/code&gt;, &lt;code&gt;alpine&lt;/code&gt; ou distroless eliminam pacotes que você nunca usa e, com eles, as CVEs associadas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use multi-stage build&lt;/strong&gt;: compile em uma etapa e copie só o artefato final, deixando compiladores e ferramentas de build fora da imagem de produção.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fixe a base por digest&lt;/strong&gt; (&lt;code&gt;FROM imagem@sha256:...&lt;/code&gt;) e atualize de forma deliberada, para que o resultado do scan seja reprodutível.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rode como usuário não root&lt;/strong&gt; com &lt;code&gt;USER&lt;/code&gt; no Dockerfile.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reconstrua com frequência&lt;/strong&gt;: uma imagem sem mudança de código acumula CVEs novas com o tempo.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Defina critérios de bloqueio realistas
&lt;/h3&gt;

&lt;p&gt;Bloquear qualquer CVE de qualquer severidade paralisa o time e leva à desativação do scan. Um ponto de partida comum é bloquear &lt;strong&gt;CRITICAL e HIGH com correção disponível&lt;/strong&gt; e apenas reportar o restante. O filtro &lt;code&gt;--ignore-unfixed&lt;/code&gt; (Trivy) e &lt;code&gt;--only-fixed&lt;/code&gt; (Scout) existem para isso, mas lembre que CVEs sem correção continuam sendo risco: elas devem ser acompanhadas, não esquecidas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trate exceções como dívida com prazo
&lt;/h3&gt;

&lt;p&gt;Toda supressão deve ter justificativa e data de revisão. Prefira VEX ou entradas com expiração a um &lt;code&gt;.trivyignore&lt;/code&gt; que só cresce. Uma CVE suprimida sem registro de por quê é indistinguível de uma CVE esquecida.&lt;/p&gt;

&lt;h3&gt;
  
  
  Armadilhas frequentes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Achar que zero CVEs significa seguro.&lt;/strong&gt; O scan cobre vulnerabilidades conhecidas em componentes inventariados; não detecta falhas de lógica na sua aplicação nem configuração insegura em runtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escanear só no build.&lt;/strong&gt; O risco muda depois do deploy; combine o scan de CI com reescaneamento agendado, Trivy Operator ou o monitoramento do Scout.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Priorizar só por CVSS.&lt;/strong&gt; Combine severidade com correção disponível, presença no catálogo KEV e EPSS; uma CVE crítica em um pacote que a aplicação não carrega pode esperar, uma média explorada ativamente não.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignorar divergências entre ferramentas.&lt;/strong&gt; Se Trivy e Scout discordam, verifique a fonte do advisory e a versão do pacote antes de concluir qual está certo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deixar o banco desatualizado.&lt;/strong&gt; Um scan com banco antigo gera falsa sensação de segurança, especialmente em ambientes isolados com &lt;code&gt;--skip-db-update&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Trivy e Docker Scout se complementam mais do que competem. O Trivy entrega cobertura ampla, neutra e executável em qualquer ambiente, incluindo IaC, secrets e Kubernetes. O Docker Scout entrega contexto: qual base image trocar, o que mudou entre duas versões e se a imagem cumpre as políticas da organização.&lt;/p&gt;

&lt;p&gt;Um caminho prático para começar:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Rode &lt;code&gt;trivy image&lt;/code&gt; e &lt;code&gt;docker scout quickview&lt;/code&gt; na imagem de produção atual e compare os resultados.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;docker scout recommendations&lt;/code&gt; para escolher uma base image menor ou mais atual.&lt;/li&gt;
&lt;li&gt;Adicione o pipeline de GitHub Actions com bloqueio apenas para CRITICAL com correção disponível.&lt;/li&gt;
&lt;li&gt;Passe a gerar SBOM e provenance no build.&lt;/li&gt;
&lt;li&gt;Agende o reescaneamento das imagens publicadas e, em Kubernetes, avalie o Trivy Operator.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Referências
&lt;/h3&gt;

&lt;p&gt;Flags, nomes de inputs das actions e recursos dependem da versão e do plano; confirme sempre na documentação oficial antes de adotar um comando em produção.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://trivy.dev/latest/docs/" rel="noopener noreferrer"&gt;Documentação do Trivy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/scout/" rel="noopener noreferrer"&gt;Documentação do Docker Scout&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/aquasecurity/trivy" rel="noopener noreferrer"&gt;Repositório do Trivy no GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/docker/scout-action" rel="noopener noreferrer"&gt;docker/scout-action no GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>docker</category>
      <category>webdev</category>
      <category>programming</category>
      <category>devops</category>
    </item>
    <item>
      <title>Kyverno Policy as Code no Kubernetes</title>
      <dc:creator>Kauê Matos</dc:creator>
      <pubDate>Wed, 07 Oct 2026 02:51:01 +0000</pubDate>
      <link>https://dev.to/ikauedev/kyverno-policy-as-code-no-kubernetes-12l8</link>
      <guid>https://dev.to/ikauedev/kyverno-policy-as-code-no-kubernetes-12l8</guid>
      <description>&lt;p&gt;Kyverno (do grego "governar") é um motor de políticas nativo do Kubernetes, projeto da CNCF, que permite validar, alterar e gerar recursos do cluster usando apenas YAML, sem aprender uma linguagem nova.&lt;/p&gt;

&lt;p&gt;Em clusters compartilhados, qualquer pessoa com acesso ao &lt;code&gt;kubectl apply&lt;/code&gt; pode criar um Pod privilegiado, uma imagem sem tag ou um Service exposto sem querer. Revisão manual não escala, e documentação de boas práticas não impede ninguém de errar. O Kyverno resolve isso aplicando regras no momento em que o recurso chega à API do Kubernetes, antes de ele ser persistido no etcd.&lt;/p&gt;

&lt;p&gt;O diferencial frente a outras ferramentas é que as políticas são recursos Kubernetes comuns (&lt;code&gt;ClusterPolicy&lt;/code&gt;, &lt;code&gt;Policy&lt;/code&gt;), versionáveis em Git e entregues por GitOps. Quem já escreve manifests consegue escrever políticas no mesmo dia.&lt;/p&gt;

&lt;p&gt;O que o Kyverno faz, em resumo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Validar&lt;/strong&gt;: bloquear ou apenas auditar recursos fora do padrão (por exemplo, containers rodando como root).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mutar&lt;/strong&gt;: injetar valores padrão (labels, &lt;code&gt;securityContext&lt;/code&gt;, &lt;code&gt;imagePullPolicy&lt;/code&gt;) automaticamente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gerar&lt;/strong&gt;: criar recursos derivados, como &lt;code&gt;NetworkPolicy&lt;/code&gt; e &lt;code&gt;ResourceQuota&lt;/code&gt; em todo novo namespace.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verificar imagens&lt;/strong&gt;: exigir assinaturas e atestações (Cosign/Sigstore) antes de rodar uma imagem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limpar&lt;/strong&gt;: remover recursos expirados por regras de TTL ou de agendamento.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Arquitetura
&lt;/h2&gt;

&lt;p&gt;O Kyverno roda dentro do cluster como um conjunto de controladores, e o principal deles é um admission webhook registrado no API Server.&lt;/p&gt;

&lt;p&gt;[embedded content: fluxo de admissão e componentes do Kyverno]&lt;/p&gt;

&lt;p&gt;Quando uma requisição de criação ou atualização chega ao API Server, ele consulta o webhook do Kyverno, que avalia as políticas e devolve a decisão: aprovar, negar ou aprovar com alterações (patch). Só o que é aprovado é gravado no etcd.&lt;/p&gt;

&lt;p&gt;Os componentes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Admission controller&lt;/strong&gt;: atende o webhook, aplicando as regras &lt;code&gt;validate&lt;/code&gt;, &lt;code&gt;mutate&lt;/code&gt; e &lt;code&gt;verifyImages&lt;/code&gt; em tempo real.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Background controller&lt;/strong&gt;: processa regras &lt;code&gt;generate&lt;/code&gt; e &lt;code&gt;mutate&lt;/code&gt; sobre recursos existentes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reports controller&lt;/strong&gt;: consolida os resultados em &lt;code&gt;PolicyReport&lt;/code&gt; e &lt;code&gt;ClusterPolicyReport&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cleanup controller&lt;/strong&gt;: executa as políticas de limpeza e a remoção por TTL.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Como cada controlador é um Deployment separado, dá para dimensionar e escalar cada um de forma independente. Por exemplo, o admission controller, que fica no caminho de toda requisição, merece mais réplicas e mais atenção que os demais.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tipos de regras
&lt;/h2&gt;

&lt;p&gt;Uma política tem uma ou mais regras, e cada regra declara um &lt;code&gt;match&lt;/code&gt; (a quais recursos se aplica), condições opcionais (&lt;code&gt;exclude&lt;/code&gt;, &lt;code&gt;preconditions&lt;/code&gt;) e uma ação. Existem cinco tipos de ação.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tipo&lt;/th&gt;
&lt;th&gt;O que faz&lt;/th&gt;
&lt;th&gt;Quando roda&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;validate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Aprova ou rejeita o recurso conforme um padrão, uma expressão CEL ou &lt;code&gt;deny&lt;/code&gt; com condições&lt;/td&gt;
&lt;td&gt;Admissão e varredura em background&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mutate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Altera o recurso, via merge patch, JSON patch ou &lt;code&gt;foreach&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Admissão (e sobre recursos existentes, se configurado)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;generate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cria ou sincroniza outros recursos a partir de um gatilho&lt;/td&gt;
&lt;td&gt;Quando o recurso gatilho é criado ou atualizado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;verifyImages&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Confere assinaturas e atestações de imagens de container&lt;/td&gt;
&lt;td&gt;Admissão de Pods e workloads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cleanup&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Apaga recursos que casam com uma condição, em um cronograma&lt;/td&gt;
&lt;td&gt;Periodicamente (&lt;code&gt;CleanupPolicy&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A ordem importa: o Kubernetes executa as mutações antes das validações, então uma política &lt;code&gt;mutate&lt;/code&gt; pode preencher um campo que uma política &lt;code&gt;validate&lt;/code&gt; exige logo depois.&lt;/p&gt;

&lt;p&gt;A ação de uma política &lt;code&gt;validate&lt;/code&gt; depende do campo &lt;code&gt;validationFailureAction&lt;/code&gt;. Com &lt;code&gt;Audit&lt;/code&gt;, a violação é registrada, mas o recurso passa. Com &lt;code&gt;Enforce&lt;/code&gt;, a requisição é negada e o usuário recebe a mensagem de erro definida na política. Nas versões mais recentes essa configuração pode ser refinada por namespace, o que facilita uma adoção gradual.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exemplos práticos
&lt;/h2&gt;

&lt;p&gt;Os três exemplos abaixo usam a API &lt;code&gt;kyverno.io/v1&lt;/code&gt; (&lt;code&gt;ClusterPolicy&lt;/code&gt;). Os nomes de campos podem variar entre versões, então confira a documentação da versão instalada.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Validar: exigir limites de recursos&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kyverno.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ClusterPolicy&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;require-resource-limits&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;validationFailureAction&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Enforce&lt;/span&gt;
  &lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;check-limits&lt;/span&gt;
      &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;any&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;kinds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Pod&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Todos&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;os&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;containers&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;devem&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;definir&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;limits&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;de&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;CPU&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;e&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;memória."&lt;/span&gt;
        &lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                    &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;?*"&lt;/span&gt;
                    &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;?*"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Mutar: adicionar um padrão de segurança&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kyverno.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ClusterPolicy&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;add-default-security-context&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;set-run-as-non-root&lt;/span&gt;
      &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;any&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;kinds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Pod&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;mutate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;patchStrategicMerge&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;securityContext&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;+(runAsNonRoot)&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O prefixo &lt;code&gt;+()&lt;/code&gt; é um "anchor" de adição: o valor só é inserido se o campo ainda não existir, respeitando o que o desenvolvedor já definiu.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Gerar: NetworkPolicy padrão em todo namespace novo&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kyverno.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ClusterPolicy&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default-deny-ingress&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;generate-default-deny&lt;/span&gt;
      &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;any&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;kinds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Namespace&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;generate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;networking.k8s.io/v1&lt;/span&gt;
        &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NetworkPolicy&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default-deny-ingress&lt;/span&gt;
        &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{request.object.metadata.name}}"&lt;/span&gt;
        &lt;span class="na"&gt;synchronize&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;podSelector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
            &lt;span class="na"&gt;policyTypes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Ingress&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com &lt;code&gt;synchronize: true&lt;/code&gt;, se alguém apagar ou editar a &lt;code&gt;NetworkPolicy&lt;/code&gt; gerada, o Kyverno a restaura. Isso transforma a regra em uma garantia contínua, e não apenas em um passo inicial.&lt;/p&gt;

&lt;h2&gt;
  
  
  Policy Reports, Audit vs Enforce e exceções
&lt;/h2&gt;

&lt;p&gt;O caminho seguro para adotar o Kyverno em um cluster existente é começar em &lt;code&gt;Audit&lt;/code&gt;, medir o impacto e só então passar para &lt;code&gt;Enforce&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O Kyverno grava os resultados de cada avaliação em recursos &lt;code&gt;PolicyReport&lt;/code&gt; (por namespace) e &lt;code&gt;ClusterPolicyReport&lt;/code&gt;, no formato padronizado da comunidade (Policy WG). Com &lt;code&gt;background: true&lt;/code&gt;, as políticas também varrem recursos que já existem, e não só os novos. Assim você descobre quantos workloads violariam a regra antes de bloquear qualquer deploy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get policyreport &lt;span class="nt"&gt;-A&lt;/span&gt;
kubectl get clusterpolicyreport &lt;span class="nt"&gt;-o&lt;/span&gt; wide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Um roteiro de adoção que funciona bem:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Instale a política em &lt;code&gt;Audit&lt;/code&gt; e deixe rodar alguns dias.&lt;/li&gt;
&lt;li&gt;Leia os relatórios (ou exporte para Prometheus/Grafana) e corrija os workloads que violam.&lt;/li&gt;
&lt;li&gt;Trate os casos legítimos com exceções, nunca afrouxando a regra para todos.&lt;/li&gt;
&lt;li&gt;Mude para &lt;code&gt;Enforce&lt;/code&gt;, começando por namespaces não críticos.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Para exceções pontuais existem duas ferramentas: o bloco &lt;code&gt;exclude&lt;/code&gt; dentro da própria regra (por namespace, label, usuário ou role) e o recurso &lt;code&gt;PolicyException&lt;/code&gt;, que permite a uma equipe pedir a isenção de uma política específica sem editar a política original. O &lt;code&gt;PolicyException&lt;/code&gt; costuma ser mais auditável, porque cada exceção vira um objeto próprio, com dono e histórico no Git.&lt;/p&gt;

&lt;p&gt;Também vale excluir os namespaces do sistema (&lt;code&gt;kube-system&lt;/code&gt;, o próprio namespace do Kyverno) das políticas mais restritivas, para não travar componentes essenciais do cluster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kyverno CLI e testes no CI/CD
&lt;/h2&gt;

&lt;p&gt;O Kyverno CLI aplica as mesmas políticas fora do cluster, o que permite barrar um manifest inválido no pull request, bem antes do deploy.&lt;/p&gt;

&lt;p&gt;Há dois comandos principais:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;kyverno apply&lt;/code&gt;: avalia políticas contra manifests locais (ou contra recursos de um cluster) e imprime aprovações e violações.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;kyverno test&lt;/code&gt;: roda uma suíte de testes declarativa, comparando o resultado esperado de cada regra com o obtido.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Valida os manifests do repositório contra as políticas&lt;/span&gt;
kyverno apply ./policies &lt;span class="nt"&gt;--resource&lt;/span&gt; ./k8s/deployment.yaml

&lt;span class="c"&gt;# Executa os testes das políticas&lt;/span&gt;
kyverno &lt;span class="nb"&gt;test&lt;/span&gt; ./policies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Um arquivo &lt;code&gt;kyverno-test.yaml&lt;/code&gt; lista as políticas, os recursos de entrada e o resultado esperado (&lt;code&gt;pass&lt;/code&gt;, &lt;code&gt;fail&lt;/code&gt;, &lt;code&gt;skip&lt;/code&gt;) por regra. Tratar políticas como código significa testá-las como código: um teste de que o recurso ruim falha e o recurso bom passa evita que uma edição "inocente" na política abra uma brecha.&lt;/p&gt;

&lt;p&gt;Em um pipeline do GitHub Actions, o fluxo típico é:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fazer checkout do repositório de manifests e de políticas.&lt;/li&gt;
&lt;li&gt;Instalar o CLI (ação oficial ou download do binário).&lt;/li&gt;
&lt;li&gt;Rodar &lt;code&gt;kyverno test&lt;/code&gt; nas políticas e &lt;code&gt;kyverno apply&lt;/code&gt; nos manifests da aplicação.&lt;/li&gt;
&lt;li&gt;Falhar o job se houver violações em políticas de severidade alta.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O resultado é um feedback em segundos para quem abriu o PR, e o admission controller do cluster fica como última linha de defesa, não como a primeira.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalação e operação em produção
&lt;/h2&gt;

&lt;p&gt;A instalação recomendada é via Helm, em um namespace dedicado e com réplicas suficientes para alta disponibilidade.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update

helm &lt;span class="nb"&gt;install &lt;/span&gt;kyverno kyverno/kyverno &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; kyverno &lt;span class="nt"&gt;--create-namespace&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--set&lt;/span&gt; admissionController.replicas&lt;span class="o"&gt;=&lt;/span&gt;3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em produção, alguns pontos merecem atenção desde o primeiro dia:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Alta disponibilidade&lt;/strong&gt;: use três réplicas do admission controller, com &lt;code&gt;PodDisruptionBudget&lt;/code&gt; e anti-afinidade. Como o webhook está no caminho de toda requisição de criação, uma indisponibilidade pode travar deploys.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;failurePolicy&lt;/code&gt; do webhook&lt;/strong&gt;: com &lt;code&gt;Fail&lt;/code&gt;, se o Kyverno estiver fora do ar, as requisições são negadas (mais seguro, menos disponível). Com &lt;code&gt;Ignore&lt;/code&gt;, elas passam sem validação. Escolha de forma consciente por cluster.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recursos e escala&lt;/strong&gt;: o consumo de memória cresce com o número de recursos no cluster e de políticas. Defina requests e limits e acompanhe as métricas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observabilidade&lt;/strong&gt;: o Kyverno expõe métricas Prometheus (latência de admissão, resultados por política). O Policy Reporter, projeto complementar, entrega dashboards e notificações a partir dos &lt;code&gt;PolicyReport&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Políticas via GitOps&lt;/strong&gt;: mantenha as políticas em um repositório próprio e aplique com Argo CD ou Flux, para que toda mudança tenha revisão e histórico.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evite o &lt;code&gt;webhookConfiguration&lt;/code&gt; ruidoso&lt;/strong&gt;: restrinja o &lt;code&gt;match&lt;/code&gt; aos tipos de recurso necessários, para o Kyverno não ser chamado em requisições irrelevantes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Kyverno vs OPA/Gatekeeper e ValidatingAdmissionPolicy
&lt;/h2&gt;

&lt;p&gt;Kyverno se destaca pela curva de aprendizado baixa e pelo escopo amplo (mutar, gerar e verificar imagens); o Gatekeeper é a escolha de quem já usa OPA e Rego em outros sistemas; a ValidatingAdmissionPolicy nativa cobre validações simples sem instalar nada.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Critério&lt;/th&gt;
&lt;th&gt;Kyverno&lt;/th&gt;
&lt;th&gt;OPA/Gatekeeper&lt;/th&gt;
&lt;th&gt;ValidatingAdmissionPolicy (nativa)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Linguagem das regras&lt;/td&gt;
&lt;td&gt;YAML, com CEL e JMESPath em casos avançados&lt;/td&gt;
&lt;td&gt;Rego (via &lt;code&gt;ConstraintTemplate&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;CEL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Valida&lt;/td&gt;
&lt;td&gt;Sim&lt;/td&gt;
&lt;td&gt;Sim&lt;/td&gt;
&lt;td&gt;Sim&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Muta&lt;/td&gt;
&lt;td&gt;Sim&lt;/td&gt;
&lt;td&gt;Sim, com recursos mais limitados&lt;/td&gt;
&lt;td&gt;Há política de mutação nativa, mais recente&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gera recursos&lt;/td&gt;
&lt;td&gt;Sim&lt;/td&gt;
&lt;td&gt;Não&lt;/td&gt;
&lt;td&gt;Não&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verifica assinatura de imagens&lt;/td&gt;
&lt;td&gt;Sim (Cosign/Notary)&lt;/td&gt;
&lt;td&gt;Não nativamente&lt;/td&gt;
&lt;td&gt;Não&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Componente extra no cluster&lt;/td&gt;
&lt;td&gt;Sim&lt;/td&gt;
&lt;td&gt;Sim&lt;/td&gt;
&lt;td&gt;Não, roda dentro do API server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Curva de aprendizado&lt;/td&gt;
&lt;td&gt;Baixa para quem conhece YAML&lt;/td&gt;
&lt;td&gt;Alta (Rego)&lt;/td&gt;
&lt;td&gt;Média (CEL)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Na prática, as três opções não são excludentes. Há times que usam a ValidatingAdmissionPolicy para regras simples e de alta performance e o Kyverno para mutação, geração e verificação de imagens. O próprio Kyverno vem incorporando CEL e novos tipos de política para se aproximar do modelo nativo, então vale conferir na documentação o estado atual dessa evolução antes de escolher o formato das suas políticas.&lt;/p&gt;

&lt;p&gt;Uma regra de bolso: se o time já domina Rego e usa OPA fora do Kubernetes, o Gatekeeper preserva o investimento. Se a prioridade é adotar rápido, com políticas legíveis por qualquer pessoa que escreva manifests, o Kyverno costuma ser o caminho mais curto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Boas práticas e armadilhas comuns
&lt;/h2&gt;

&lt;p&gt;A maior parte dos problemas com Kyverno vem de adotar rápido demais ou de escrever regras amplas demais.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Comece em &lt;code&gt;Audit&lt;/code&gt;&lt;/strong&gt;: bloquear no primeiro dia é o jeito mais rápido de gerar resistência das equipes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mensagens de erro claras&lt;/strong&gt;: diga o que está errado e como corrigir. Uma mensagem boa economiza um chamado de suporte.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uma política, um objetivo&lt;/strong&gt;: políticas pequenas e nomeadas pelo que fazem (&lt;code&gt;require-labels&lt;/code&gt;, &lt;code&gt;disallow-latest-tag&lt;/code&gt;) são mais fáceis de testar, excluir e auditar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reaproveite as políticas da comunidade&lt;/strong&gt;: o catálogo de políticas do Kyverno cobre o Pod Security Standards, boas práticas de rede e supply chain, e serve de ponto de partida.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cuidado com &lt;code&gt;generate&lt;/code&gt; e &lt;code&gt;mutate&lt;/code&gt; em cascata&lt;/strong&gt;: regras que geram recursos que disparam outras regras são difíceis de depurar. Teste com &lt;code&gt;kyverno test&lt;/code&gt; antes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exclua componentes críticos&lt;/strong&gt;: o &lt;code&gt;kube-system&lt;/code&gt; e o próprio Kyverno devem ficar fora das regras mais restritivas, para evitar o deadlock de um cluster que não consegue subir os próprios pods.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Revise exceções periodicamente&lt;/strong&gt;: exceções temporárias tendem a virar permanentes se ninguém as reavalia.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Versione tudo no Git&lt;/strong&gt;: políticas, testes e exceções, com revisão por pull request.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;O Kyverno transforma boas práticas de segurança e governança em regras executáveis, escritas na mesma linguagem dos manifests que o time já domina. Ele valida e muta na admissão, gera recursos que precisam existir em todo namespace e confere a origem das imagens, tudo versionado em Git e testável no CI.&lt;/p&gt;

&lt;p&gt;Para começar, instale o Kyverno em um cluster de teste, aplique uma política de validação em &lt;code&gt;Audit&lt;/code&gt;, leia os &lt;code&gt;PolicyReport&lt;/code&gt; e evolua gradualmente até o &lt;code&gt;Enforce&lt;/code&gt;. Em poucos dias você terá uma visão concreta do quanto o cluster se afasta do padrão desejado, e um caminho seguro para corrigir isso.&lt;/p&gt;

</description>
      <category>kyverno</category>
      <category>kubernetes</category>
      <category>cloud</category>
      <category>cloudcomputing</category>
    </item>
    <item>
      <title>Amazon Aurora Serverless v2 guia detalhado de arquitetura, escala, custo e operação</title>
      <dc:creator>Kauê Matos</dc:creator>
      <pubDate>Tue, 06 Oct 2026 01:20:35 +0000</pubDate>
      <link>https://dev.to/ikauedev/amazon-aurora-serverless-v2-guia-detalhado-de-arquitetura-escala-custo-e-operacao-999</link>
      <guid>https://dev.to/ikauedev/amazon-aurora-serverless-v2-guia-detalhado-de-arquitetura-escala-custo-e-operacao-999</guid>
      <description>&lt;p&gt;O &lt;strong&gt;Amazon Aurora Serverless v2&lt;/strong&gt; é uma configuração do Aurora em que a &lt;strong&gt;capacidade de computação do banco acompanha a demanda em tempo real&lt;/strong&gt;, em vez de ser fixada na criação da instância. Você define uma faixa (mínimo e máximo) e o Aurora ajusta a capacidade dentro dela, sem reiniciar o banco e sem derrubar conexões.&lt;/p&gt;

&lt;p&gt;Ele &lt;strong&gt;não é um produto separado&lt;/strong&gt;, e sim um &lt;em&gt;tipo de instância&lt;/em&gt; dentro de um cluster Aurora comum (&lt;code&gt;db.serverless&lt;/code&gt;). Por isso herda o armazenamento distribuído, o Multi-AZ, as réplicas de leitura e o restante do ecossistema do Aurora.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Os valores de preço, limites de ACU e disponibilidade por versão de motor mudam com o tempo. Os números deste artigo são referências para raciocínio. Confirme sempre na documentação e na página de preços da AWS.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  2. Um pouco de contexto: v1 vs. v2
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Serverless v1&lt;/th&gt;
&lt;th&gt;Serverless v2&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Modelo&lt;/td&gt;
&lt;td&gt;Cluster inteiro escala&lt;/td&gt;
&lt;td&gt;Instâncias escalam individualmente&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Escala&lt;/td&gt;
&lt;td&gt;Em degraus, com pausa para encontrar "ponto seguro"&lt;/td&gt;
&lt;td&gt;Contínua, em incrementos pequenos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Interrompe conexões ao escalar&lt;/td&gt;
&lt;td&gt;Pode interromper&lt;/td&gt;
&lt;td&gt;Não&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-AZ, réplicas, Global DB&lt;/td&gt;
&lt;td&gt;Limitado&lt;/td&gt;
&lt;td&gt;Suportado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Granularidade&lt;/td&gt;
&lt;td&gt;Capacidade dobra&lt;/td&gt;
&lt;td&gt;0,5 ACU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Status&lt;/td&gt;
&lt;td&gt;Legado&lt;/td&gt;
&lt;td&gt;Modelo atual&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A v2 foi desenhada para eliminar as limitações da v1 e é o modelo recomendado para novas cargas.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Como funciona por dentro
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 O ACU (Aurora Capacity Unit)
&lt;/h3&gt;

&lt;p&gt;Cada &lt;strong&gt;ACU equivale a aproximadamente 2 GiB de memória&lt;/strong&gt;, com CPU e rede proporcionais. A capacidade vai de frações de ACU até centenas de ACUs, e o incremento é de &lt;strong&gt;0,5 ACU&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Pense no ACU como uma "fatia" de instância: um banco a 16 ACU tem algo na ordem de 32 GiB de memória disponíveis.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2 Escala em linha (in-place)
&lt;/h3&gt;

&lt;p&gt;Diferentemente da troca de classe de instância, a v2 &lt;strong&gt;ajusta CPU e memória dentro do próprio processo do banco&lt;/strong&gt;. As consequências práticas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sem failover para escalar.&lt;/li&gt;
&lt;li&gt;Conexões e transações em andamento são preservadas.&lt;/li&gt;
&lt;li&gt;A escala responde a CPU, memória e rede, não só ao número de conexões.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A velocidade da escala &lt;strong&gt;depende da capacidade atual&lt;/strong&gt;: quanto maior a instância já está, mais rápido ela cresce. Um banco parado em 0,5 ACU sobe mais devagar que um que já opera em 16 ACU. Isso é relevante para quem usa mínimo muito baixo e espera picos bruscos.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.3 Faixa mínima e máxima
&lt;/h3&gt;

&lt;p&gt;Você configura:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;min_capacity&lt;/code&gt;:&lt;/strong&gt; piso de capacidade (pode ser 0 ACU com auto-pause, em versões de motor compatíveis).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;max_capacity&lt;/code&gt;:&lt;/strong&gt; teto de capacidade e &lt;strong&gt;teto de custo&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O ACU em uso nunca sai dessa faixa. Além de controlar custo, o piso e o teto influenciam parâmetros do banco, como o tamanho do &lt;em&gt;buffer pool&lt;/em&gt; e o número máximo de conexões, que são derivados da configuração de capacidade.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.4 Auto-pause (scale-to-zero)
&lt;/h3&gt;

&lt;p&gt;Com &lt;code&gt;min_capacity = 0&lt;/code&gt;, o banco pode &lt;strong&gt;pausar após um período de inatividade&lt;/strong&gt; que você configura, e a computação deixa de ser cobrada. Ao chegar uma nova conexão, o banco &lt;strong&gt;retoma&lt;/strong&gt;, o que leva algum tempo (na casa de segundos).&lt;/p&gt;

&lt;p&gt;Pontos de atenção:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O armazenamento continua sendo cobrado.&lt;/li&gt;
&lt;li&gt;A primeira requisição após a pausa sofre a latência de retomada.&lt;/li&gt;
&lt;li&gt;É ideal para dev, teste e ferramentas internas, e &lt;strong&gt;arriscado para produção&lt;/strong&gt; com usuários esperando.&lt;/li&gt;
&lt;li&gt;Conexões em &lt;em&gt;pool&lt;/em&gt; e &lt;em&gt;health checks&lt;/em&gt; frequentes podem impedir a pausa, mantendo o banco acordado sem você perceber.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3.5 Armazenamento
&lt;/h3&gt;

&lt;p&gt;O armazenamento é o mesmo do Aurora convencional: volume distribuído em 3 AZs, com 6 cópias, crescendo automaticamente. Você não provisiona disco. A cobrança de storage e I/O é independente do tipo de instância, e existem as opções de configuração &lt;strong&gt;Standard&lt;/strong&gt; e &lt;strong&gt;I/O-Optimized&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.6 Tiers de promoção em clusters com readers
&lt;/h3&gt;

&lt;p&gt;Em clusters com mais de uma instância, os &lt;strong&gt;tiers de failover (0 a 15)&lt;/strong&gt; influenciam como os readers escalam:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tiers 0 e 1:&lt;/strong&gt; o reader acompanha a capacidade do writer, para estar pronto para assumir em caso de failover.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tiers 2 a 15:&lt;/strong&gt; o reader escala de forma independente, de acordo com a própria carga.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essa escolha afeta diretamente custo e prontidão para failover.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Recursos suportados
&lt;/h2&gt;

&lt;p&gt;Em geral, a v2 funciona com o ecossistema do Aurora:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-AZ e failover automático&lt;/li&gt;
&lt;li&gt;Até 15 réplicas de leitura&lt;/li&gt;
&lt;li&gt;Aurora Global Database&lt;/li&gt;
&lt;li&gt;RDS Proxy&lt;/li&gt;
&lt;li&gt;Performance Insights e Enhanced Monitoring&lt;/li&gt;
&lt;li&gt;Backups, snapshots e Point-in-Time Recovery&lt;/li&gt;
&lt;li&gt;Criptografia com KMS e autenticação IAM&lt;/li&gt;
&lt;li&gt;Integração com Secrets Manager (&lt;code&gt;manage_master_user_password&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Blue/Green Deployments&lt;/li&gt;
&lt;li&gt;Data API (conforme versão e região)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compatível com &lt;strong&gt;Aurora MySQL&lt;/strong&gt; e &lt;strong&gt;Aurora PostgreSQL&lt;/strong&gt;, em versões de motor específicas. Vale checar a matriz de versões antes de criar o cluster.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Modelo de custo
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 Como é cobrado
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Computação:&lt;/strong&gt; ACU-hora consumido, medido por segundo, com mínimo de cobrança por período de capacidade.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Armazenamento:&lt;/strong&gt; por GB-mês.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I/O:&lt;/strong&gt; por requisição no modo Standard. No modo I/O-Optimized não há cobrança de I/O, mas o preço de computação e storage é maior.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backups&lt;/strong&gt; além da retenção gratuita, &lt;strong&gt;transferência de dados&lt;/strong&gt;, &lt;strong&gt;Performance Insights&lt;/strong&gt; além do tier gratuito, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.2 Raciocínio de break-even
&lt;/h3&gt;

&lt;p&gt;O ACU-hora é, por unidade de memória, &lt;strong&gt;mais caro&lt;/strong&gt; que uma instância provisionada equivalente. Ilustrando com valores aproximados de us-east-1:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 ACU ≈ US$ 0,12/h → rodando 24x7 ≈ &lt;strong&gt;US$ 87/mês por ACU&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Uma instância &lt;code&gt;db.r6g.large&lt;/code&gt; (16 GiB) custa em torno de US$ 0,26/h ≈ &lt;strong&gt;US$ 190/mês&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;16 GiB equivalem a ~8 ACUs, que custariam ≈ US$ 0,96/h ≈ &lt;strong&gt;US$ 700/mês&lt;/strong&gt; se ficassem sempre ligados.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A conclusão é que, &lt;strong&gt;sob carga constante e alta&lt;/strong&gt;, o provisionado é bem mais barato. Já se o banco &lt;strong&gt;usa em média menos de ~25–30% da capacidade equivalente&lt;/strong&gt;, o serverless costuma sair na frente, e com auto-pause em dev pode custar uma fração.&lt;/p&gt;

&lt;p&gt;O raciocínio correto é: &lt;strong&gt;custo = média de ACUs consumidos ao longo do tempo × preço do ACU-hora&lt;/strong&gt;. Por isso o monitoramento de ACU médio importa mais que o pico.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.3 O que não esquecer
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reserved Instances&lt;/strong&gt; não se aplicam ao ACU da mesma forma. Savings Plans para banco de dados podem se aplicar, conforme as regras vigentes.&lt;/li&gt;
&lt;li&gt;O &lt;code&gt;max_capacity&lt;/code&gt; é seu &lt;strong&gt;limite de gasto de computação&lt;/strong&gt;, então defina-o conscientemente.&lt;/li&gt;
&lt;li&gt;Readers com tier 0/1 acompanham o writer, e isso &lt;strong&gt;multiplica o custo&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6. Quando usar (e quando evitar)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bons casos de uso
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cargas variáveis ou imprevisíveis:&lt;/strong&gt; e-commerce com campanhas, apps com picos em horário comercial.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aplicações novas&lt;/strong&gt; sem histórico de consumo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev, teste e homologação:&lt;/strong&gt; principalmente com auto-pause.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SaaS multi-tenant&lt;/strong&gt; com muitos bancos de perfis diferentes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workloads com picos curtos:&lt;/strong&gt; relatórios noturnos, processamento em lote.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Arquiteturas serverless&lt;/strong&gt; (Lambda + RDS Proxy) em que o tráfego é irregular.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Quando reconsiderar
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Carga alta e constante 24x7:&lt;/strong&gt; provisionado com Reserved Instance tende a custar menos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latência ultra-previsível exigida:&lt;/strong&gt; variações de cache durante escalas podem incomodar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Produção com auto-pause:&lt;/strong&gt; a latência de retomada geralmente é inaceitável.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Falta de limite de custo definido:&lt;/strong&gt; um &lt;code&gt;max_capacity&lt;/code&gt; alto sem alarmes pode gerar conta alta com uma query mal escrita.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. Arquitetura de referência
&lt;/h2&gt;

&lt;p&gt;Um padrão comum para uma aplicação web em produção:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Usuários
   │
CloudFront ── ALB ── ECS/EKS (aplicação)
                         │
                    RDS Proxy
                         │
        ┌────────────────┴───────────────┐
   Writer (Serverless v2)        Reader(s) (Serverless v2)
        └────────────────┬───────────────┘
              Volume Aurora (3 AZs, 6 cópias)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pontos de design:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Writer em Serverless v2&lt;/strong&gt; com mínimo que mantenha o cache aquecido.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Readers em tier 2+&lt;/strong&gt; se você quer que escalem de forma independente e mais barata.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RDS Proxy&lt;/strong&gt; na frente, para absorver conexões e reduzir o impacto de &lt;em&gt;connection storms&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secrets Manager&lt;/strong&gt; para credenciais, com rotação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subnets privadas&lt;/strong&gt;, com Security Groups restritos à camada de aplicação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alarmes&lt;/strong&gt; de ACU, CPU, conexões e latência.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Variação: cluster misto
&lt;/h3&gt;

&lt;p&gt;Como o storage é compartilhado, é possível ter um &lt;strong&gt;writer provisionado&lt;/strong&gt; (carga estável, com desconto) e &lt;strong&gt;readers Serverless v2&lt;/strong&gt; para absorver picos de leitura. É um bom caminho para quem quer previsibilidade na escrita e elasticidade na leitura.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Implementação com Terraform
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_db_subnet_group"&lt;/span&gt; &lt;span class="s2"&gt;"this"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"app-aurora-subnets"&lt;/span&gt;
  &lt;span class="nx"&gt;subnet_ids&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;private_subnet_ids&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_security_group"&lt;/span&gt; &lt;span class="s2"&gt;"db"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"app-aurora-sg"&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vpc_id&lt;/span&gt;

  &lt;span class="nx"&gt;ingress&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;from_port&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5432&lt;/span&gt;
    &lt;span class="nx"&gt;to_port&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5432&lt;/span&gt;
    &lt;span class="nx"&gt;protocol&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;
    &lt;span class="nx"&gt;security_groups&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;app_security_group_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_rds_cluster"&lt;/span&gt; &lt;span class="s2"&gt;"this"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cluster_identifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"app-aurora-sv2"&lt;/span&gt;
  &lt;span class="nx"&gt;engine&lt;/span&gt;             &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"aurora-postgresql"&lt;/span&gt;
  &lt;span class="nx"&gt;engine_mode&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"provisioned"&lt;/span&gt;   &lt;span class="c1"&gt;# Serverless v2 usa o modo provisioned&lt;/span&gt;
  &lt;span class="nx"&gt;engine_version&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"16.4"&lt;/span&gt;

  &lt;span class="nx"&gt;database_name&lt;/span&gt;               &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"appdb"&lt;/span&gt;
  &lt;span class="nx"&gt;master_username&lt;/span&gt;             &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"dbadmin"&lt;/span&gt;
  &lt;span class="nx"&gt;manage_master_user_password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

  &lt;span class="nx"&gt;db_subnet_group_name&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_db_subnet_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_security_group_ids&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;aws_security_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="nx"&gt;storage_encrypted&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;backup_retention_period&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;
  &lt;span class="nx"&gt;deletion_protection&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;copy_tags_to_snapshot&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

  &lt;span class="nx"&gt;serverlessv2_scaling_configuration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;min_capacity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="nx"&gt;max_capacity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
    &lt;span class="c1"&gt;# seconds_until_auto_pause = 600   # só com min_capacity = 0&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_rds_cluster_instance"&lt;/span&gt; &lt;span class="s2"&gt;"writer"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;identifier&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"app-aurora-sv2-writer"&lt;/span&gt;
  &lt;span class="nx"&gt;cluster_identifier&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_rds_cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;engine&lt;/span&gt;               &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_rds_cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;engine&lt;/span&gt;
  &lt;span class="nx"&gt;engine_version&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_rds_cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;engine_version&lt;/span&gt;
  &lt;span class="nx"&gt;instance_class&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"db.serverless"&lt;/span&gt;
  &lt;span class="nx"&gt;promotion_tier&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="nx"&gt;performance_insights_enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_rds_cluster_instance"&lt;/span&gt; &lt;span class="s2"&gt;"reader"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;identifier&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"app-aurora-sv2-reader"&lt;/span&gt;
  &lt;span class="nx"&gt;cluster_identifier&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_rds_cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;engine&lt;/span&gt;               &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_rds_cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;engine&lt;/span&gt;
  &lt;span class="nx"&gt;engine_version&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_rds_cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;engine_version&lt;/span&gt;
  &lt;span class="nx"&gt;instance_class&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"db.serverless"&lt;/span&gt;
  &lt;span class="nx"&gt;promotion_tier&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;   &lt;span class="c1"&gt;# escala de forma independente do writer&lt;/span&gt;
  &lt;span class="nx"&gt;performance_insights_enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Observações:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O &lt;code&gt;engine_mode&lt;/code&gt; continua &lt;code&gt;provisioned&lt;/code&gt;. O que torna a instância serverless é o &lt;code&gt;instance_class = "db.serverless"&lt;/code&gt; junto com o bloco &lt;code&gt;serverlessv2_scaling_configuration&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A capacidade é configurada &lt;strong&gt;no cluster&lt;/strong&gt;, e vale para todas as instâncias serverless dele.&lt;/li&gt;
&lt;li&gt;Verifique a versão do provider AWS para suporte a recursos mais novos, como o auto-pause.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  9. Observabilidade
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Métricas essenciais (CloudWatch)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Métrica&lt;/th&gt;
&lt;th&gt;O que mostra&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ServerlessDatabaseCapacity&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ACUs em uso no momento&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ACUUtilization&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;% do &lt;code&gt;max_capacity&lt;/code&gt; em uso&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CPUUtilization&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CPU, no contexto da capacidade atual&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FreeableMemory&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Memória livre&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DatabaseConnections&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Conexões abertas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BufferCacheHitRatio&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Eficiência do cache&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AuroraReplicaLag&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Atraso dos readers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Alarmes recomendados
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ACUUtilization&lt;/code&gt; alto por tempo prolongado, o que indica &lt;code&gt;max_capacity&lt;/code&gt; apertado.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ServerlessDatabaseCapacity&lt;/code&gt; encostando no máximo, o que sinaliza risco de saturação &lt;strong&gt;e&lt;/strong&gt; de custo.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;BufferCacheHitRatio&lt;/code&gt; caindo após escalas para baixo.&lt;/li&gt;
&lt;li&gt;Conexões se aproximando do limite.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Um padrão útil: acompanhar a &lt;strong&gt;média de ACU por dia&lt;/strong&gt; e cruzar com a fatura, para validar se o serverless está compensando em relação ao provisionado.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Boas práticas
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Dimensione o mínimo pelo cache, não só pelo custo.&lt;/strong&gt; Um piso muito baixo faz o &lt;em&gt;working set&lt;/em&gt; sair da memória, e a latência piora quando a carga volta.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dimensione o máximo pelo teto de custo aceitável&lt;/strong&gt; e pelo pior pico real.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use RDS Proxy&lt;/strong&gt; com Lambda ou aplicações com muitas conexões curtas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Não use auto-pause em produção&lt;/strong&gt; com usuários finais, a menos que a latência de retomada seja aceitável.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escolha o tier de promoção dos readers&lt;/strong&gt; de acordo com a necessidade de failover rápido versus economia.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Defina alarmes de custo&lt;/strong&gt; (AWS Budgets) e de ACU. Uma query descontrolada pode manter o banco no máximo por horas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Otimize queries antes de aumentar o máximo.&lt;/strong&gt; Escalar infraestrutura para esconder SQL ruim é caro.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Teste carga com perfil realista&lt;/strong&gt;, incluindo picos súbitos, para validar a velocidade de escala partindo do mínimo escolhido.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mantenha IaC e proteção contra deleção&lt;/strong&gt; ligadas em produção.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reavalie a cada trimestre:&lt;/strong&gt; se a carga estabilizou, talvez o writer deva migrar para uma instância fixa.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  11. Migração
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;De Aurora provisionado para Serverless v2:&lt;/strong&gt; como o storage é o mesmo, adicione uma instância &lt;code&gt;db.serverless&lt;/code&gt; ao cluster, promova-a via failover e remova a instância antiga. É necessário que a versão do motor seja compatível.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;De Serverless v1 para v2:&lt;/strong&gt; o caminho é por snapshot/restauração ou por upgrade de versão com recriação, conforme a documentação vigente. Planeje uma janela de manutenção e teste no ambiente de homologação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;De RDS comum para Aurora Serverless v2:&lt;/strong&gt; use réplica de leitura Aurora ou o AWS DMS, dependendo do motor e da tolerância a downtime.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  12. Armadilhas comuns
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Achar que serverless é sempre mais barato.&lt;/strong&gt; Em carga constante e alta, é o contrário.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mínimo em 0,5 ACU em produção&lt;/strong&gt; e depois estranhar a lentidão no primeiro pico.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Esquecer que readers de tier 0/1 acompanham o writer&lt;/strong&gt; e dobram o custo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deixar o &lt;code&gt;max_capacity&lt;/code&gt; muito alto&lt;/strong&gt; sem alarmes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pools de conexão que impedem o auto-pause&lt;/strong&gt; em ambientes de dev.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignorar limites de conexão&lt;/strong&gt; derivados da capacidade configurada.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  13. Conclusão
&lt;/h2&gt;

&lt;p&gt;O Aurora Serverless v2 resolve um problema clássico: &lt;strong&gt;pagar por capacidade que você só usa em parte do tempo&lt;/strong&gt;. Ele entrega elasticidade fina, sem downtime ao escalar, e mantém todos os recursos do Aurora. Em troca, cobra mais caro por unidade de capacidade e exige disciplina com limites, monitoramento e dimensionamento de mínimo e máximo.&lt;/p&gt;

&lt;p&gt;A decisão certa não é "serverless ou fixo" de forma absoluta, e sim &lt;strong&gt;medir a utilização real, calcular o custo nos dois modelos e, quando fizer sentido, combiná-los no mesmo cluster&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>webdev</category>
      <category>programming</category>
      <category>devops</category>
    </item>
    <item>
      <title>Artifact Hub: o guia completo do repositório central de pacotes Kubernetes</title>
      <dc:creator>Kauê Matos</dc:creator>
      <pubDate>Sun, 04 Oct 2026 13:45:52 +0000</pubDate>
      <link>https://dev.to/ikauedev/artifact-hub-o-guia-completo-do-repositorio-central-de-pacotes-kubernetes-7o4</link>
      <guid>https://dev.to/ikauedev/artifact-hub-o-guia-completo-do-repositorio-central-de-pacotes-kubernetes-7o4</guid>
      <description>&lt;p&gt;Quem trabalha com Kubernetes conhece o ritual: precisa de um ingress controller, um operador de banco, uma política de segurança ou um plugin do &lt;code&gt;kubectl&lt;/code&gt;, e começa a busca no GitHub, em blogs e em READMEs. Cada projeto publica de um jeito, em um lugar diferente, com níveis variados de documentação e de cuidado com segurança.&lt;/p&gt;

&lt;p&gt;O &lt;a href="https://artifacthub.io" rel="noopener noreferrer"&gt;Artifact Hub&lt;/a&gt; centraliza essa descoberta. Ele indexa pacotes de centenas de repositórios e mostra, numa interface única, documentação, versões, licença, mantenedores, vulnerabilidades conhecidas e o comando de instalação. Este artigo explica o que ele é, como funciona por dentro, como consumir e publicar pacotes e quais cuidados de segurança e governança times de plataforma devem ter.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é o Artifact Hub
&lt;/h2&gt;

&lt;p&gt;O Artifact Hub é uma aplicação web de código aberto, hospedada pela CNCF em artifacthub.io, para descobrir, instalar e publicar pacotes e configurações de projetos cloud native. Ele nasceu a partir do antigo Helm Hub, que foi incorporado a ele, e hoje é um projeto da CNCF (confira o nível de maturidade atual na página do projeto na CNCF, pois ele muda com o tempo).&lt;/p&gt;

&lt;p&gt;O ponto mais importante: &lt;strong&gt;o Artifact Hub é um catálogo, não um registry&lt;/strong&gt;. Ele não armazena seus charts nem suas imagens. Quem publica continua hospedando os artefatos onde já hospeda (um repositório Helm em GitHub Pages, um registry OCI, um repositório Git) e o Artifact Hub apenas indexa os metadados e os apresenta.&lt;/p&gt;

&lt;p&gt;Na prática, isso traz três consequências:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Você não depende dele para instalar: &lt;code&gt;helm install&lt;/code&gt; continua apontando para o repositório de origem.&lt;/li&gt;
&lt;li&gt;Se um repositório sai do ar, o pacote some da fonte, mesmo que a página continue listada por um tempo.&lt;/li&gt;
&lt;li&gt;A confiança vem dos sinais que ele exibe (publisher verificado, status oficial, scan de segurança, assinatura), e não do simples fato de o pacote estar listado.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tipos de artefatos suportados
&lt;/h2&gt;

&lt;p&gt;Helm charts são a maior parte do catálogo, mas o Artifact Hub cobre muito mais do que isso. A lista abaixo mostra os tipos mais usados; ela cresce conforme projetos da CNCF adotam a plataforma, então vale conferir a documentação para o conjunto atual.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tipo&lt;/th&gt;
&lt;th&gt;O que é&lt;/th&gt;
&lt;th&gt;Onde costuma ser usado&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Helm charts&lt;/td&gt;
&lt;td&gt;Pacotes de manifests Kubernetes com templates e values&lt;/td&gt;
&lt;td&gt;Instalar aplicações e componentes de cluster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OLM operators&lt;/td&gt;
&lt;td&gt;Operadores empacotados para o Operator Lifecycle Manager&lt;/td&gt;
&lt;td&gt;Bancos de dados, mensageria e outros serviços com ciclo de vida complexo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tekton tasks e pipelines&lt;/td&gt;
&lt;td&gt;Blocos reutilizáveis de CI/CD nativo de Kubernetes&lt;/td&gt;
&lt;td&gt;Pipelines de build e deploy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Políticas (OPA, Gatekeeper, Kyverno, Kubewarden)&lt;/td&gt;
&lt;td&gt;Regras de admissão e conformidade&lt;/td&gt;
&lt;td&gt;Governança e segurança de cluster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Regras Falco&lt;/td&gt;
&lt;td&gt;Detecção de comportamento anômalo em runtime&lt;/td&gt;
&lt;td&gt;Observabilidade de segurança&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Plugins do kubectl (Krew)&lt;/td&gt;
&lt;td&gt;Extensões da CLI do Kubernetes&lt;/td&gt;
&lt;td&gt;Produtividade e troubleshooting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backstage plugins&lt;/td&gt;
&lt;td&gt;Plugins para portais de desenvolvedores&lt;/td&gt;
&lt;td&gt;Plataformas internas (IDP)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Imagens de container&lt;/td&gt;
&lt;td&gt;Referências a imagens publicadas&lt;/td&gt;
&lt;td&gt;Descoberta e avaliação de segurança&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Outros&lt;/td&gt;
&lt;td&gt;KEDA scalers, plugins do CoreDNS, templates Argo, entre outros&lt;/td&gt;
&lt;td&gt;Casos específicos de cada projeto&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Para times de plataforma, essa diversidade é a vantagem real: um único lugar para procurar tanto o chart do cert-manager quanto a política Kyverno que impõe limites de recursos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arquitetura: como o catálogo é montado
&lt;/h2&gt;

&lt;p&gt;O Artifact Hub é composto por poucos serviços em torno de um banco PostgreSQL: o hub (API e interface), o tracker, o scanner e o notifier.&lt;/p&gt;

&lt;p&gt;[embedded content: arquitetura do Artifact Hub · 5 serviços e os repositórios de origem]&lt;/p&gt;

&lt;p&gt;O tracker lê os repositórios de origem e grava os metadados no banco; o scanner analisa as imagens com o Trivy; o notifier envia alertas por e-mail e webhook. O hub serve a interface e a API a partir do banco, enquanto a instalação com &lt;code&gt;helm install&lt;/code&gt; vai sempre direto à origem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como usar: buscar, avaliar e instalar
&lt;/h2&gt;

&lt;p&gt;O fluxo de consumo tem três passos: buscar, avaliar o pacote e instalar a partir do repositório de origem.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Buscar.&lt;/strong&gt; Use a busca em artifacthub.io e filtre por tipo (por exemplo, apenas Helm charts), por publisher verificado, por status oficial ou por licença.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avaliar.&lt;/strong&gt; Abra a página do pacote e olhe, nessa ordem: quem publica (selos de &lt;em&gt;Verified publisher&lt;/em&gt; e &lt;em&gt;Official&lt;/em&gt;), data da última versão, changelog, relatório de segurança, licença, links de documentação e o &lt;code&gt;values.yaml&lt;/code&gt; com seu schema.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instalar.&lt;/strong&gt; O botão &lt;em&gt;Install&lt;/em&gt; mostra os comandos exatos. Para um chart Helm, o formato é este (exemplo com o cert-manager):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm repo add jetstack https://charts.jetstack.io
helm repo update
helm &lt;span class="nb"&gt;install &lt;/span&gt;cert-manager jetstack/cert-manager &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--namespace&lt;/span&gt; cert-manager &lt;span class="nt"&gt;--create-namespace&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--set&lt;/span&gt; crds.enabled&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use sempre os comandos da página do pacote, porque flags como a que habilita os CRDs mudam entre versões. Para inspecionar antes de instalar, &lt;code&gt;helm show values jetstack/cert-manager&lt;/code&gt; e &lt;code&gt;helm template&lt;/code&gt; ajudam a revisar o que será aplicado.&lt;/p&gt;

&lt;p&gt;O Artifact Hub também tem uma API REST pública, útil para automação. Um exemplo de busca por charts (confirme os parâmetros na &lt;a href="https://artifacthub.io/docs/api/" rel="noopener noreferrer"&gt;documentação da API&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://artifacthub.io/api/v1/packages/search?ts_query_web=cert-manager&amp;amp;kind=0&amp;amp;limit=5"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com uma conta gratuita você também pode seguir pacotes, receber notificações de novas versões e de alertas de segurança por e-mail ou webhook, e dar &lt;em&gt;star&lt;/em&gt; nos pacotes que sua equipe usa.&lt;/p&gt;

&lt;h2&gt;
  
  
  Publicando seus pacotes
&lt;/h2&gt;

&lt;p&gt;Publicar no Artifact Hub é registrar um repositório que você já mantém, não subir arquivos. O processo tem quatro etapas.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Hospede o chart&lt;/strong&gt; em um repositório Helm (GitHub Pages com o &lt;code&gt;chart-releaser&lt;/code&gt;, por exemplo) ou em um registry OCI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adicione o repositório&lt;/strong&gt; no painel de controle do Artifact Hub (conta necessária), informando tipo, nome e URL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comprove a propriedade&lt;/strong&gt; com o arquivo &lt;code&gt;artifacthub-repo.yml&lt;/code&gt;, publicado na raiz do repositório (ou como tag especial em registries OCI), contendo o &lt;code&gt;repositoryID&lt;/code&gt; gerado pela plataforma e o e-mail do dono. Isso concede o selo &lt;em&gt;Verified publisher&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enriqueça os metadados&lt;/strong&gt; com annotations no &lt;code&gt;Chart.yaml&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Exemplo de &lt;code&gt;artifacthub-repo.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;repositoryID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;00000000-0000-0000-0000-000000000000&lt;/span&gt;
&lt;span class="na"&gt;owners&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Time de Plataforma&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;plataforma@exemplo.com.br&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E de annotations no &lt;code&gt;Chart.yaml&lt;/code&gt;, que melhoram a página do pacote:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;artifacthub.io/license&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Apache-2.0&lt;/span&gt;
  &lt;span class="na"&gt;artifacthub.io/images&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
    &lt;span class="s"&gt;- name: minha-app&lt;/span&gt;
      &lt;span class="s"&gt;image: ghcr.io/minha-org/minha-app:1.4.2&lt;/span&gt;
  &lt;span class="na"&gt;artifacthub.io/changes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
    &lt;span class="s"&gt;- kind: added&lt;/span&gt;
      &lt;span class="s"&gt;description: Suporte a ServiceMonitor&lt;/span&gt;
    &lt;span class="s"&gt;- kind: fixed&lt;/span&gt;
      &lt;span class="s"&gt;description: Probe de readiness com timeout incorreto&lt;/span&gt;
  &lt;span class="na"&gt;artifacthub.io/links&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
    &lt;span class="s"&gt;- name: Documentação&lt;/span&gt;
      &lt;span class="s"&gt;url: https://exemplo.com.br/docs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A annotation &lt;code&gt;artifacthub.io/images&lt;/code&gt; é a mais importante para segurança: é por ela que o scanner sabe quais imagens analisar. Outras annotations úteis cobrem mantenedores, CRDs com exemplos, recomendações e marcação de versões &lt;em&gt;prerelease&lt;/em&gt; ou com correções de segurança.&lt;/p&gt;

&lt;p&gt;O selo &lt;em&gt;Official&lt;/em&gt; é diferente: indica que o publicador é o dono do software empacotado, e é concedido pela equipe do Artifact Hub após solicitação.&lt;/p&gt;

&lt;p&gt;No CI (GitHub Actions, por exemplo), rode o &lt;code&gt;ah lint&lt;/code&gt; (CLI do projeto) sobre o chart antes de cada release para pegar annotations malformadas antes que o tracker as rejeite.&lt;/p&gt;

&lt;h2&gt;
  
  
  Segurança: o que o Artifact Hub verifica e o que não verifica
&lt;/h2&gt;

&lt;p&gt;O Artifact Hub oferece sinais úteis de segurança, mas nenhum deles substitui a revisão do seu próprio time. Entender o limite de cada sinal evita falsa sensação de proteção.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Sinal&lt;/th&gt;
&lt;th&gt;O que significa&lt;/th&gt;
&lt;th&gt;O que &lt;strong&gt;não&lt;/strong&gt; garante&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Verified publisher&lt;/td&gt;
&lt;td&gt;O dono do repositório comprovou controle sobre ele via &lt;code&gt;artifacthub-repo.yml&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Que o conteúdo do chart é seguro ou bem mantido&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Official&lt;/td&gt;
&lt;td&gt;O publicador é o dono do software empacotado&lt;/td&gt;
&lt;td&gt;Ausência de vulnerabilidades nas imagens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security report&lt;/td&gt;
&lt;td&gt;Resultado do scan com Trivy nas imagens listadas no pacote&lt;/td&gt;
&lt;td&gt;Cobertura de imagens não declaradas ou de vulnerabilidades ainda desconhecidas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Signed&lt;/td&gt;
&lt;td&gt;O pacote tem assinatura verificável (provenance do Helm; em alguns tipos, Cosign)&lt;/td&gt;
&lt;td&gt;Que a chave de assinatura é confiável para você&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stars e uso&lt;/td&gt;
&lt;td&gt;Popularidade entre usuários&lt;/td&gt;
&lt;td&gt;Qualidade ou segurança&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Boas práticas para quem consome:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trate o security report como triagem, não como aprovação. Reescaneie as imagens no seu pipeline com o scanner que sua empresa adota.&lt;/li&gt;
&lt;li&gt;Fixe versões de chart e de imagem (de preferência por digest) e revise o &lt;code&gt;helm template&lt;/code&gt; antes de atualizar.&lt;/li&gt;
&lt;li&gt;Prefira publishers verificados e oficiais, e desconfie de pacotes sem manutenção recente.&lt;/li&gt;
&lt;li&gt;Verifique assinaturas quando disponíveis e imponha isso por política (Kyverno ou Gatekeeper no cluster).&lt;/li&gt;
&lt;li&gt;Mantenha um mirror interno para charts críticos, para não depender da disponibilidade do repositório de origem.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Self-hosting e API
&lt;/h2&gt;

&lt;p&gt;Como o projeto é de código aberto, você pode rodar sua própria instância do Artifact Hub, por exemplo para catalogar apenas charts internos e aprovados. O repositório oficial inclui um chart Helm para instalar a aplicação.&lt;/p&gt;

&lt;p&gt;O que você precisa preparar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PostgreSQL&lt;/strong&gt; como banco de dados principal, com as migrações aplicadas pelo próprio chart.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Servidor SMTP&lt;/strong&gt;, se quiser notificações por e-mail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Autenticação&lt;/strong&gt;: contas locais ou provedores OAuth/OIDC, conforme a configuração.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repositórios privados&lt;/strong&gt;: repositórios com autenticação podem ser registrados informando credenciais, o que torna a instância útil como portal interno.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A configuração fica em um arquivo de valores do chart; consulte o guia de instalação na documentação oficial, porque as opções mudam entre versões.&lt;/p&gt;

&lt;p&gt;A API REST (pública em artifacthub.io e idêntica na instância própria) permite integrar o catálogo a outras ferramentas: buscar pacotes, obter detalhes de uma versão, ler o security report e listar repositórios. Alguns usos comuns em plataformas internas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Um bot que avisa no Slack quando um chart usado pela empresa publica versão com correção de segurança.&lt;/li&gt;
&lt;li&gt;Um job de CI que consulta a última versão estável de um chart e abre um pull request de atualização.&lt;/li&gt;
&lt;li&gt;Um portal de desenvolvedores (como o Backstage) que mostra o catálogo aprovado da empresa.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Limitações, alternativas e boas práticas
&lt;/h2&gt;

&lt;p&gt;O Artifact Hub é excelente para descoberta, mas não resolve sozinho a governança de pacotes de uma empresa.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Limitações a ter em mente&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Qualidade desigual: qualquer pessoa pode registrar um repositório, e a listagem não implica revisão.&lt;/li&gt;
&lt;li&gt;Metadados dependem do publisher: sem annotations, a página fica pobre e o scan de segurança pode ficar incompleto.&lt;/li&gt;
&lt;li&gt;Há atraso entre a publicação de uma versão e sua aparição no catálogo, porque o tracker roda periodicamente.&lt;/li&gt;
&lt;li&gt;É um catálogo: disponibilidade e integridade dos artefatos continuam sendo responsabilidade do repositório de origem.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Alternativas e complementos&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Ferramenta&lt;/th&gt;
&lt;th&gt;Papel&lt;/th&gt;
&lt;th&gt;Quando usar&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Registries OCI privados (Harbor, ECR, GHCR)&lt;/td&gt;
&lt;td&gt;Armazenar charts e imagens com controle de acesso&lt;/td&gt;
&lt;td&gt;Fonte de verdade interna e mirror de pacotes externos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OperatorHub.io&lt;/td&gt;
&lt;td&gt;Catálogo focado em operadores&lt;/td&gt;
&lt;td&gt;Descobrir operadores OLM (que também aparecem no Artifact Hub)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker Hub&lt;/td&gt;
&lt;td&gt;Catálogo e registry de imagens&lt;/td&gt;
&lt;td&gt;Descobrir imagens, não pacotes Kubernetes completos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Artifact Hub próprio&lt;/td&gt;
&lt;td&gt;Catálogo interno com repositórios privados&lt;/td&gt;
&lt;td&gt;Portal de pacotes aprovados pela empresa&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Boas práticas para times de plataforma&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use o Artifact Hub público para &lt;em&gt;descobrir e avaliar&lt;/em&gt;, e um registry interno para &lt;em&gt;consumir&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Defina critérios mínimos de aceite: publisher verificado, manutenção recente, licença compatível e scan sem vulnerabilidades críticas sem correção.&lt;/li&gt;
&lt;li&gt;Faça o mirror dos charts aprovados e aponte o GitOps (Argo CD ou Flux) para o mirror.&lt;/li&gt;
&lt;li&gt;Assine seus próprios charts e imagens e verifique as assinaturas no admission controller.&lt;/li&gt;
&lt;li&gt;Se publica pacotes, mantenha changelog, annotations e &lt;code&gt;ah lint&lt;/code&gt; no CI, tratando a página do Artifact Hub como a vitrine do seu produto.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;O Artifact Hub é a porta de entrada mais prática para o ecossistema de pacotes do Kubernetes: reúne Helm charts, operadores, políticas e plugins num só lugar, com sinais de confiança e segurança visíveis. O cuidado essencial é lembrar que ele cataloga e não garante: a decisão de adotar um pacote continua sendo do seu time.&lt;/p&gt;

&lt;p&gt;Como próximos passos, escolha um chart que sua equipe já usa e avalie a página dele pelos critérios deste artigo. Se você publica pacotes, registre seu repositório, adicione o &lt;code&gt;artifacthub-repo.yml&lt;/code&gt; e as annotations, e rode o &lt;code&gt;ah lint&lt;/code&gt; no CI. Para plataformas internas, considere uma instância própria combinada a um registry privado como fonte de verdade.&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>devops</category>
      <category>kubernetes</category>
      <category>software</category>
    </item>
    <item>
      <title>Argo CD a fundo como funciona o GitOps na prática</title>
      <dc:creator>Kauê Matos</dc:creator>
      <pubDate>Sat, 03 Oct 2026 19:01:42 +0000</pubDate>
      <link>https://dev.to/ikauedev/argo-cd-a-fundo-como-funciona-o-gitops-na-pratica-3onj</link>
      <guid>https://dev.to/ikauedev/argo-cd-a-fundo-como-funciona-o-gitops-na-pratica-3onj</guid>
      <description>&lt;p&gt;O Argo CD resolve um problema simples e caro: garantir que o que está rodando no Kubernetes é exatamente o que está versionado no Git. Ele é um controlador declarativo de entrega contínua (CD) para Kubernetes, mantido pela comunidade Argo e projeto graduado da CNCF.&lt;/p&gt;

&lt;p&gt;Sem uma ferramenta assim, o fluxo típico é um pipeline de CI que termina com &lt;code&gt;kubectl apply&lt;/code&gt; ou &lt;code&gt;helm upgrade&lt;/code&gt; contra o cluster. Isso funciona até o dia em que alguém altera um recurso na mão, o pipeline falha pela metade ou o cluster perde o estado e ninguém sabe qual era a versão "correta". É o chamado &lt;em&gt;configuration drift&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Neste artigo você vai ver:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;o que é GitOps e por que o modelo &lt;em&gt;pull&lt;/em&gt; muda o jogo;&lt;/li&gt;
&lt;li&gt;como o Argo CD é construído por dentro, componente por componente;&lt;/li&gt;
&lt;li&gt;o ciclo de reconciliação, do commit até o recurso saudável no cluster;&lt;/li&gt;
&lt;li&gt;os recursos principais (&lt;code&gt;Application&lt;/code&gt;, &lt;code&gt;AppProject&lt;/code&gt;, &lt;code&gt;ApplicationSet&lt;/code&gt;) com exemplos em YAML;&lt;/li&gt;
&lt;li&gt;sync policies, waves e hooks para controlar a ordem do deploy;&lt;/li&gt;
&lt;li&gt;multi-cluster, segurança, escala e observabilidade;&lt;/li&gt;
&lt;li&gt;um comparativo com Flux e com pipelines &lt;em&gt;push&lt;/em&gt;, e um exemplo prático do zero.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  GitOps em poucas palavras
&lt;/h2&gt;

&lt;p&gt;GitOps é tratar o Git como a única fonte de verdade do estado desejado da infraestrutura e das aplicações, e deixar um agente dentro do cluster trazer a realidade até esse estado. O Argo CD é uma implementação desse agente.&lt;/p&gt;

&lt;p&gt;Os quatro princípios, resumidos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Declarativo&lt;/strong&gt;: o sistema inteiro é descrito em manifestos (YAML, Helm, Kustomize), não em scripts de passo a passo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Versionado e imutável&lt;/strong&gt;: cada mudança é um commit, com autor, revisão por pull request e histórico para auditoria.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aplicado automaticamente&lt;/strong&gt;: um agente puxa o estado aprovado, sem que alguém precise rodar comandos contra o cluster.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reconciliado continuamente&lt;/strong&gt;: se o estado real divergir do desejado, o agente detecta e corrige (ou ao menos avisa).&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Push versus pull
&lt;/h3&gt;

&lt;p&gt;A diferença central está em quem tem a credencial do cluster. No modelo &lt;em&gt;push&lt;/em&gt;, o pipeline de CI fica de fora e precisa de acesso administrativo ao cluster para aplicar mudanças. No modelo &lt;em&gt;pull&lt;/em&gt;, o agente já está dentro do cluster e só precisa de permissão de &lt;strong&gt;leitura&lt;/strong&gt; no repositório Git.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspecto&lt;/th&gt;
&lt;th&gt;Push (CI faz o deploy)&lt;/th&gt;
&lt;th&gt;Pull (Argo CD)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Credenciais do cluster&lt;/td&gt;
&lt;td&gt;Ficam no sistema de CI&lt;/td&gt;
&lt;td&gt;Ficam só dentro do cluster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Detecção de drift&lt;/td&gt;
&lt;td&gt;Não existe, só no próximo deploy&lt;/td&gt;
&lt;td&gt;Contínua&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rollback&lt;/td&gt;
&lt;td&gt;Reexecutar pipeline antigo&lt;/td&gt;
&lt;td&gt;Reverter o commit no Git&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quem aplica&lt;/td&gt;
&lt;td&gt;Job efêmero do pipeline&lt;/td&gt;
&lt;td&gt;Controlador sempre ativo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Superfície de ataque&lt;/td&gt;
&lt;td&gt;Maior (chave do cluster exposta ao CI)&lt;/td&gt;
&lt;td&gt;Menor&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Arquitetura: os componentes por dentro
&lt;/h2&gt;

&lt;p&gt;O Argo CD é um conjunto de serviços pequenos, cada um com uma responsabilidade, que rodam juntos em um namespace (normalmente &lt;code&gt;argocd&lt;/code&gt;) e conversam com o repositório Git e com os clusters de destino.&lt;/p&gt;

&lt;p&gt;[embedded content: arquitetura do Argo CD · 7 componentes e 2 sistemas externos]&lt;/p&gt;

&lt;p&gt;O caminho principal é este: o &lt;strong&gt;Application Controller&lt;/strong&gt; pede ao &lt;strong&gt;Repo Server&lt;/strong&gt; os manifestos renderizados a partir do Git, compara com o que existe no cluster e aplica a diferença. O &lt;strong&gt;API Server&lt;/strong&gt; serve a interface, a CLI e a API, e delega o login ao &lt;strong&gt;Dex&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Componente&lt;/th&gt;
&lt;th&gt;Workload padrão&lt;/th&gt;
&lt;th&gt;Responsabilidade&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;argocd-server&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Deployment&lt;/td&gt;
&lt;td&gt;Expõe a UI, a CLI e a API; aplica RBAC e valida tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;argocd-repo-server&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Deployment&lt;/td&gt;
&lt;td&gt;Mantém clones locais dos repositórios e gera os manifestos finais (Helm, Kustomize, plugins)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;argocd-application-controller&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;StatefulSet&lt;/td&gt;
&lt;td&gt;Observa as aplicações e o cluster, calcula o diff, executa a sincronização e avalia a saúde dos recursos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;argocd-redis&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Deployment&lt;/td&gt;
&lt;td&gt;Cache do estado dos recursos e dos manifestos renderizados, para reduzir leituras no Git e na API do Kubernetes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;argocd-dex-server&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Deployment&lt;/td&gt;
&lt;td&gt;Intermedia o login com provedores de identidade externos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;argocd-applicationset-controller&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Deployment&lt;/td&gt;
&lt;td&gt;Gera e mantém objetos &lt;code&gt;Application&lt;/code&gt; a partir de &lt;code&gt;ApplicationSet&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;argocd-notifications-controller&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Deployment&lt;/td&gt;
&lt;td&gt;Envia alertas quando uma aplicação muda de estado&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Uma consequência importante do desenho: o Repo Server só &lt;strong&gt;gera&lt;/strong&gt; manifestos, e quem toca nos clusters é o Application Controller. Isso permite escalar cada parte separadamente e limitar o que cada uma enxerga.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ciclo de reconciliação: do commit ao cluster
&lt;/h2&gt;

&lt;p&gt;A cada ciclo, o Argo CD compara o Git com o cluster antes de aplicar qualquer coisa, e só age quando encontra diferença e a política permite.&lt;/p&gt;

&lt;p&gt;[embedded content: ciclo de reconciliação · 6 etapas e 2 decisões]&lt;/p&gt;

&lt;p&gt;Há duas formas de o Argo CD descobrir que algo mudou. A primeira é o &lt;em&gt;polling&lt;/em&gt; do repositório, a cada 3 minutos por padrão. A segunda é um &lt;em&gt;webhook&lt;/em&gt; (GitHub, GitLab, Bitbucket e outros), que avisa na hora e dispensa a espera. Mudanças feitas direto no cluster são percebidas de outro jeito: o Application Controller observa os recursos vivos continuamente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dois eixos de status
&lt;/h3&gt;

&lt;p&gt;Na interface aparecem dois status independentes, e confundi-los é um erro comum.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Eixo&lt;/th&gt;
&lt;th&gt;Pergunta que responde&lt;/th&gt;
&lt;th&gt;Valores principais&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sync status&lt;/td&gt;
&lt;td&gt;O cluster está igual ao Git?&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Synced&lt;/code&gt;, &lt;code&gt;OutOfSync&lt;/code&gt;, &lt;code&gt;Unknown&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Health status&lt;/td&gt;
&lt;td&gt;Os recursos estão funcionando?&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Healthy&lt;/code&gt;, &lt;code&gt;Progressing&lt;/code&gt;, &lt;code&gt;Degraded&lt;/code&gt;, &lt;code&gt;Suspended&lt;/code&gt;, &lt;code&gt;Missing&lt;/code&gt;, &lt;code&gt;Unknown&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Uma aplicação pode estar &lt;code&gt;Synced&lt;/code&gt; e &lt;code&gt;Degraded&lt;/code&gt; ao mesmo tempo: o manifesto foi aplicado exatamente como está no Git, mas o Pod não sobe. O contrário também vale, com &lt;code&gt;OutOfSync&lt;/code&gt; e &lt;code&gt;Healthy&lt;/code&gt;, quando alguém alterou algo à mão e o serviço continua funcionando.&lt;/p&gt;

&lt;p&gt;O Argo CD sabe avaliar a saúde de recursos nativos (Deployment, StatefulSet, Ingress, Job e outros). Para CRDs, é possível escrever uma verificação de saúde customizada em Lua.&lt;/p&gt;

&lt;p&gt;Para ver a diferença antes de sincronizar, use &lt;code&gt;argocd app diff &amp;lt;aplicação&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recursos principais: Application, AppProject e ApplicationSet
&lt;/h2&gt;

&lt;p&gt;O Argo CD é configurado por CRDs do próprio Kubernetes, então a configuração do Argo CD também pode (e deve) viver no Git. Três recursos cobrem quase todo o uso.&lt;/p&gt;

&lt;h3&gt;
  
  
  Application
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;Application&lt;/code&gt; liga uma &lt;strong&gt;origem&lt;/strong&gt; (repositório, revisão e caminho) a um &lt;strong&gt;destino&lt;/strong&gt; (cluster e namespace). É a unidade que o Argo CD sincroniza e cujo status ele mostra.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;argoproj.io/v1alpha1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Application&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;loja-api&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;argocd&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;project&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;loja&lt;/span&gt;
  &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;repoURL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/minha-org/loja-gitops.git&lt;/span&gt;
    &lt;span class="na"&gt;targetRevision&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/api/overlays/producao&lt;/span&gt;
  &lt;span class="na"&gt;destination&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://kubernetes.default.svc&lt;/span&gt;
    &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;loja&lt;/span&gt;
  &lt;span class="na"&gt;syncPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;automated&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;prune&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;selfHeal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;syncOptions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;CreateNamespace=true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O campo &lt;code&gt;path&lt;/code&gt; pode apontar para YAML puro, um chart Helm, uma pasta Kustomize ou um plugin de geração de manifestos.&lt;/p&gt;

&lt;h3&gt;
  
  
  AppProject
&lt;/h3&gt;

&lt;p&gt;O &lt;code&gt;AppProject&lt;/code&gt; é a fronteira de segurança e de organização. Ele define de quais repositórios um grupo de aplicações pode ler, para quais clusters e namespaces pode implantar e quais tipos de recurso são permitidos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;argoproj.io/v1alpha1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AppProject&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;loja&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;argocd&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;sourceRepos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;https://github.com/minha-org/loja-gitops.git&lt;/span&gt;
  &lt;span class="na"&gt;destinations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://kubernetes.default.svc&lt;/span&gt;
      &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;loja&lt;/span&gt;
  &lt;span class="na"&gt;clusterResourceWhitelist&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;namespaceResourceBlacklist&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
      &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ResourceQuota&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com &lt;code&gt;clusterResourceWhitelist&lt;/code&gt; vazio, o time dono do projeto não consegue criar recursos de escopo de cluster (como &lt;code&gt;ClusterRole&lt;/code&gt;), mesmo que escreva isso no repositório.&lt;/p&gt;

&lt;h3&gt;
  
  
  ApplicationSet
&lt;/h3&gt;

&lt;p&gt;O &lt;code&gt;ApplicationSet&lt;/code&gt; gera várias &lt;code&gt;Application&lt;/code&gt; a partir de um modelo e de &lt;em&gt;generators&lt;/em&gt;. É a resposta para "preciso da mesma aplicação em 30 clusters" ou "uma aplicação por pasta do repositório".&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Generator&lt;/th&gt;
&lt;th&gt;O que ele faz&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;List&lt;/td&gt;
&lt;td&gt;Itera sobre uma lista fixa de valores&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cluster&lt;/td&gt;
&lt;td&gt;Gera uma aplicação por cluster cadastrado no Argo CD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Git (diretórios)&lt;/td&gt;
&lt;td&gt;Gera uma aplicação por pasta encontrada no repositório&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Git (arquivos)&lt;/td&gt;
&lt;td&gt;Lê arquivos JSON/YAML e usa o conteúdo como parâmetros&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pull Request&lt;/td&gt;
&lt;td&gt;Cria um ambiente efêmero por pull request aberto&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Matrix / Merge&lt;/td&gt;
&lt;td&gt;Combina dois generators (por exemplo, cluster × diretório)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;argoproj.io/v1alpha1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ApplicationSet&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;servicos&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;argocd&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;generators&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;git&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;repoURL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/minha-org/loja-gitops.git&lt;/span&gt;
        &lt;span class="na"&gt;revision&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
        &lt;span class="na"&gt;directories&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/*&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{path.basename}}"&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;project&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;loja&lt;/span&gt;
      &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;repoURL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/minha-org/loja-gitops.git&lt;/span&gt;
        &lt;span class="na"&gt;targetRevision&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{path}}"&lt;/span&gt;
      &lt;span class="na"&gt;destination&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://kubernetes.default.svc&lt;/span&gt;
        &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{{path.basename}}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com isso, criar uma nova pasta em &lt;code&gt;apps/&lt;/code&gt; basta para que uma nova aplicação apareça no Argo CD, sem tocar em nenhum outro arquivo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sync policies, waves e hooks
&lt;/h2&gt;

&lt;p&gt;Por padrão a sincronização é manual: o Argo CD mostra &lt;code&gt;OutOfSync&lt;/code&gt; e espera alguém clicar em &lt;em&gt;Sync&lt;/em&gt;. Três mecanismos controlam o quanto disso é automático e em que ordem as coisas acontecem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Política de sincronização automática
&lt;/h3&gt;

&lt;p&gt;Quando &lt;code&gt;syncPolicy.automated&lt;/code&gt; está ativo, o Argo CD aplica sozinho qualquer diferença entre o Git e o cluster. Duas opções mudam bastante o comportamento:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;prune: true&lt;/code&gt;&lt;/strong&gt;: remove do cluster recursos que foram apagados do Git. Sem isso, o que sai do repositório continua rodando.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;selfHeal: true&lt;/code&gt;&lt;/strong&gt;: desfaz alterações feitas diretamente no cluster (por exemplo, um &lt;code&gt;kubectl edit&lt;/code&gt; em um Deployment) e volta ao estado do Git.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Outras opções úteis ficam em &lt;code&gt;syncOptions&lt;/code&gt;, como &lt;code&gt;CreateNamespace=true&lt;/code&gt;, &lt;code&gt;ServerSideApply=true&lt;/code&gt; e &lt;code&gt;PruneLast=true&lt;/code&gt;. Há também &lt;code&gt;retry&lt;/code&gt;, com &lt;em&gt;backoff&lt;/em&gt; exponencial, para tentar de novo quando uma sincronização falha por motivo transitório.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sync waves
&lt;/h3&gt;

&lt;p&gt;Os recursos de uma aplicação são aplicados em ordem de &lt;em&gt;wave&lt;/em&gt;, definida pela anotação &lt;code&gt;argocd.argoproj.io/sync-wave&lt;/code&gt;. O padrão é 0, valores menores vêm antes e valores negativos são permitidos. O Argo CD só avança para a próxima wave quando todos os recursos da atual estão saudáveis.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;argocd.argoproj.io/sync-wave&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-1"&lt;/span&gt;   &lt;span class="c1"&gt;# roda antes dos recursos da wave 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Um uso típico: &lt;code&gt;Namespace&lt;/code&gt; e &lt;code&gt;CRD&lt;/code&gt; na wave -2, &lt;code&gt;ConfigMap&lt;/code&gt; e &lt;code&gt;Secret&lt;/code&gt; na wave -1, o &lt;code&gt;Deployment&lt;/code&gt; na wave 0 e um &lt;code&gt;Ingress&lt;/code&gt; na wave 1.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hooks
&lt;/h3&gt;

&lt;p&gt;Hooks são recursos (normalmente &lt;code&gt;Job&lt;/code&gt;) que rodam em fases específicas da sincronização, marcados com a anotação &lt;code&gt;argocd.argoproj.io/hook&lt;/code&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hook&lt;/th&gt;
&lt;th&gt;Quando roda&lt;/th&gt;
&lt;th&gt;Uso comum&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PreSync&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Antes de aplicar os manifestos&lt;/td&gt;
&lt;td&gt;Migração de banco de dados&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Sync&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Junto com a aplicação dos manifestos&lt;/td&gt;
&lt;td&gt;Passos que dependem da ordem das waves&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PostSync&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Depois que tudo ficou saudável&lt;/td&gt;
&lt;td&gt;Teste de fumaça, notificação&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SyncFail&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Quando a sincronização falha&lt;/td&gt;
&lt;td&gt;Limpeza, alerta&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A anotação &lt;code&gt;argocd.argoproj.io/hook-delete-policy&lt;/code&gt; define quando o &lt;code&gt;Job&lt;/code&gt; é apagado (&lt;code&gt;HookSucceeded&lt;/code&gt;, &lt;code&gt;HookFailed&lt;/code&gt; ou &lt;code&gt;BeforeHookCreation&lt;/code&gt;). Se um &lt;code&gt;PreSync&lt;/code&gt; falhar, a sincronização é interrompida e os manifestos principais não são aplicados, o que protege contra subir uma versão nova com o banco no estado antigo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multi-cluster, RBAC, SSO e segurança
&lt;/h2&gt;

&lt;p&gt;Uma única instância do Argo CD pode gerenciar vários clusters, e é isso que o torna útil em empresas com ambientes separados para desenvolvimento, homologação e produção.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-cluster
&lt;/h3&gt;

&lt;p&gt;O cluster onde o Argo CD roda se chama &lt;code&gt;in-cluster&lt;/code&gt; (&lt;code&gt;https://kubernetes.default.svc&lt;/code&gt;). Para adicionar outros, usa-se &lt;code&gt;argocd cluster add &amp;lt;contexto&amp;gt;&lt;/code&gt;, que cria uma &lt;code&gt;ServiceAccount&lt;/code&gt; no cluster remoto e guarda o token em um &lt;code&gt;Secret&lt;/code&gt; no namespace &lt;code&gt;argocd&lt;/code&gt;. Há dois desenhos comuns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hub e spokes&lt;/strong&gt;: um Argo CD central gerencia todos os clusters. É mais simples de operar, mas esse cluster central passa a guardar credenciais de todos os outros e vira um alvo importante.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uma instância por cluster (ou por ambiente)&lt;/strong&gt;: cada Argo CD gerencia só o próprio cluster. Isola o impacto de uma falha ou invasão, ao custo de operar várias instâncias.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  RBAC e SSO
&lt;/h3&gt;

&lt;p&gt;A autenticação delega para um provedor externo via &lt;strong&gt;Dex&lt;/strong&gt; (embutido) ou OIDC direto, com suporte a GitHub, GitLab, Google, Okta, Azure AD, Keycloak e LDAP. A autorização usa uma política no estilo Casbin, no &lt;code&gt;ConfigMap&lt;/code&gt; &lt;code&gt;argocd-rbac-cm&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;p, role:dev-loja, applications, get, loja/*, allow
p, role:dev-loja, applications, sync, loja/*, allow
g, grupo-loja-devs, role:dev-loja
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As linhas &lt;code&gt;p&lt;/code&gt; definem permissões (papel, recurso, ação, objeto) e as linhas &lt;code&gt;g&lt;/code&gt; ligam grupos do provedor de identidade a papéis. O objeto &lt;code&gt;loja/*&lt;/code&gt; restringe o acesso às aplicações do projeto &lt;code&gt;loja&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Segredos
&lt;/h3&gt;

&lt;p&gt;O Argo CD &lt;strong&gt;não&lt;/strong&gt; resolve o problema de guardar segredos no Git, ele só aplica o que está lá. Como &lt;code&gt;Secret&lt;/code&gt; do Kubernetes é apenas Base64, as abordagens mais comuns são:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Abordagem&lt;/th&gt;
&lt;th&gt;Como funciona&lt;/th&gt;
&lt;th&gt;Observação&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sealed Secrets&lt;/td&gt;
&lt;td&gt;O segredo é cifrado com a chave pública de um controlador e só o cluster consegue abrir&lt;/td&gt;
&lt;td&gt;Cifrado no próprio Git&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;External Secrets Operator&lt;/td&gt;
&lt;td&gt;O Git guarda só a referência; o operador busca o valor no AWS Secrets Manager, Vault etc.&lt;/td&gt;
&lt;td&gt;Nenhum valor no Git&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SOPS com plugin&lt;/td&gt;
&lt;td&gt;Arquivos cifrados com KMS ou age, decifrados na hora de gerar manifestos&lt;/td&gt;
&lt;td&gt;Exige configurar o repo server&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Outros cuidados
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;AppProject&lt;/code&gt; para restringir repositórios, destinos e tipos de recurso por time.&lt;/li&gt;
&lt;li&gt;Desative o usuário &lt;code&gt;admin&lt;/code&gt; local depois de configurar o SSO.&lt;/li&gt;
&lt;li&gt;Use um repositório de leitura (deploy key ou token só de leitura) para o Argo CD.&lt;/li&gt;
&lt;li&gt;Habilite TLS no &lt;code&gt;argocd-server&lt;/code&gt; e limite o acesso à API por rede, já que ele tem poder sobre todos os clusters conectados.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Escala, alta disponibilidade e observabilidade
&lt;/h2&gt;

&lt;p&gt;O Argo CD é em grande parte &lt;em&gt;stateless&lt;/em&gt;: o estado vive em objetos do Kubernetes, e o que pesa quando a escala cresce é o Application Controller, que mantém em memória o estado dos clusters que gerencia (&lt;a href="https://argo-cd.readthedocs.io/en/stable/operator-manual/high_availability/" rel="noopener noreferrer"&gt;documentação de alta disponibilidade&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;[embedded content: sharding de clusters no Application Controller · exemplo ilustrativo]&lt;/p&gt;

&lt;h3&gt;
  
  
  Onde ajustar cada componente
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Application Controller&lt;/strong&gt;: quando ele gerencia muitos clusters e consome muita memória, o caminho é distribuir os clusters entre réplicas. Aumente &lt;code&gt;replicas&lt;/code&gt; no StatefulSet e repita o número na variável &lt;code&gt;ARGOCD_CONTROLLER_REPLICAS&lt;/code&gt;. Cada réplica usa duas filas, uma para reconciliação (milissegundos) e outra para sincronização (segundos), e o número de &lt;em&gt;processors&lt;/em&gt; pode ser aumentado para muitas aplicações.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repo Server&lt;/strong&gt;: guarda em cache os manifestos gerados, por padrão por 24 horas, usando o SHA do commit como chave. Ele mantém um clone local por repositório, o que pode ficar lento em monorepos com muitas aplicações; a anotação &lt;code&gt;argocd.argoproj.io/manifest-generate-paths&lt;/code&gt; ajuda a evitar regenerar manifestos à toa.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Server e Redis&lt;/strong&gt;: o projeto oferece manifests de alta disponibilidade, com réplicas do servidor e uma variante de Redis em HA.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Em uso real, a pesquisa de 2025 com usuários do Argo CD, conduzida pela CNCF e pelos mantenedores, reportou que &lt;a href="https://x.com/CloudNativeFdn/status/1948444518048563269" rel="noopener noreferrer"&gt;97% usam em produção e 42% gerenciam mais de 500 aplicações por instância&lt;/a&gt;, e que &lt;a href="https://www.cncf.io/announcements/2025/07/24/cncf-end-user-survey-finds-argo-cd-as-majority-adopted-gitops-solution-for-kubernetes/" rel="noopener noreferrer"&gt;quase 60% dos clusters dos respondentes&lt;/a&gt; usam Argo CD.&lt;/p&gt;

&lt;h3&gt;
  
  
  Observabilidade
&lt;/h3&gt;

&lt;p&gt;Cada componente expõe métricas no formato Prometheus. Três delas cobrem a maior parte dos painéis e alertas:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Métrica&lt;/th&gt;
&lt;th&gt;O que mostra&lt;/th&gt;
&lt;th&gt;Uso típico&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;argocd_app_info&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Status de sync e de saúde de cada aplicação&lt;/td&gt;
&lt;td&gt;Alerta para aplicações &lt;code&gt;OutOfSync&lt;/code&gt; ou &lt;code&gt;Degraded&lt;/code&gt; por muito tempo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;argocd_app_sync_total&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Quantidade de sincronizações e seus resultados&lt;/td&gt;
&lt;td&gt;Taxa de falha de deploy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;argocd_app_reconcile&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Duração da reconciliação das aplicações&lt;/td&gt;
&lt;td&gt;Mapa de calor para detectar controller sobrecarregado&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Além das métricas, o Argo CD Notifications envia o evento a Slack, e-mail ou webhook no momento em que a saúde muda ou a sincronização falha.&lt;/p&gt;

&lt;h2&gt;
  
  
  Argo CD, Flux e pipeline push: como se comparam
&lt;/h2&gt;

&lt;p&gt;Argo CD e Flux são projetos graduados da CNCF que seguem o mesmo modelo &lt;em&gt;pull&lt;/em&gt;. A escolha costuma depender do que a equipe valoriza: uma plataforma integrada com interface web (Argo CD) ou um conjunto modular de controllers guiado por linha de comando (Flux), como resume &lt;a href="https://thenewstack.io/survey-argocd-leaves-flux-and-other-gitops-platforms-behind/" rel="noopener noreferrer"&gt;a matéria do The New Stack&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;[embedded content: The New Stack, jun/2025 · Octopus Deploy (State of GitOps) e pesquisa da CNCF]&lt;/p&gt;

&lt;p&gt;O desnível aparece nas duas pesquisas, mas o valor exato depende de quem foi perguntado e de como a pergunta foi feita.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspecto&lt;/th&gt;
&lt;th&gt;Argo CD&lt;/th&gt;
&lt;th&gt;Flux&lt;/th&gt;
&lt;th&gt;Pipeline push (CI)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Modelo de entrega&lt;/td&gt;
&lt;td&gt;Pull, por um controlador no cluster&lt;/td&gt;
&lt;td&gt;Pull, por controllers no cluster&lt;/td&gt;
&lt;td&gt;Push, o CI aplica no cluster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Interface web&lt;/td&gt;
&lt;td&gt;Embutida&lt;/td&gt;
&lt;td&gt;Sem UI embutida&lt;/td&gt;
&lt;td&gt;Depende do CI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arquitetura&lt;/td&gt;
&lt;td&gt;Plataforma integrada; instância central ou uma por cluster&lt;/td&gt;
&lt;td&gt;Conjunto de controllers independentes&lt;/td&gt;
&lt;td&gt;Job efêmero a cada pipeline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-cluster&lt;/td&gt;
&lt;td&gt;Clusters registrados e &lt;code&gt;ApplicationSet&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Repositório organizado e um Flux em cada cluster&lt;/td&gt;
&lt;td&gt;Credencial de cada cluster guardada no CI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Segredos&lt;/td&gt;
&lt;td&gt;Via ferramentas externas&lt;/td&gt;
&lt;td&gt;Suporte nativo a SOPS&lt;/td&gt;
&lt;td&gt;Segredos do próprio CI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Detecção de drift&lt;/td&gt;
&lt;td&gt;Contínua&lt;/td&gt;
&lt;td&gt;Contínua&lt;/td&gt;
&lt;td&gt;Só no próximo deploy&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Um pipeline &lt;em&gt;push&lt;/em&gt; costuma bastar para projetos pequenos, com um ou dois ambientes. O GitOps começa a compensar quando surgem vários clusters, vários times e a necessidade de auditoria e de detectar &lt;em&gt;drift&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exemplo prático: do zero à primeira aplicação
&lt;/h2&gt;

&lt;p&gt;O roteiro abaixo leva cerca de dez minutos em um cluster de testes (kind, minikube ou um cluster gerenciado).&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Instalar o Argo CD
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create namespace argocd
kubectl apply &lt;span class="nt"&gt;-n&lt;/span&gt; argocd &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em produção, prefira o chart Helm oficial (&lt;code&gt;argo/argo-cd&lt;/code&gt;) com os valores versionados no Git, e fixe a versão em vez de usar &lt;code&gt;stable&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Acessar a interface e a CLI
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# senha inicial do usuário admin&lt;/span&gt;
kubectl &lt;span class="nt"&gt;-n&lt;/span&gt; argocd get secret argocd-initial-admin-secret &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"{.data.password}"&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;

&lt;span class="c"&gt;# encaminhar a porta do servidor&lt;/span&gt;
kubectl port-forward svc/argocd-server &lt;span class="nt"&gt;-n&lt;/span&gt; argocd 8080:443

&lt;span class="c"&gt;# login pela CLI&lt;/span&gt;
argocd login localhost:8080 &lt;span class="nt"&gt;--username&lt;/span&gt; admin &lt;span class="nt"&gt;--insecure&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Organizar o repositório
&lt;/h3&gt;

&lt;p&gt;Uma estrutura simples e muito usada separa a base dos ambientes com Kustomize:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;loja-gitops/
├── apps/
│   └── api/
│       ├── base/
│       │   ├── deployment.yaml
│       │   ├── service.yaml
│       │   └── kustomization.yaml
│       └── overlays/
│           ├── homologacao/
│           │   └── kustomization.yaml
│           └── producao/
│               └── kustomization.yaml
└── argocd/
    └── applications/
        └── loja-api-producao.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Criar a aplicação
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;argocd app create loja-api &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--repo&lt;/span&gt; https://github.com/minha-org/loja-gitops.git &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--path&lt;/span&gt; apps/api/overlays/producao &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--dest-server&lt;/span&gt; https://kubernetes.default.svc &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--dest-namespace&lt;/span&gt; loja &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sync-policy&lt;/span&gt; automated &lt;span class="nt"&gt;--auto-prune&lt;/span&gt; &lt;span class="nt"&gt;--self-heal&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O mesmo resultado sai de aplicar o YAML da &lt;code&gt;Application&lt;/code&gt; mostrado antes, que é a forma recomendada porque fica versionada.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Ver a reconciliação funcionando
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Altere &lt;code&gt;replicas&lt;/code&gt; no &lt;code&gt;deployment.yaml&lt;/code&gt;, faça commit e push. Em poucos minutos (ou na hora, se houver webhook), a aplicação passa a &lt;code&gt;OutOfSync&lt;/code&gt; e logo volta a &lt;code&gt;Synced&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Rode &lt;code&gt;kubectl scale deployment api -n loja --replicas=1&lt;/code&gt; na mão. Com &lt;code&gt;selfHeal&lt;/code&gt; ativo, o Argo CD desfaz a mudança e volta ao valor do Git.&lt;/li&gt;
&lt;li&gt;Apague o &lt;code&gt;service.yaml&lt;/code&gt; do repositório. Com &lt;code&gt;prune&lt;/code&gt; ativo, o Service é removido do cluster.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;argocd app history loja-api&lt;/code&gt; e &lt;code&gt;argocd app rollback loja-api &amp;lt;id&amp;gt;&lt;/code&gt; para voltar a uma revisão anterior. Em modo automático, o rollback pela CLI exige desativar a sincronização automática antes; o caminho mais limpo é um &lt;code&gt;git revert&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Boas práticas e armadilhas comuns
&lt;/h2&gt;

&lt;p&gt;A maior parte dos problemas com Argo CD vem de decisões de organização, não da ferramenta em si.&lt;/p&gt;

&lt;h3&gt;
  
  
  O que fazer
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Separe o repositório de código do repositório de configuração.&lt;/strong&gt; Um commit de código não deve disparar uma mudança de manifesto sem passar por um passo explícito (por exemplo, o CI atualiza a tag da imagem no repositório GitOps por pull request).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use o padrão &lt;em&gt;app of apps&lt;/em&gt; ou &lt;code&gt;ApplicationSet&lt;/code&gt;&lt;/strong&gt; para que a própria lista de aplicações esteja no Git, e não cadastrada à mão.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uma pasta por ambiente&lt;/strong&gt;, com Kustomize overlays ou arquivos de valores do Helm, em vez de branches por ambiente. Branches divergem e a promoção vira merge doloroso.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fixe versões&lt;/strong&gt;: tags de imagem imutáveis (nunca &lt;code&gt;latest&lt;/code&gt;), versões de chart e &lt;code&gt;targetRevision&lt;/code&gt; por tag ou SHA em produção.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatize com cuidado&lt;/strong&gt;: &lt;code&gt;automated&lt;/code&gt; em homologação quase sempre vale a pena; em produção, muitos times preferem sincronização automática com &lt;code&gt;prune&lt;/code&gt; e &lt;code&gt;selfHeal&lt;/code&gt;, mas com janelas de sincronização (&lt;em&gt;sync windows&lt;/em&gt;) e revisão obrigatória de pull request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ative notificações&lt;/strong&gt; (Argo CD Notifications) para Slack, e-mail ou webhook nos eventos de falha de sincronização e degradação de saúde.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Armadilhas
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Armadilha&lt;/th&gt;
&lt;th&gt;O que acontece&lt;/th&gt;
&lt;th&gt;Como evitar&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;HPA e &lt;code&gt;replicas&lt;/code&gt; fixo no Git&lt;/td&gt;
&lt;td&gt;O Argo CD e o autoscaler brigam pelo número de réplicas&lt;/td&gt;
&lt;td&gt;Remover &lt;code&gt;replicas&lt;/code&gt; do manifesto ou usar &lt;code&gt;ignoreDifferences&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Campos gerados por controladores&lt;/td&gt;
&lt;td&gt;Aplicação fica &lt;code&gt;OutOfSync&lt;/code&gt; para sempre por causa de campos que o cluster preenche&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ignoreDifferences&lt;/code&gt; ou &lt;code&gt;RespectIgnoreDifferences=true&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CRDs grandes&lt;/td&gt;
&lt;td&gt;Falha de &lt;code&gt;apply&lt;/code&gt; por limite da anotação &lt;code&gt;last-applied&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ServerSideApply=true&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Segredos em texto no Git&lt;/td&gt;
&lt;td&gt;Vazamento de credenciais&lt;/td&gt;
&lt;td&gt;Sealed Secrets, External Secrets ou SOPS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Um único repositório gigante&lt;/td&gt;
&lt;td&gt;Renderização lenta e cache do repo server sempre invalidado&lt;/td&gt;
&lt;td&gt;Dividir por domínio e usar anotação &lt;code&gt;manifest-generate-paths&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;prune&lt;/code&gt; sem entender o escopo&lt;/td&gt;
&lt;td&gt;Recursos apagados por engano&lt;/td&gt;
&lt;td&gt;Testar primeiro com &lt;code&gt;argocd app sync --dry-run&lt;/code&gt; e usar &lt;code&gt;Prune=false&lt;/code&gt; em recursos críticos&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Conclusão e próximos passos
&lt;/h2&gt;

&lt;p&gt;O Argo CD é um laço de controle: ele lê o estado desejado no Git, observa o estado real no cluster e fecha a diferença, com visibilidade, política e auditoria em volta disso. O ganho prático vem de três hábitos: tudo no Git, nada aplicado à mão e sincronização automática onde o risco permite.&lt;/p&gt;

&lt;p&gt;Para colocar em prática:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Suba o Argo CD em um cluster de testes e siga o exemplo prático deste artigo.&lt;/li&gt;
&lt;li&gt;Crie um &lt;code&gt;AppProject&lt;/code&gt; por time antes de liberar acesso, e configure SSO e RBAC no primeiro dia.&lt;/li&gt;
&lt;li&gt;Decida como os segredos serão tratados (Sealed Secrets, External Secrets ou SOPS) antes de migrar a primeira aplicação real.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;ApplicationSet&lt;/code&gt; para que a lista de aplicações também seja versionada.&lt;/li&gt;
&lt;li&gt;Ative métricas e notificações, e só depois habilite &lt;code&gt;selfHeal&lt;/code&gt; e &lt;code&gt;prune&lt;/code&gt; em produção.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>argocd</category>
      <category>kubernetes</category>
      <category>aws</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Instâncias AWS Graviton Arquitetura ARM na Nuvem</title>
      <dc:creator>Kauê Matos</dc:creator>
      <pubDate>Sun, 13 Sep 2026 17:04:17 +0000</pubDate>
      <link>https://dev.to/ikauedev/instancias-aws-graviton-instancias-aws-graviton-arquitetura-arm-na-nuvem-16d</link>
      <guid>https://dev.to/ikauedev/instancias-aws-graviton-instancias-aws-graviton-arquitetura-arm-na-nuvem-16d</guid>
      <description>&lt;p&gt;O &lt;strong&gt;AWS Graviton&lt;/strong&gt; é uma família de processadores desenvolvidos pela própria AWS, baseados em arquitetura &lt;strong&gt;ARM (64-bit, Arm Neoverse)&lt;/strong&gt;, em vez da arquitetura x86 tradicional (Intel/AMD). Lançado inicialmente em 2018, o Graviton se tornou uma das principais estratégias da AWS para oferecer melhor custo-benefício e eficiência energética em instâncias EC2.&lt;/p&gt;

&lt;p&gt;Hoje, praticamente todas as famílias de instância "de uso geral" da AWS (M, C, R, T e derivadas) possuem uma variante Graviton, identificada pelo sufixo &lt;strong&gt;g&lt;/strong&gt; no nome (ex.: &lt;code&gt;m7g&lt;/code&gt;, &lt;code&gt;c7g&lt;/code&gt;, &lt;code&gt;r7g&lt;/code&gt;, &lt;code&gt;t4g&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Este artigo explica o que é o Graviton, como evoluiu ao longo das gerações, quando vale a pena adotar e quais são os principais cuidados de migração.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é o Graviton
&lt;/h2&gt;

&lt;p&gt;Graviton é um &lt;strong&gt;System on Chip (SoC)&lt;/strong&gt; projetado pela AWS Annapurna Labs (empresa israelense adquirida pela AWS em 2015), otimizado especificamente para rodar dentro da infraestrutura da própria AWS. Diferente de depender de fornecedores externos (Intel, AMD), a AWS controla o design do chip ponta a ponta — o que permite ajustar a arquitetura ao perfil real de uso dos seus data centers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Principais vantagens declaradas pela AWS:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Melhor custo-benefício&lt;/strong&gt; — em geral, 20% a 40% mais barato que instâncias x86 equivalentes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Melhor performance por watt&lt;/strong&gt; — até ~60% mais eficiente energeticamente, o que também contribui para metas de sustentabilidade (ESG) das empresas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance competitiva ou superior&lt;/strong&gt; em cargas de trabalho compatíveis, especialmente as que escalam horizontalmente.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Evolução das gerações
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Graviton1 (2018)
&lt;/h3&gt;

&lt;p&gt;Primeira geração, lançada com as instâncias &lt;code&gt;a1&lt;/code&gt;. Voltada principalmente para cargas escaláveis horizontalmente e workloads que não exigiam alta performance de CPU por núcleo. Adoção limitada, mas serviu como prova de conceito.&lt;/p&gt;

&lt;h3&gt;
  
  
  Graviton2 (2019/2020)
&lt;/h3&gt;

&lt;p&gt;Salto significativo de performance — baseado em núcleos Arm Neoverse N1. Introduziu as variantes &lt;code&gt;g&lt;/code&gt; em famílias já conhecidas: &lt;code&gt;m6g&lt;/code&gt;, &lt;code&gt;c6g&lt;/code&gt;, &lt;code&gt;r6g&lt;/code&gt;, &lt;code&gt;t4g&lt;/code&gt;. Trouxe suporte a mais casos de uso de produção, com performance comparável a instâncias x86 de geração equivalente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Graviton3 (2021/2022)
&lt;/h3&gt;

&lt;p&gt;Presente em &lt;code&gt;m7g&lt;/code&gt;, &lt;code&gt;c7g&lt;/code&gt;, &lt;code&gt;r7g&lt;/code&gt;, além de instâncias especializadas como &lt;code&gt;c7gn&lt;/code&gt; (rede otimizada) e &lt;code&gt;hpc7g&lt;/code&gt; (HPC). Trouxe ganhos relevantes em:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Performance de ponto flutuante (importante para HPC e ML)&lt;/li&gt;
&lt;li&gt;Criptografia acelerada por hardware&lt;/li&gt;
&lt;li&gt;Maior largura de banda de memória (DDR5)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Graviton4 (2023/2024)
&lt;/h3&gt;

&lt;p&gt;Geração mais recente, presente em instâncias como &lt;code&gt;r8g&lt;/code&gt; e &lt;code&gt;m8g&lt;/code&gt;. Foco em maior número de núcleos, maior largura de banda de memória e melhorias de segurança, mantendo compatibilidade com o ecossistema ARM já validado nas gerações anteriores.&lt;/p&gt;

&lt;h2&gt;
  
  
  Famílias disponíveis com Graviton
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Família x86 equivalente&lt;/th&gt;
&lt;th&gt;Variante Graviton&lt;/th&gt;
&lt;th&gt;Foco&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;M (uso geral)&lt;/td&gt;
&lt;td&gt;m6g, m7g, m8g&lt;/td&gt;
&lt;td&gt;Aplicações web, microsserviços&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C (compute optimized)&lt;/td&gt;
&lt;td&gt;c6g, c7g, c7gn&lt;/td&gt;
&lt;td&gt;CPU intensiva, rede otimizada&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;R (memory optimized)&lt;/td&gt;
&lt;td&gt;r6g, r7g, r8g&lt;/td&gt;
&lt;td&gt;Bancos de dados, cache&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;T (burstable)&lt;/td&gt;
&lt;td&gt;t4g&lt;/td&gt;
&lt;td&gt;Cargas variáveis, dev/test&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;X (memória alta)&lt;/td&gt;
&lt;td&gt;x2gd&lt;/td&gt;
&lt;td&gt;In-memory databases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;I (storage optimized)&lt;/td&gt;
&lt;td&gt;i4g&lt;/td&gt;
&lt;td&gt;NoSQL, alta taxa de I/O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hpc&lt;/td&gt;
&lt;td&gt;hpc7g&lt;/td&gt;
&lt;td&gt;HPC fortemente acoplado&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Quando vale a pena migrar para Graviton
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Bons candidatos:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Aplicações &lt;strong&gt;stateless&lt;/strong&gt; rodando em containers (Docker/Kubernetes) com imagens multi-arquitetura.&lt;/li&gt;
&lt;li&gt;Linguagens/runtimes com suporte nativo e maduro a ARM: Java (JVM), Go, Python, Node.js, .NET.&lt;/li&gt;
&lt;li&gt;Cargas de trabalho gerenciadas pela própria AWS que já oferecem variante Graviton nativamente: Amazon RDS, ElastiCache, OpenSearch, EMR.&lt;/li&gt;
&lt;li&gt;Workloads horizontalmente escaláveis, onde trocar a arquitetura de um conjunto de instâncias idênticas é simples de validar.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pontos de atenção antes de migrar:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dependências binárias nativas&lt;/strong&gt; (bibliotecas compiladas, extensões C/C++) precisam ter build para ARM64 disponível.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Imagens de container&lt;/strong&gt; precisam ser multi-arquitetura (&lt;code&gt;docker buildx&lt;/code&gt; com suporte a &lt;code&gt;linux/arm64&lt;/code&gt;) ou reconstruídas especificamente para ARM.&lt;/li&gt;
&lt;li&gt;Softwares proprietários de terceiros (agentes de monitoramento, APM, drivers específicos) precisam ter suporte oficial a ARM confirmado pelo fornecedor.&lt;/li&gt;
&lt;li&gt;Testes de performance e carga são recomendados antes de migrar workloads críticas de produção, mesmo com boa compatibilidade declarada.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Estratégia de migração recomendada
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Inventariar&lt;/strong&gt; as aplicações e suas dependências, verificando compatibilidade com ARM64 (bibliotecas, imagens base de container, agentes de terceiros).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Começar pelo menos crítico&lt;/strong&gt; — ambientes de desenvolvimento/homologação ou workloads stateless de baixo risco.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rodar testes de carga comparativos&lt;/strong&gt; entre a instância x86 atual e a equivalente Graviton, validando performance e custo real.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Migrar gradualmente&lt;/strong&gt; ambientes de produção, aproveitando Auto Scaling Groups com múltiplos tipos de instância (mixed instance policy) durante a transição.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consolidar o ganho de custo&lt;/strong&gt; validado nas etapas anteriores em Savings Plans ou Reserved Instances específicas para a família Graviton escolhida.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;O Graviton deixou de ser uma opção experimental e se tornou, hoje, a recomendação padrão da AWS para novas cargas de trabalho — quando a stack permite. A combinação de menor custo, menor consumo energético e performance competitiva faz da migração para ARM uma das otimizações de maior impacto disponíveis em uma conta AWS, especialmente quando combinada com outras estratégias de FinOps como Savings Plans e Spot Instances.&lt;/p&gt;

&lt;p&gt;Antes de migrar qualquer workload crítica, o caminho mais seguro é sempre: validar compatibilidade, testar performance real e migrar de forma incremental — começando pelos ambientes de menor risco.&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>cloudcomputing</category>
      <category>cloudnative</category>
    </item>
    <item>
      <title>The Twelve-Factor App: o guia que todo sistema deveria seguir (mas poucos seguem)</title>
      <dc:creator>Kauê Matos</dc:creator>
      <pubDate>Sat, 12 Sep 2026 22:29:40 +0000</pubDate>
      <link>https://dev.to/ikauedev/the-twelve-factor-app-o-guia-que-todo-sistema-deveria-seguir-mas-poucos-seguem-5g5a</link>
      <guid>https://dev.to/ikauedev/the-twelve-factor-app-o-guia-que-todo-sistema-deveria-seguir-mas-poucos-seguem-5g5a</guid>
      <description>&lt;p&gt;Se você já trabalhou num sistema que funcionava perfeitamente no seu computador mas quebrava assim que ia pra produção, ou já se irritou com uma atualização que exigiu reconstruir tudo só porque mudou a senha do banco de dados, você já sentiu na pele o problema que o Twelve-Factor App tenta resolver.&lt;/p&gt;

&lt;p&gt;Essa ideia surgiu por volta de 2010, dentro da empresa Heroku, com Adam Wiggins à frente. Na época, a empresa já hospedava centenas de milhares de sistemas de clientes diferentes na mesma plataforma, o que deu a eles uma visão privilegiada de tudo que costuma dar errado quando um time constrói software sem pensar em portabilidade, crescimento e manutenção. O resultado foi uma lista de doze práticas — nenhuma delas revolucionária sozinha, mas que juntas formam uma base sólida pra qualquer sistema que roda como serviço na internet.&lt;/p&gt;

&lt;p&gt;O interessante é que, mesmo com toda a evolução das ferramentas desde então, essas doze práticas continuam extremamente válidas. Vamos passar por cada uma.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Um único código-fonte, várias versões em uso
&lt;/h2&gt;

&lt;p&gt;Cada sistema deve viver em um único repositório de código com histórico de versões (como o Git), e a partir dele você gera quantas cópias precisar: uma pra testes, outra pra homologação, outra pra produção. Se você tem vários repositórios diferentes pra uma coisa que deveria ser "um sistema só", provavelmente não é mais um sistema — é vários sistemas conectados, e cada um deveria seguir essa regra separadamente.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Deixe claro do que o sistema depende
&lt;/h2&gt;

&lt;p&gt;Nada de assumir que uma determinada ferramenta ou biblioteca já está instalada no computador ou servidor só porque "sempre esteve". Liste tudo isso de forma explícita, em um arquivo próprio do projeto, e mantenha isso separado do que já vem instalado no sistema operacional. É isso que garante que o sistema funcione do mesmo jeito em qualquer máquina, seja no notebook de quem está desenvolvendo, seja no servidor de produção.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Mantenha as configurações fora do código
&lt;/h2&gt;

&lt;p&gt;Senhas de banco de dados, chaves de acesso a serviços externos, endereços de outros sistemas — nada disso deveria estar escrito dentro do código-fonte. Isso deve ficar guardado separadamente, em variáveis de ambiente do próprio servidor. Além de ser mais seguro (menos risco de vazar uma senha sem querer), isso permite trocar de ambiente sem precisar reconstruir o sistema do zero.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Trate serviços externos como peças substituíveis
&lt;/h2&gt;

&lt;p&gt;Banco de dados, fila de mensagens, sistema de cache, serviço de envio de e-mail — tudo isso deveria ser tratado como uma peça que se conecta por meio de um endereço e uma credencial, sem diferença entre se está rodando no próprio computador ou em outro lugar. Trocar um banco de dados local por um banco hospedado por um provedor de nuvem não deveria exigir mudar uma linha do código, só a configuração.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Separe bem as etapas de construir, preparar e executar
&lt;/h2&gt;

&lt;p&gt;Essas três etapas precisam ser bem distintas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;construir&lt;/strong&gt;: transforma o código escrito em algo pronto pra rodar;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;preparar&lt;/strong&gt;: junta esse resultado com a configuração daquele ambiente específico;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;executar&lt;/strong&gt;: efetivamente coloca isso em funcionamento.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cada versão preparada deveria ter uma identificação única, pra que, se algo der errado, seja possível voltar rapidamente pra versão anterior.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Não guarde informação importante dentro do próprio sistema em execução
&lt;/h2&gt;

&lt;p&gt;O sistema deveria funcionar sem depender de guardar informações importantes na própria memória entre um pedido e outro. Qualquer coisa que precise ser lembrada deve ficar armazenada em um lugar próprio pra isso, como um banco de dados. Isso parece óbvio, mas é justamente o que permite aumentar a capacidade do sistema adicionando mais cópias dele rodando ao mesmo tempo, sem risco de perder informação ou gerar comportamento estranho.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. O sistema deve se apresentar sozinho, sem depender de outro programa
&lt;/h2&gt;

&lt;p&gt;O sistema deveria ser completo por si só e ficar disponível através de uma porta de comunicação própria, sem precisar que outro programa seja instalado por fora pra fazer essa ponte. A maioria das ferramentas modernas de desenvolvimento já vem com isso embutido — é só configurar em qual porta o sistema vai atender.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Aumente a capacidade dividindo o trabalho em partes
&lt;/h2&gt;

&lt;p&gt;Divida o sistema em partes diferentes conforme o tipo de tarefa — uma parte pra atender pedidos que chegam pela internet, outra pra processar tarefas em segundo plano, outra pra rodar tarefas programadas — e aumente cada parte de forma independente conforme a necessidade. Assim, se o gargalo está no processamento em segundo plano, você aumenta só aquela parte, sem precisar mexer no resto.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Deixe o sistema pronto pra ligar e desligar rápido
&lt;/h2&gt;

&lt;p&gt;Um sistema bem construído é aquele que consegue começar a funcionar rapidamente e também parar de forma organizada, terminando o que estava fazendo antes de desligar de vez. Isso é fundamental pra atualizações ágeis, pra aumentar ou diminuir a capacidade automaticamente conforme a demanda, e pra se recuperar rápido quando algo dá errado.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Mantenha o ambiente de testes parecido com o de produção
&lt;/h2&gt;

&lt;p&gt;Esse é um dos pontos mais esquecidos na prática. A ideia é diminuir ao máximo a diferença entre o ambiente onde o sistema é desenvolvido e testado e aquele onde ele realmente atende os usuários — usar a mesma versão de banco de dados, atualizar com frequência, e ter as mesmas pessoas cuidando das duas pontas. É basicamente a receita pra nunca mais ouvir a frase "mas funcionava aqui". Ferramentas que automatizam a criação de ambientes ajudam bastante a diminuir essa distância.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Registros de atividade não devem ser um arquivo pra gerenciar
&lt;/h2&gt;

&lt;p&gt;O sistema não deveria se preocupar em decidir onde guardar seus próprios registros de atividade (o famoso "log"). Ele apenas deveria escrevê-los de forma simples, e outra ferramenta, especializada nisso, deveria cuidar de coletar, organizar e guardar essas informações. Isso simplifica bastante o trabalho de quem constrói o sistema.&lt;/p&gt;

&lt;h2&gt;
  
  
  12. Tarefas administrativas rodam do mesmo jeito que o resto
&lt;/h2&gt;

&lt;p&gt;Corrigir dados no banco, rodar um ajuste pontual, abrir uma sessão pra investigar um problema em produção — tudo isso deveria ser feito usando o mesmo ambiente, o mesmo código e a mesma configuração do sistema normal. Nada de manter um script separado, guardado em outro lugar, que só uma pessoa lembra de atualizar de vez em quando.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usar contêineres não resolve isso sozinho
&lt;/h2&gt;

&lt;p&gt;Vale desfazer um mal-entendido comum: muita gente pensa que, ao usar ferramentas modernas de empacotamento e orquestração de sistemas, essas doze práticas "vêm de graça" junto com elas. Não vêm. Essas ferramentas ajudam bastante em algumas partes — como isolar dependências e permitir que o sistema ligue e desligue rápido —, mas manter a configuração separada do código, evitar guardar informação importante dentro do sistema em execução e organizar bem as versões continua sendo trabalho de quem projeta o sistema, não da ferramenta.&lt;/p&gt;

&lt;h2&gt;
  
  
  No fim das contas
&lt;/h2&gt;

&lt;p&gt;Essas doze práticas não são regras burocráticas de manual. São o tipo de coisa que a maioria das pessoas aprende depois de passar por um problema chato em produção, e que, depois de adotada, ninguém mais quer abrir mão. Seguir esses princípios é o que diferencia um sistema fácil de manter e fazer crescer de um que só continua funcionando porque alguém está sempre correndo atrás de apagar incêndio.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Baseado em &lt;a href="https://12factor.net" rel="noopener noreferrer"&gt;12factor.net&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
      <category>cloud</category>
    </item>
    <item>
      <title>AWS Well-Architected Framework</title>
      <dc:creator>Kauê Matos</dc:creator>
      <pubDate>Sat, 05 Sep 2026 18:12:41 +0000</pubDate>
      <link>https://dev.to/ikauedev/aws-well-architected-framework-47f1</link>
      <guid>https://dev.to/ikauedev/aws-well-architected-framework-47f1</guid>
      <description>&lt;p&gt;Construir na nuvem é fácil. Construir &lt;strong&gt;bem&lt;/strong&gt; na nuvem é outra história. É justamente para preencher essa lacuna que a AWS criou o &lt;strong&gt;Well-Architected Framework (WAF)&lt;/strong&gt;: um conjunto estruturado de princípios de design, boas práticas e perguntas orientadoras que ajudam arquitetos e engenheiros a avaliar workloads sob a ótica de seis pilares — Excelência Operacional, Segurança, Confiabilidade, Eficiência de Performance, Otimização de Custos e Sustentabilidade.&lt;/p&gt;

&lt;p&gt;O framework não é uma checklist genérica de "boas práticas de nuvem". Ele é, na prática, uma metodologia de &lt;strong&gt;trade-offs conscientes&lt;/strong&gt;: toda decisão arquitetural — usar um banco relacional ou NoSQL, multi-AZ ou multi-região, autoscaling agressivo ou conservador — implica abrir mão de algo em troca de outra coisa. O WAF força você a nomear esses trade-offs em vez de descobri-los tarde demais, em produção, sob incidente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Um pouco de história
&lt;/h2&gt;

&lt;p&gt;O framework nasceu em 2012 como um documento interno de arquitetos de soluções da AWS e virou whitepaper público em 2015. Em 2016 ganhou o pilar de Excelência Operacional; em 2017 chegaram os &lt;em&gt;Lenses&lt;/em&gt; (recortes especializados por domínio) e, em 2018, a ferramenta gratuita &lt;strong&gt;AWS Well-Architected Tool&lt;/strong&gt;, disponível direto no Console. O sexto pilar, Sustentabilidade, foi incorporado no fim de 2021, refletindo a pressão crescente por eficiência energética e redução de pegada de carbono em cargas de trabalho de nuvem.&lt;/p&gt;

&lt;p&gt;De lá para cá, a AWS vem tornando o conteúdo cada vez mais &lt;strong&gt;prescritivo&lt;/strong&gt;: cada boas práticas hoje tem página dedicada, com antipadrões comuns, nível de risco, passos de implementação e recursos relacionados — uma resposta direta ao feedback de que o framework antigo dizia "o que" fazer, mas pouco sobre "como".&lt;/p&gt;

&lt;h2&gt;
  
  
  Os princípios gerais de design
&lt;/h2&gt;

&lt;p&gt;Antes de entrar pilar por pilar, vale destacar os princípios transversais que sustentam o framework:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pare de adivinhar sua capacidade&lt;/strong&gt; — use autoscaling e elasticidade em vez de dimensionar para o pico teórico.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Teste sistemas em produção (com segurança)&lt;/strong&gt; — ambientes controlados de teste em escala real, não só em staging.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatize experimentações arquiteturais&lt;/strong&gt; — infraestrutura como código torna barato testar variações de arquitetura.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permita evolução arquitetural&lt;/strong&gt; — desenhe para mudar, não para ser definitivo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Direcione arquiteturas com dados&lt;/strong&gt; — decisões baseadas em métricas reais de uso, não em intuição.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Melhore através de "game days"&lt;/strong&gt; — simule falhas e eventos reais para validar respostas antes que aconteçam de verdade.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Os seis pilares
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Excelência Operacional
&lt;/h3&gt;

&lt;p&gt;Trata da capacidade de operar e monitorar sistemas para entregar valor de negócio, e de melhorar processos e procedimentos continuamente. Na prática, envolve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Infraestrutura como código (Terraform, CloudFormation, CDK) para operações reproduzíveis e auditáveis.&lt;/li&gt;
&lt;li&gt;Observabilidade real: métricas, logs e traces centralizados (CloudWatch, X-Ray) com alarmes acionáveis, não apenas dashboards bonitos.&lt;/li&gt;
&lt;li&gt;Runbooks e playbooks versionados para resposta a incidentes.&lt;/li&gt;
&lt;li&gt;Deploys pequenos, frequentes e reversíveis (blue/green, canary), reduzindo o "blast radius" de cada mudança.&lt;/li&gt;
&lt;li&gt;Retrospectivas pós-incidente sem culpabilização, com ações de melhoria rastreadas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Segurança
&lt;/h3&gt;

&lt;p&gt;O pilar de Segurança foca em proteger informação, sistemas e ativos, mantendo o valor do negócio através de avaliação de risco e estratégias de mitigação. Pontos centrais:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Identidade forte como novo perímetro&lt;/strong&gt;: IAM com privilégio mínimo, roles em vez de credenciais estáticas, MFA obrigatório para operações sensíveis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Defesa em profundidade&lt;/strong&gt;: VPCs segmentadas, security groups e NACLs, WAF e Shield contra ataques na borda.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Criptografia em repouso e em trânsito&lt;/strong&gt; por padrão, com KMS gerenciando chaves e rotação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visibilidade contínua&lt;/strong&gt;: GuardDuty para detecção de ameaças, Security Hub para consolidar postura de segurança, Config para compliance contínuo de configuração.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automação de resposta a incidentes&lt;/strong&gt;, para reduzir o tempo entre detecção e contenção.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A atualização mais recente do framework incorporou também uma área dedicada de &lt;strong&gt;AppSec&lt;/strong&gt; (segurança de aplicação), reforçando que testes de segurança devem fazer parte do ciclo de desenvolvimento — SAST, DAST e dependency scanning como etapas normais de CI/CD, não como auditoria pontual.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Confiabilidade
&lt;/h3&gt;

&lt;p&gt;Aqui o foco é a capacidade de um workload realizar sua função corretamente e de forma consistente, incluindo a habilidade de operar e testar o sistema durante todo o seu ciclo de vida. Boas práticas típicas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arquiteturas multi-AZ como padrão mínimo; multi-região para workloads críticos.&lt;/li&gt;
&lt;li&gt;Recuperação automática de falhas (self-healing) via health checks e auto-replacement de instâncias.&lt;/li&gt;
&lt;li&gt;Gestão de capacidade com margem de segurança e testes de carga regulares.&lt;/li&gt;
&lt;li&gt;Estratégias de disaster recovery bem definidas (backup and restore, pilot light, warm standby, multi-site ativo-ativo), apoiadas por serviços como Elastic Disaster Recovery e Resilience Hub para medir e validar objetivos de RTO/RPO.&lt;/li&gt;
&lt;li&gt;Circuit breakers e retries com backoff exponencial para conter falhas em cascata entre serviços distribuídos.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Eficiência de Performance
&lt;/h3&gt;

&lt;p&gt;Trata do uso eficiente de recursos computacionais para atender requisitos e manter essa eficiência conforme a demanda muda e as tecnologias evoluem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Escolha deliberada de tipo de computação (EC2, containers em ECS/EKS, serverless com Lambda) conforme o padrão de carga do workload.&lt;/li&gt;
&lt;li&gt;Uso de cache em múltiplas camadas (CloudFront, ElastiCache) para reduzir latência e carga em backends.&lt;/li&gt;
&lt;li&gt;Bancos de dados adequados ao padrão de acesso — relacional para transações complexas, NoSQL para escala horizontal e baixa latência, data warehouse para analytics.&lt;/li&gt;
&lt;li&gt;Revisão periódica de novas famílias de instância e serviços gerenciados, já que "o melhor recurso hoje pode não ser o melhor em seis meses".&lt;/li&gt;
&lt;li&gt;Testes de carga e benchmarking como parte do pipeline, não como evento isolado antes de um lançamento.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Otimização de Custos
&lt;/h3&gt;

&lt;p&gt;Foca em evitar gastos desnecessários e obter o melhor retorno pelo dinheiro investido em nuvem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modelos de compra corretos: On-Demand para picos imprevisíveis, Savings Plans/Reserved Instances para baseline previsível, Spot para workloads tolerantes a interrupção.&lt;/li&gt;
&lt;li&gt;Rightsizing constante com apoio do Compute Optimizer e Trusted Advisor, eliminando recursos superdimensionados ou ociosos.&lt;/li&gt;
&lt;li&gt;Tagging consistente de recursos para permitir &lt;em&gt;chargeback&lt;/em&gt;/&lt;em&gt;showback&lt;/em&gt; real por time, produto ou ambiente.&lt;/li&gt;
&lt;li&gt;Orçamentos e alertas proativos via AWS Budgets, evitando surpresas na fatura.&lt;/li&gt;
&lt;li&gt;Cultura de FinOps: custo como métrica de engenharia, revisada com a mesma seriedade que performance e disponibilidade.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6. Sustentabilidade
&lt;/h3&gt;

&lt;p&gt;O pilar mais recente do framework, focado em minimizar o impacto ambiental de workloads em nuvem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Priorizar regiões com matriz energética mais limpa quando a latência permitir.&lt;/li&gt;
&lt;li&gt;Maximizar utilização de recursos provisionados, evitando superprovisionamento "por segurança".&lt;/li&gt;
&lt;li&gt;Preferir serviços gerenciados e serverless, que se beneficiam de ganhos de eficiência agregados da AWS em escala.&lt;/li&gt;
&lt;li&gt;Adotar políticas de ciclo de vida de dados (arquivamento e exclusão automática) para reduzir armazenamento desnecessário.&lt;/li&gt;
&lt;li&gt;Escolher arquiteturas e algoritmos eficientes, já que menos processamento também significa menos consumo energético.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A ferramenta e o processo de revisão
&lt;/h2&gt;

&lt;p&gt;O &lt;strong&gt;AWS Well-Architected Tool&lt;/strong&gt;, gratuito no Console, permite conduzir uma revisão estruturada de um workload: você responde a um conjunto de perguntas por pilar, e a ferramenta identifica riscos (baixo, médio ou alto) e sugere ações de remediação com base nas boas práticas atualizadas.&lt;/p&gt;

&lt;p&gt;Na prática, uma revisão Well-Architected segue um fluxo simples:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Definir o workload&lt;/strong&gt; e seu contexto de negócio (criticidade, SLAs, requisitos regulatórios).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Responder às perguntas de cada pilar&lt;/strong&gt; com a equipe técnica responsável, documentando decisões e justificativas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identificar riscos altos (HRIs)&lt;/strong&gt; — os itens que mais ameaçam o sucesso do workload.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Priorizar e planejar remediação&lt;/strong&gt;, tratando os HRIs como itens de backlog com dono e prazo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repetir periodicamente&lt;/strong&gt;, já que arquiteturas e boas práticas evoluem — uma revisão não é um evento único, é um hábito.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Lenses: recortes especializados
&lt;/h2&gt;

&lt;p&gt;Além do framework geral, a AWS mantém &lt;em&gt;Lenses&lt;/em&gt; — extensões que aplicam os seis pilares a domínios específicos. Existem lenses para arquiteturas serverless, machine learning, SaaS, IoT, containers, entre outros. A adição mais notável recentemente foi o &lt;strong&gt;Generative AI Lens&lt;/strong&gt;, lançado em 2025, que aplica os seis pilares ao ciclo de vida completo de workloads de IA generativa — do escopo de impacto e seleção de modelo até customização, integração, deployment e iteração contínua, com atenção especial a temas como veracidade, explicabilidade e uso responsável de LLMs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como aplicar isso na prática, sem virar teatro corporativo
&lt;/h2&gt;

&lt;p&gt;O maior risco de qualquer framework é ele virar um exercício de preenchimento de formulário. Algumas recomendações práticas para evitar isso:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Comece pequeno: revise um workload real e crítico antes de tentar aplicar o framework em toda a organização de uma vez.&lt;/li&gt;
&lt;li&gt;Trate os pilares como lentes de discussão, não como categorias isoladas — a maioria das decisões arquiteturais toca vários pilares ao mesmo tempo.&lt;/li&gt;
&lt;li&gt;Automatize o que for possível (Config Rules, Security Hub, Trusted Advisor) para que parte da revisão aconteça continuamente, não só numa reunião trimestral.&lt;/li&gt;
&lt;li&gt;Conecte os riscos identificados a itens reais de backlog, com dono e prazo — um relatório de revisão que não vira ação é apenas um documento a mais.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;O AWS Well-Architected Framework não é sobre seguir regras cegamente, é sobre tornar explícitos os trade-offs que toda arquitetura de nuvem já carrega implicitamente. Usado com disciplina — revisões periódicas, HRIs viram backlog, métricas acompanhadas ao longo do tempo — ele funciona como um mecanismo de melhoria contínua genuíno. Usado como checklist de auditoria pontual, vira só mais um documento arquivado. A diferença entre as duas coisas não está no framework, está no processo que você constrói ao redor dele.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>aws</category>
      <category>cloud</category>
      <category>cloudcomputing</category>
    </item>
    <item>
      <title>Por que a Prime Video trocou microsserviços serverless por um monólito</title>
      <dc:creator>Kauê Matos</dc:creator>
      <pubDate>Sat, 05 Sep 2026 17:48:34 +0000</pubDate>
      <link>https://dev.to/ikauedev/por-que-a-prime-video-trocou-microsservicos-serverless-por-um-monolito-3n08</link>
      <guid>https://dev.to/ikauedev/por-que-a-prime-video-trocou-microsservicos-serverless-por-um-monolito-3n08</guid>
      <description>&lt;p&gt;Em março de 2023, a equipe de engenharia da Amazon Prime Video publicou um post técnico que causou bastante repercussão na comunidade de cloud: eles haviam redesenhado um de seus serviços internos, saindo de uma arquitetura distribuída baseada em serverless para uma aplicação monolítica rodando em containers — e reduziram o custo operacional em 90%.&lt;/p&gt;

&lt;p&gt;O caso ficou conhecido de forma simplificada como "Prime Video abandona microsserviços", mas essa leitura esconde um detalhe importante: o problema não estava no conceito de microsserviços em si, e sim em como serverless (Step Functions e Lambda) havia sido usado para orquestrar um fluxo de altíssima frequência de eventos. Vale entender o caso com mais profundidade, porque as lições dele valem para qualquer arquiteto de cloud que precisa decidir entre desacoplar componentes ou simplificar a orquestração.&lt;/p&gt;

&lt;h2&gt;
  
  
  O serviço em questão: monitoramento de qualidade de áudio/vídeo
&lt;/h2&gt;

&lt;p&gt;O time responsável era o de &lt;strong&gt;Video Quality Analysis (VQA)&lt;/strong&gt;, que mantém uma ferramenta capaz de detectar problemas de qualidade em streams de vídeo em tempo real — coisas como corrupção de blocos de imagem, congelamento de vídeo e dessincronização entre áudio e vídeo. Essa ferramenta já existia, mas não havia sido projetada para operar na escala de milhares de streams simultâneos, que é o volume real de tráfego da Prime Video.&lt;/p&gt;

&lt;h2&gt;
  
  
  A arquitetura original
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft24kplwmtxf3pewpah1d.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft24kplwmtxf3pewpah1d.jpg" alt=" " width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A primeira versão do serviço foi construída como um sistema distribuído usando componentes serverless, o que fazia todo sentido do ponto de vista de velocidade de entrega. Em linhas gerais, o desenho contava com:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Media Converter&lt;/strong&gt;: um componente responsável por quebrar os streams de áudio/vídeo em frames de imagem e buffers de áudio decodificados.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Defect Detectors&lt;/strong&gt;: microsserviços que analisavam esses frames e buffers usando algoritmos de machine learning para identificar defeitos, executados via AWS Lambda.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Orquestração via AWS Step Functions&lt;/strong&gt;: controlando as transições de estado entre as etapas do pipeline de análise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon S3&lt;/strong&gt;: usado como armazenamento intermediário, guardando os frames de imagem entre uma etapa e outra do pipeline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon SNS&lt;/strong&gt;: usado para notificar os resultados da análise.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esse desenho tinha uma vantagem clara: escalabilidade horizontal teórica, já que cada componente poderia escalar de forma independente, e uma implementação rápida, aproveitando serviços gerenciados da AWS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Onde a conta não fechou
&lt;/h2&gt;

&lt;p&gt;O problema apareceu quando o serviço começou a operar em escala real. Dois gargalos concentraram praticamente todo o impacto negativo:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Step Functions como orquestrador de alta frequência.&lt;/strong&gt; O fluxo realizava múltiplas transições de estado a cada segundo de stream analisado. Como o Step Functions cobra por transição de estado, e como existem limites de conta para volume de transições, o serviço atingiu limites de escala em torno de apenas 5% da carga esperada — bem abaixo do necessário para operar com todos os streams da plataforma.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Custo de chamadas de camada 1 ao S3.&lt;/strong&gt; Passar frames de vídeo entre componentes usando S3 como intermediário gerava um volume enorme de chamadas de escrita e leitura (chamadas "tier-1", que são as mais caras no modelo de precificação do S3), o que tornava o custo de operação proibitivo em escala.&lt;/p&gt;

&lt;p&gt;Em resumo: o desenho não estava "errado" em teoria, mas o padrão de uso — altíssima frequência de eventos pequenos, orquestrados por um serviço que cobra por evento, trocando dados por um armazenamento intermediário que cobra por chamada — é exatamente o cenário em que orquestração serverless tende a sair cara.&lt;/p&gt;

&lt;h2&gt;
  
  
  A nova arquitetura
&lt;/h2&gt;

&lt;p&gt;A solução da equipe foi consolidar as etapas do pipeline (conversão de mídia e detecção de defeitos) em um único processo, eliminando a orquestração via Step Functions e a troca de dados via S3. Os frames passaram a ser transferidos em memória, dentro do mesmo processo, e não mais por chamadas de rede a um serviço de armazenamento.&lt;/p&gt;

&lt;p&gt;Essa aplicação consolidada passou a rodar sobre &lt;strong&gt;EC2 e ECS&lt;/strong&gt;, com uma camada leve de orquestração para distribuir as requisições dos clientes entre instâncias. Para lidar com o problema de escala vertical de um único processo, a equipe replicou o serviço em múltiplas tarefas ECS, cada uma com um subconjunto de detectores — ou seja, ainda existe distribuição de carga, só que em um nível de granularidade bem mais grosso do que antes.&lt;/p&gt;

&lt;h2&gt;
  
  
  O resultado
&lt;/h2&gt;

&lt;p&gt;A mudança de arquitetura reduziu o custo operacional do serviço em 90% e resolveu o gargalo de escala, permitindo cobrir a totalidade dos streams monitorados. A lógica de negócio (os algoritmos de detecção de defeitos) permaneceu praticamente a mesma — o que mudou foi a camada de orquestração e transporte de dados entre etapas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Uma ressalva importante: monólito ou só "menos serverless"?
&lt;/h2&gt;

&lt;p&gt;O post original gerou um debate acalorado na comunidade técnica, incluindo críticas de arquitetos conhecidos do setor. O ponto central da discussão é que, tecnicamente, o novo desenho não é um monólito no sentido tradicional do termo: a Prime Video como um todo continua operando como um conjunto de serviços independentes (cobrança, catálogo, streaming, etc.), e mesmo o novo serviço de VQA ainda é replicado em múltiplas instâncias ECS.&lt;/p&gt;

&lt;p&gt;O que de fato mudou foi a granularidade da orquestração: em vez de fragmentar cada etapa do processamento em funções Lambda separadas e coordená-las por um serviço de estado que cobra por transição, a equipe passou a executar todas as etapas de um mesmo stream dentro de um único processo. É mais preciso descrever isso como uma migração de &lt;strong&gt;serverless orientado a eventos&lt;/strong&gt; para &lt;strong&gt;compute tradicional em containers&lt;/strong&gt;, do que como "microsserviços versus monólito" — ainda que essa segunda formulação tenha sido a usada no post original e seja a que pegou popularmente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lições para quem projeta arquiteturas em cloud
&lt;/h2&gt;

&lt;p&gt;Alguns pontos ficam claros ao analisar o caso:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;O modelo de cobrança do serviço gerenciado importa tanto quanto sua elasticidade.&lt;/strong&gt; Step Functions e Lambda são excelentes para orquestrar fluxos de baixa a média frequência ou eventos assíncronos, mas cobrar por transição de estado ou por invocação se torna um problema quando a frequência de eventos é da ordem de múltiplas vezes por segundo, por stream, multiplicado por milhares de streams simultâneos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Armazenamento intermediário tem custo de chamada, não só de armazenamento.&lt;/strong&gt; Usar S3 como "fila" ou buffer entre etapas de um pipeline parece simples, mas o custo por operação pode superar rapidamente o custo do armazenamento em si, especialmente em payloads pequenos e frequentes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Desacoplamento tem um custo de rede e serialização que nem sempre se paga.&lt;/strong&gt; Quando as etapas de um pipeline sempre são executadas juntas, para o mesmo item de trabalho, colocá-las no mesmo processo elimina overhead de rede sem necessariamente sacrificar a capacidade de escalar — desde que a unidade de escala (nesse caso, a instância ECS) seja bem dimensionada.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A escolha de arquitetura depende do padrão de acesso, não de uma regra geral.&lt;/strong&gt; O próprio caso não é uma prova de que "monólitos são melhores que microsserviços" — é uma prova de que a granularidade da orquestração precisa ser compatível com a frequência e o volume dos eventos que ela processa.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;O caso da Prime Video se tornou um símbolo do debate entre microsserviços e monólitos, mas seu valor real está em outro lugar: ele mostra como escolhas de orquestração e transporte de dados, tomadas cedo no design de um sistema, podem determinar se uma arquitetura escala de forma sustentável ou colide com limites de conta e custos inesperados assim que sai do piloto para a produção em escala real. Antes de escolher entre serverless, containers ou uma combinação dos dois, vale simular o padrão real de tráfego esperado e o modelo de cobrança de cada serviço envolvido — não só a elegância teórica do desenho distribuído.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fontes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Prime Video Tech Blog — &lt;em&gt;Scaling up the Prime Video audio/video monitoring service and reducing costs by 90%&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;InfoQ — &lt;em&gt;Prime Video Switched from Serverless to EC2 and ECS to Save Costs&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;The New Stack — &lt;em&gt;Amazon Prime Video's Microservices Move Doesn't Lead to a Monolith after All&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>primevideo</category>
      <category>cloud</category>
      <category>cloudcomputing</category>
    </item>
    <item>
      <title>Kiro: a IDE agêntica da AWS — o que é, como funciona e vale a pena usar?</title>
      <dc:creator>Kauê Matos</dc:creator>
      <pubDate>Wed, 02 Sep 2026 15:41:07 +0000</pubDate>
      <link>https://dev.to/ikauedev/kiro-a-ide-agentica-da-aws-o-que-e-como-funciona-e-vale-a-pena-usar-29ag</link>
      <guid>https://dev.to/ikauedev/kiro-a-ide-agentica-da-aws-o-que-e-como-funciona-e-vale-a-pena-usar-29ag</guid>
      <description>&lt;p&gt;Em julho de 2025, a AWS lançou o &lt;strong&gt;Kiro&lt;/strong&gt;, uma IDE agêntica construída sobre a base open-source do VS Code (Code OSS), entrando em um mercado já disputado por ferramentas como Cursor, Windsurf, GitHub Copilot e Claude Code. O produto saiu do modo preview e alcançou disponibilidade geral no fim de 2025/início de 2026, e desde então vem se consolidando como a aposta oficial da AWS para desenvolvimento assistido por IA — a ponto de a própria empresa ter anunciado, em janeiro de 2026, o fim de novos cadastros no Amazon Q Developer (efetivo a partir de 15 de maio de 2026), direcionando explicitamente os usuários ao Kiro.&lt;/p&gt;

&lt;p&gt;O que diferencia o Kiro do restante da concorrência não é o modelo de IA por trás dele (ele roda sobre modelos Claude via Amazon Bedrock, com roteamento também para a Amazon Nova), mas sim sua filosofia de trabalho: em vez de "chat primeiro, código depois", o Kiro é &lt;strong&gt;spec-first&lt;/strong&gt; — a unidade de trabalho não é um prompt solto, e sim uma especificação estruturada que o agente usa para planejar, implementar, verificar e documentar uma funcionalidade de ponta a ponta.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é o Kiro, na prática
&lt;/h2&gt;

&lt;p&gt;O Kiro está disponível em quatro superfícies que compartilham o mesmo agente e o mesmo histórico de créditos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;IDE desktop&lt;/strong&gt; (macOS, Windows e Linux), com a interface familiar de quem já usa VS Code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLI&lt;/strong&gt; para quem prefere trabalhar via terminal&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interface web&lt;/strong&gt;, incluída em todos os planos pagos, que ganhou suporte a GitLab e specs completos em meados de 2026&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App mobile&lt;/strong&gt;, para acompanhar e disparar tarefas em trânsito&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Não é necessário ter conta AWS para começar: dá para entrar com GitHub ou Google, o que reduz a barreira de adoção — embora todo o poder de integração nativa com ambientes AWS só apareça para quem já usa a nuvem da Amazon.&lt;/p&gt;

&lt;h2&gt;
  
  
  O conceito central: desenvolvimento orientado por especificação (spec-driven)
&lt;/h2&gt;

&lt;p&gt;Quando você inicia uma nova funcionalidade no Kiro, a ferramenta não parte direto para o código. Primeiro, ela gera três artefatos estruturados:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;requirements.md&lt;/strong&gt; — histórias de usuário e critérios de aceitação&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;design.md&lt;/strong&gt; — desenho do sistema, decomposição de componentes e fluxo de dados&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;tasks.md&lt;/strong&gt; — lista de tarefas sequenciadas e executáveis&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Só depois que essas especificações são revisadas (e aprovadas) pelo desenvolvedor é que os agentes começam a implementar, rodando comandos e testes ao longo do caminho — inclusive em paralelo, quando o plano permite. Uma atualização de maio de 2026 reforçou esse fluxo em torno de TDD: o agente escreve primeiro os testes que devem falhar a partir da especificação, depois a implementação, e por fim roda a suíte de testes — uma forma de manter um agente autônomo "honesto" em mudanças que tocam vários arquivos.&lt;/p&gt;

&lt;p&gt;Diferente de especificações tradicionais em cascata, que são escritas uma vez e esquecidas, as specs do Kiro evoluem junto com o código e continuam servindo de referência para onboarding, refatoração e novas funcionalidades.&lt;/p&gt;

&lt;h2&gt;
  
  
  Principais recursos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Specs&lt;/strong&gt;: como descrito acima, o núcleo do produto&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hooks (ganchos de agente)&lt;/strong&gt;: automações que disparam em eventos do repositório — salvar um arquivo, criar um componente — para atualizar testes, documentação ou rodar varreduras de segurança automaticamente&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Steering&lt;/strong&gt;: arquivos markdown que guiam o comportamento do Kiro com regras e contexto específicos do projeto&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agentic Chat&lt;/strong&gt;: conversa em linguagem natural que entende o contexto do projeto inteiro&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP (Model Context Protocol)&lt;/strong&gt;: conexão com ferramentas e fontes de dados externas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kiro Autonomous Agent&lt;/strong&gt;: agente em segundo plano que pega tarefas, implementa e abre pull requests sem que o desenvolvedor precise acompanhar em tempo real&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memória persistente entre sessões&lt;/strong&gt; e &lt;strong&gt;agentes que aprendem&lt;/strong&gt; com cada interação&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verificação determinística&lt;/strong&gt;, como testes baseados em propriedades, para checar se o código gerado realmente corresponde à especificação&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pontos positivos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rastreabilidade e disciplina&lt;/strong&gt;: quebrar o trabalho em specs e tarefas revisáveis torna o desenvolvimento assistido por IA mais previsível — você não está apostando que um "despejo" gigante de código vai funcionar de primeira.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bom para produção, não só prototipagem&lt;/strong&gt;: enquanto ferramentas como Cursor otimizam velocidade de iteração, o Kiro otimiza para projetos maiors, em equipe, onde documentação e trilha de decisões importam.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integração nativa com AWS&lt;/strong&gt;: para quem já é cliente AWS, o Kiro capta contexto do ambiente de nuvem sem configuração extra, o que economiza um trabalho real de "engenharia de contexto".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Suporte a GovCloud&lt;/strong&gt;: coloca o Kiro na lista de opções viáveis para setores regulados, onde a maioria dos concorrentes de IA não pode operar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Múltiplas superfícies com o mesmo agente&lt;/strong&gt;: IDE, CLI, web e mobile compartilham a mesma lógica e o mesmo pool de créditos, sem métricas separadas para gerenciar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hooks como colaborador constante&lt;/strong&gt;: automatizam tarefas repetitivas e viram, na prática, um "parceiro" que trabalha em segundo plano.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Guardrails de segurança reforçados&lt;/strong&gt; após um incidente de destaque (ver seção de controvérsias abaixo), o que tornou o produto mais maduro para uso em ambientes de produção.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pontos negativos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Modelo de preços por créditos é agressivo e difícil de prever&lt;/strong&gt;: os planos vão de um tier gratuito (50 créditos/mês) a um Power de US$ 200/mês (cerca de 20.000 créditos), passando por Pro (US$ 20), Pro+ (US$ 40) e Pro Max (US$ 100). Uma construção completa de feature via spec custa, em média, de 15 a 25 créditos — ou seja, o tier gratuito só permite 2 ou 3 features completas por mês.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overhead para tarefas simples&lt;/strong&gt;: se o seu dia a dia é fazer pequenas edições pontuais em um único arquivo, a estrutura de specs adiciona etapas e reduz a sensação de velocidade — o Kiro "compensa" mais em features grandes e multi-etapas do que em ajustes rápidos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custo de add-ons&lt;/strong&gt;: créditos extras saem a US$ 0,04 cada, e o consumo varia conforme o modelo escolhido (usar Claude Sonnet diretamente, por exemplo, consome cerca de 30% mais créditos do que o modo Auto de roteamento).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GovCloud custa ~20% a mais&lt;/strong&gt; e não tem tier gratuito.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Produto ainda "jovem"&lt;/strong&gt;: alcançou disponibilidade geral só no fim de 2025/início de 2026, e usuários relatam lentidão e arestas na interface em threads de comunidades como o r/kiroIDE — problemas típicos de uma ferramenta recente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Incidente de reputação em fevereiro de 2026&lt;/strong&gt;: código gerado por um usuário do Kiro foi apontado, num primeiro momento, como possível causa de uma interrupção de serviço na AWS. A narrativa "o Kiro vibrou demais e derrubou a AWS" viralizou; a AWS negou oficialmente que o Kiro tivesse causado o problema, mas o episódio expôs um risco real: código gerado por IA que interage com infraestrutura de produção precisa de barreiras de segurança bem definidas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependência de um ecossistema (Bedrock/Claude)&lt;/strong&gt;: por rodar sobre modelos de terceiros via Bedrock, o Kiro fica sujeito a mudanças de disponibilidade e custo desses modelos.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Preços (panorama de 2026)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plano&lt;/th&gt;
&lt;th&gt;Preço/mês&lt;/th&gt;
&lt;th&gt;Créditos aproximados&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;US$ 0&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro&lt;/td&gt;
&lt;td&gt;US$ 20&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro+&lt;/td&gt;
&lt;td&gt;US$ 40&lt;/td&gt;
&lt;td&gt;~2.500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro Max&lt;/td&gt;
&lt;td&gt;US$ 100&lt;/td&gt;
&lt;td&gt;~7.000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Power&lt;/td&gt;
&lt;td&gt;US$ 200&lt;/td&gt;
&lt;td&gt;~20.000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Além disso, novos usuários costumam receber créditos-bônus por tempo limitado, e startups elegíveis (até Series B) podem se candidatar a até um ano do plano Pro+ gratuito. Times contam com planos equivalentes, faturamento consolidado, analytics de uso e SSO via AWS IAM Identity Center.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kiro vs. concorrentes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cursor / Windsurf&lt;/strong&gt;: mais rápidos para começar e mais "leves" para quem trabalha sozinho e quer iteração ágil; o Kiro compensa quando o time precisa de planejamento repetível e rastreabilidade de implementação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Code&lt;/strong&gt;: também terminal-first e forte em tarefas de codificação profundas, mas sem o andaime formal de specs (requirements/design/tasks) que o Kiro impõe por padrão.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Copilot&lt;/strong&gt;: mais focado em autocomplete e sugestões inline do que em orquestrar uma feature inteira a partir de uma especificação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon Q Developer&lt;/strong&gt;: era o assistente da AWS mais atrelado ao console e à infraestrutura AWS; a própria AWS está descontinuando novos cadastros nele, direcionando os usuários para o Kiro como sucessor para assistência de IA em IDE.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Para quem o Kiro faz sentido
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Times que precisam que o código gerado por IA seja revisável, documentado e auditável — não apenas rápido.&lt;/li&gt;
&lt;li&gt;Organizações que já compram serviços via AWS e querem aproveitar a relação de billing existente.&lt;/li&gt;
&lt;li&gt;Equipes em setores regulados que dependem de GovCloud.&lt;/li&gt;
&lt;li&gt;Desenvolvedores avaliando Cursor ou Windsurf, mas que querem uma alternativa com etapa de planejamento explícita e maior flexibilidade de modelos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Já para prototipagem rápida, ajustes pontuais em um único arquivo ou projetos pessoais pequenos, o overhead do fluxo de specs pode não compensar — nesses casos, ferramentas mais leves e "chat-first" tendem a parecer mais ágeis no dia a dia.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;O Kiro representa uma aposta filosófica clara da AWS: em vez de tratar a IA como um autocomplete mais rápido, ele tenta resolver o problema de raiz do "vibe coding" — a falta de planejamento antes da implementação. Isso o torna, para muitos, uma das opções mais sólidas para desenvolvimento de produção com IA em 2026, especialmente em times e em ambientes AWS. Por outro lado, o modelo de créditos exige atenção ao orçamento, a estrutura de specs pode ser overkill para tarefas simples, e o produto ainda carrega as arestas normais de uma ferramenta que amadureceu rápido demais para o holofote que recebeu — inclusive um episódio de reputação que, apesar de desmentido pela AWS, deixou claro o quanto guardrails de segurança são essenciais quando agentes de IA tocam infraestrutura real.&lt;/p&gt;

&lt;p&gt;Na prática, a recomendação mais comum entre quem testou a ferramenta a fundo é: rodar o Kiro em paralelo com a ferramenta que você já usa, reservando-o para features maiores e mais estruturadas, e usar algo mais leve para o trabalho do dia a dia.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>kiro</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
