# Daemon crítico ou não-crítico: o contrato de falha do ECS

Em 3 de setembro de 2026 a AWS passou a permitir declarar um ECS Managed Daemon como não-crítico, e com isso transformou uma decisão que antes era implícita em um parâmetro versionado. O que está em jogo não é o daemon: é o contrato de falha entre um agente transversal e a instância que o hospeda. Este teardown dissseca a anatomia do padrão, a regra de decisão que uso para classificar cada agente e o que se paga — em churn, em ponto cego e em conta — ao classificar errado.

- URL: https://fernando.moretes.com/blog/daemon-critico-ou-nao-critico-o-contrato-de-falha-do-ecs-amazon-ecs-m

- Markdown: https://fernando.moretes.com/blog/daemon-critico-ou-nao-critico-o-contrato-de-falha-do-ecs-amazon-ecs-m/article.md?lang=pt

- Published: 2026-09-04T10:15:54.867Z

- Category: IA & Agentes

- Tags: ECS, Managed Instances, containers, reliability, observability, FinOps, Well-Architected

- Reading time: 7 min

- Source: [Amazon ECS Managed Daemons now support non-critical daemons](https://aws.amazon.com/about-aws/whats-new/2026/09/ecs-managed-daemons-non-critical/)

---

Todo cluster de contêineres carrega uma camada de software que ninguém pediu e todo mundo precisa: o coletor de logs, o agente de EDR, o exportador de métricas, o proxy de malha. Durante anos essa camada foi tratada como detalhe de empacotamento — um sidecar a mais no task definition, um DaemonSet no Kubernetes. O lançamento de daemons não-críticos no Amazon ECS Managed Daemons, em 3 de setembro de 2026, expõe a questão que estava escondida embaixo do empacotamento: quando esse agente morre, o que deve acontecer com a máquina que o hospeda? A resposta agora é um parâmetro (`critical`), e parâmetro é coisa que se versiona, se revisa e se erra.

## O problema: agentes transversais são acoplamento disfarçado de conveniência

O modelo sidecar-por-task resolve distribuição e falha em economia e governança. Uma instância que roda 40 tasks roda 40 cópias do coletor de logs; a 128 MiB cada, são 5 GiB de RAM gastos duplicando a mesma função. Pior que o desperdício é a deriva: a versão do agente passa a ser propriedade de cada time de aplicação, e o time de segurança descobre no auditoria que três serviços ainda rodam uma imagem de sete meses atrás.

O ECS já tinha a estratégia de escalonamento `DAEMON` para o launch type EC2, mas ela é apenas colocação — um daemon por instância, sem garantia de que ele esteja de pé *antes* da primeira task de aplicação atender tráfego. Para telemetria isso é um buraco no gráfico. Para um agente de runtime security, é uma janela em que a instância processa transação sem cobertura.

Managed Daemons, GA em 1º de abril de 2026 para capacity providers do ECS Managed Instances, fechou esse buraco invertendo a relação: a instância só transiciona a task de aplicação para `RUNNING` depois que o daemon está rodando. O preço dessa garantia foi um acoplamento rígido — qualquer daemon que falhasse levava a instância a drenar e ser substituída. Correto para um agente de conformidade. Absurdo para um exportador de métricas. O lançamento de setembro não adiciona uma funcionalidade nova; ele desfaz um acoplamento que nunca deveria ter sido único.

## Anatomia: três peças, duas garantias, um interruptor

O padrão tem três recursos distintos. Primeiro, um **daemon task definition** — um tipo de recurso próprio, com ARN próprio (`daemon-task-definition/...`), separado do task definition de aplicação. Segundo, um **daemon**, criado com `CreateDaemon`, que amarra essa definição a um cluster e a um ou mais capacity providers do Managed Instances. Terceiro, as instâncias EC2 provisionadas por esses capacity providers, em cada uma das quais o ECS mantém exatamente uma task de daemon.

A primeira garantia é de **ordem**: o ECS provisiona a instância, sobe a task de daemon e só então promove a task de aplicação a `RUNNING`. Medições independentes publicadas em abril de 2026 mostraram o daemon alcançando `RUNNING` de 18 a 21 segundos antes da aplicação, com a instância mantida em `REGISTERING` nesse intervalo. **Essa ordem vale para todo daemon, crítico ou não.** É o ponto que mais vejo entendido errado: ao marcar um daemon como não-crítico você não perde a garantia de que o agente sobe antes do tráfego; perde apenas a garantia de que ele *continua* de pé.

A segunda garantia é de **remediação**, e é ela que o interruptor `critical` controla. Vale registrar como o ECS remedia: ele não reinicia o contêiner, ele drena e substitui a instância inteira. É deliberadamente brutal — um agente que morreu pode ter deixado probes eBPF desanexadas, regras de rede meio aplicadas, buffers perdidos. Trocar a instância é a única forma barata de voltar a um estado conhecido.

## O ciclo de vida da instância e a bifurcação da criticidade

A ordem de inicialização (esquerda) é idêntica nos dois modos. O parâmetro `critical` só decide o que acontece depois que o daemon falha — e o ramo não-crítico só é seguro se o braço de observabilidade estiver ligado.

### 🟦 AWS — Provisioning & startup order

- Managed Instances capacity provider (compute)
- EC2 instance state: REGISTERING (compute)
- Daemon task exactly 1 per instance (compute)

### 🔀 Failure contract — critical parameter

- critical = true | false per-daemon, default true (security)

### 🟥 critical=true — fail closed

- Registration blocked instance never goes ACTIVE (security)
- DRAINING + replace ~5 min per wave, 25% default (compute)

### 🟩 critical=false — fail open

- Instance stays ACTIVE running tasks untouched (compute)
- Placement continues registration never blocked (compute)
- Coverage gap silent unless observed (security)

### 🟧 Observability — the other half of the pattern

- EventBridge Daemon service action (messaging)
- Service action log critical + non-critical (data)
- CloudWatch alarm + bake time rollback (data)
- Coverage SLO % instances with healthy daemon (data)

### Fluxos

- svc -> cp: 1. task pendente
- cp -> ec2: 2. provisiona EC2
- ec2 -> daemon: 3. sobe o daemon primeiro (~18-21s)
- daemon -> gate: 4. falhou / parou / unhealthy
- gate -> block: falha ao iniciar
- gate -> drain: falha depois de ativa
- gate -> active: critical=false
- active -> place: novas tasks entram
- place -> gap: sem cobertura do agente
- gate -> eb: evento em ambos os modos
- gate -> log: service action log
- eb -> alarm: regra → SNS/Lambda
- alarm -> drain: rollback do circuit breaker
- eb -> slo: alimenta o erro de cobertura
- gap -> slo: só aparece se medido

## O que muda de fato entre os dois modos
| Critério | Crítico (padrão) | Não-crítico (critical=false) |
| --- | --- | --- |
| Daemon falha ao iniciar | Instância não completa o registro; nenhuma task de aplicação é colocada nela | Registro nunca é bloqueado; tasks de aplicação sobem imediatamente |
| Daemon para ou fica unhealthy depois | ECS drena e substitui a instância inteira (auto-repair) | Instância segue ACTIVE; tasks existentes não são tocadas |
| Colocação de novas tasks | Interrompida na instância afetada | Continua normalmente, mesmo sem o agente |
| Ordem de inicialização | Daemon antes da aplicação | Daemon antes da aplicação — idêntico |
| Sinal emitido na falha | Evento no EventBridge + service action log | Evento no EventBridge + service action log — idêntico |
| Risco residual que você assume | Churn de frota: um agente instável vira substituição de instâncias em cascata | Ponto cego: cobertura degrada em silêncio se ninguém consumir o evento |

## Quando usar cada modo: a regra que aplico

A regra cabe em uma linha: **marque como crítico o agente cuja ausência muda o que o sistema tem permissão de fazer; marque como não-crítico o agente cuja ausência muda apenas o que você consegue ver.** Um EDR de runtime, um enforcer de política de rede, um sidecar de mTLS ou um agente de integridade de arquivos exigido por PCI DSS caem no primeiro grupo — sem eles, a instância não deveria estar apta a processar uma transação. Um coletor OTel de métricas, um exportador de nó, um agente de profiling contínuo caem no segundo.

A nuance mora no roteador de logs. Em ambiente financeiro, o log frequentemente *é* a trilha de auditoria: "o que você consegue ver" vira "o que você consegue provar", e o Fluent Bit deixa de ser auxiliar. Não classifique por categoria de ferramenta; classifique pela obrigação regulatória que aquele fluxo sustenta. Se o buffer local do agente aguenta a janela de indisponibilidade sem perder evento, não-crítico é defensável; se ele perde, é crítico.

O corolário de design é o que mais rende na prática: como a criticidade é por daemon, e um capacity provider aceita múltiplos daemons, **não empacote agentes de contratos diferentes no mesmo task definition**. Um task definition com o EDR e o coletor de métricas juntos força o contrato mais estrito sobre os dois — e transforma um vazamento de memória do coletor em substituição de frota. Dois daemons, dois ciclos de release, dois donos, duas criticidades.

> "Não-crítico" é um termo do control plane, não do negócio. O parâmetro descreve o que o ECS faz com a instância — não o quanto aquele agente importa para você.

## O que se paga ao classificar errado — nos dois sentidos

**Crítico demais.** Uma revisão ruim do agente faz a task oscilar, e cada oscilação vira substituição de instância. Numa frota de 60 instâncias com o *drain percentage* no padrão de 25%, são 15 substituições simultâneas por onda; com o tempo medido de ~4min50s por onda, uma mudança de uma linha no agente custa cerca de 20 minutos de rotação de frota. O impacto direto na conta é modesto e calculável: a taxa de gerenciamento do Managed Instances para um `c6a.2xlarge` é de US$ 0,037/hora por instância (Oregon), então 60 instâncias somam ~US$ 1.620/mês só de fee, mais o EC2 e o overlap durante o drain. A fatura cara é outra: reescalonamento de tasks de aplicação, conexões drenadas, caches frios, JIT frio.

Dois defaults conspiram aqui. O *bake time* padrão é `0` minuto — ou seja, terminada a última onda, a janela em que o circuit breaker observa alarmes para fazer rollback é nula. Uma regressão que só aparece sob carga passa direto.

**Não-crítico demais.** O modo falha aberto não emite dor: a instância continua ACTIVE, o SLO da aplicação não se move, e a cobertura do agente cai em silêncio. Some-se a armadilha operacional documentada: as configurações de daemon **não são persistidas entre updates**, e `critical` tem default `true`. Um `UpdateDaemon` disparado por pipeline sem `--no-critical` explícito re-arma o churn de frota inteiro sem que ninguém tenha pedido isso. É exatamente o tipo de mudança que só aparece no próximo incidente.

## Anti-padrões que este lançamento torna fáceis

- Marcar tudo como não-crítico para "parar de ter churn" — você não removeu a falha, apenas desligou o alarme que ela puxava.
- Flipar para não-crítico sem antes ligar a regra do EventBridge para os eventos de daemon a um destino que acorda alguém. O modo fail-open sem consumidor de evento é um ponto cego de conformidade com aparência de estabilidade.
- Empacotar agente de segurança e agente de telemetria no mesmo daemon task definition, forçando um único contrato de falha sobre softwares com riscos opostos.
- Gerenciar daemon por CLI ad hoc: como o `UpdateDaemon` não persiste configurações e `critical` volta ao default `true`, cada chamada parcial é uma mudança de contrato silenciosa.
- Manter bake time em 0 com alarmes configurados — é pagar o custo cognitivo do circuit breaker sem comprar a janela de observação que o torna útil.
- Tratar o daemon crítico como substituto de health check da aplicação. Ele repara cobertura de agente, não saúde de negócio; um agente saudável numa instância com disco cheio segue "saudável".

## Leitura Well-Architected da decisão

- **security**: Fail-closed continua sendo o default correto para agentes de enforcement: um daemon crítico impede que a instância registre sem cobertura. Governe quem pode afrouxar isso com IAM em `ecs:CreateDaemon`/`ecs:UpdateDaemon`, escopado por ARN de daemon e condicionado por tag, para que o time de segurança seja dono do daemon de segurança e a plataforma seja dona dos demais.
- **reliability**: Não-crítico remove um modo de falha correlacionado real: uma regressão no agente atingindo todas as instâncias ao mesmo tempo produzia substituição simultânea de frota. Em troca, a recuperação do agente deixa de ser automática — planeje reparo explícito.

> **Configuração de referência que eu levaria para produção:** Dois daemons por capacity provider: `sec-runtime` com `critical: true` e `obs-otel` com `critical: false`. Drain percentage em 10 (não 25) para que uma onda ruim atinja 10% da frota, e bake time entre 15 e 30 minutos com pelo menos dois alarmes do CloudWatch ligados ao circuit breaker — um de erro da aplicação, um de saúde do próprio agente. Uma regra do EventBridge capturando os eventos de daemon service action e daemon deployment state change, com destino em SNS para o daemon crítico e em fila/Lambda que alimenta o SLO de cobertura para o não-crítico. Todo daemon declarado por inteiro em IaC — nunca por CLI parcial — com drift detection, porque `UpdateDaemon` reverte o que você omitir. E confira o instance profile: ele precisa de `AmazonECSInstanceRolePolicyForManagedInstances`; a policy legada `AmazonEC2ContainerServiceforEC2Role` impede o daemon de subir.

> **Nota de curadoria:** Já vi um vazamento de memória num agente de observabilidade virar rotação de nós numa janela de liquidação, e o post-mortem não apontou o vazamento como causa raiz — apontou que ninguém nunca tinha escrito quais agentes tinham permissão de morrer. Desde então eu exijo um campo de criticidade explícito no ADR de qualquer agente antes de ele entrar na plataforma, com o dono e a obrigação regulatória que ele sustenta ao lado. Este lançamento me dá, enfim, um lugar no control plane para materializar essa decisão em vez de deixá-la implícita no runbook. O que eu não faria é usar o `critical: false` como analgésico: se um agente falha o suficiente para incomodar, o problema é o agente, e marcá-lo como não-crítico só troca um incidente ruidoso por uma lacuna silenciosa. Meu default segue sendo crítico, e cada exceção precisa de um SLO de cobertura para ser aprovada.

## Veredito

Adote — e trate o `critical` como decisão de arquitetura, não como flag de tuning. Mantenha o default crítico para agentes de enforcement (EDR, política de rede, mTLS, integridade de arquivos) e para roteadores de log que sustentam trilha de auditoria. Mova para não-crítico apenas métricas, profiling e telemetria cuja perda temporária não vira perda de prova — e só depois de a regra do EventBridge estar ligada a um consumidor e o SLO de cobertura estar publicado. Separe agentes de contratos diferentes em daemons diferentes, baixe o drain percentage para 10, suba o bake time para 15-30 minutos e declare tudo em IaC, porque `UpdateDaemon` reverte omissões para `critical: true` silenciosamente. Se o seu cluster ainda não está em Managed Instances, esse lançamento não muda seu roadmap; se está, ele fecha a última desculpa razoável para manter sidecar de agente em todo task definition.

**Rating:** Adopt — with the switch written down

## Referências

- [AWS What's New — Amazon ECS Managed Daemons now support non-critical daemons (Sep 3, 2026)](https://aws.amazon.com/about-aws/whats-new/2026/09/ecs-managed-daemons-non-critical/)
- [Amazon ECS Developer Guide — Amazon ECS Managed Daemons (daemon criticality)](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/managed-daemons.html)
- [Amazon ECS Developer Guide — Creating and managing daemons (drain percentage, bake time, UpdateDaemon)](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/managed-daemons-create-manage.html)
- [Amazon ECS Developer Guide — Amazon ECS events (daemon service action, daemon deployment state change)](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs_cwe_events.html)
- [AWS What's New — Amazon ECS announces Managed Daemons for ECS Managed Instances (Apr 1, 2026)](https://aws.amazon.com/about-aws/whats-new/2026/04/amazon-ecs-managed-daemons/)
- [Amazon ECS pricing — ECS Managed Instances management fee](https://aws.amazon.com/ecs/pricing/)
- [shinyaz — Measuring ECS Managed Daemons startup order guarantees and rolling deployment behavior](https://shinyaz.com/en/blog/2026/04/02/ecs-managed-daemons-verification)
- [Amazon ECS Managed Instances — product overview](https://aws.amazon.com/ecs/managed-instances/)
