Pular para o conteúdo
fernando.moretes.com
BlogEstudosCursosE-booksOpen SourcePodcasts
Loading…
Fernando Azevedo

Arquiteto de TI Especialista

Arquitetura, AWS, IA em produção, sistemas financeiros e FinOps, escritos a partir do que foi operado, com os números.

  • LinkedIn
  • GitHub
  • E-mail

Conteúdo

  • Blog
  • Estudos de arquitetura
  • Cursos
  • E-books
  • Open Source
  • Podcasts
  • Assuntos
  • Trilhas

Ferramentas

  • Well-Architected self-check
  • Arquitetura deste site
  • Números públicos
  • Histórico de estudo

Sobre

  • Comunidade
  • IA Builder
  • Perfil
  • Currículo (CV)
  • Trabalhe comigo
  • Media kit
  • RSS do blog
  • RSS dos estudos
  • Artigos narrados (podcast)
  • llms.txt
  • Termos, privacidade e uso de IA

(c) 2026 Fernando Francisco Azevedo

Blog/Artigo
RSSMarkdownLLMs
AWS & CloudAnatomia do Padrão

AMI com contrato: anatomia do novo bloqueio de tipos no EC2

4 de set. de 2026 8 minAvançado Com apoio de IA000 visualizações00 reproduções
Ouvir artigo

15:53 · voz do Fernando

Um AMI sempre foi um contrato verbal. O artefato sabe exatamente de que hardware ele precisa, driver ENA, NVMe, arquitetura do binário, extensão de CPU que a JVM compilou, e nada disso estava escrito em lugar nenhum que o RunInstances pudesse ler. A partir de 4 de setembro de 2026 dá para escrever: o dono do AMI declara SupportedInstanceTypes, UnsupportedInstanceTypes ou os dois, e o EC2 bloqueia o lançamento fora da lista. Sem custo adicional, em todas as regiões. A leitura fácil é "menos launch quebrado". A leitura que interessa é outra, o ponto de enforcement mudou de lugar, e com ele mudou quem paga a conta da manutenção.

O problema: o contrato existia, mas não era executável

Todo time de plataforma que publica golden AMI já viveu esta cena. A imagem endurecida foi construída para x86_64, com agente de EDR compilado estaticamente e um kernel que só carrega driver de rede em host Nitro. Alguém abre um Auto Scaling group com attribute-based instance type selection pedindo 4 vCPU e 16 GiB, deixa a diversificação de Spot larga, que é a recomendação correta para preencher capacidade, e o EC2 escolhe uma família Graviton porque ela casa os atributos e é a mais barata do momento.

A instância sobe. É esse o detalhe que faz o modo de falha doer. Ela não morre no RunInstances; ela morre depois, sem console, sem rede, sem nada além de um health check que expira. O ASG espera o grace period padrão de 300 segundos, marca a instância como não saudável, termina e tenta de novo, e como a decisão de alocação não mudou, ele escolhe o mesmo pool. Você tem um loop de launch/terminate cobrado no mínimo de 60 segundos por instância criada, um alarme que dispara às duas da manhã e um gráfico que parece falta de capacidade.

As defesas que existiam eram todas do lado do chamador: condição ec2:InstanceType em política IAM, SCP na Organization, ExcludedInstanceTypes dentro do InstanceRequirements da frota. Todas corretas, todas com o mesmo defeito estrutural, elas descrevem o que aquele principal pode lançar, não o que aquela imagem aguenta. Compartilhe o AMI com 40 contas e você precisa replicar a regra 40 vezes, em 40 lugares que divergem.

O contrato viaja com o artefato, e falha no portão, não no health check

Desenho de referência: o pipeline gera a lista a partir de uma consulta de capacidade, grava a especificação no AMI, e o RunInstances vira o ponto único de avaliação para toda conta que recebeu a imagem.

🏗️ Pipeline de imagem, build time
  • EC2 Image Builder · pipeline do golden AMI
  • DescribeInstanceTypes · filtro por arquitetura + hypervisor
  • ReplaceImageInstanceTypeSpecification · lista explícita, gerada
🟧 AWS, plano de controle do EC2
  • AMI · InstanceTypeSpecification
  • CopyImage / share · especificação preservada
  • RunInstances · avalia tipo × contrato
🚀 Consumidores, launch time
  • Auto Scaling group · ABIS + Spot diversificado
  • Launch template · versão do AMI fixada
  • Instância lançada · tipo dentro do contrato
  • InvalidParameterCombination · lançamento bloqueado
🔍 Sinais, o que você tem que instrumentar
  • CloudTrail · errorCode em RunInstances
  • Scaling activity · falha registrada no ASG
  • CloudWatch · metric filter por imageId

Anatomia: duas listas, uma ordem de avaliação, zero estado

O atributo se chama InstanceTypeSpecification e carrega SupportedInstanceTypes e UnsupportedInstanceTypes. A lógica é curta o bastante para caber num ADR: sem especificação, tudo passa (é o default, e é por isso que nada quebrou no dia 4); só a lista de não suportados, passa tudo menos o que casar; com a lista de suportados, o tipo precisa casar a lista de suportados e não casar a de não suportados. A negação sempre vence.

Se escreve pela CLI com aws ec2 replace-image-instance-type-specification --image-id ami-... --instance-type-specification '{"SupportedInstanceTypes": ["t3.","a2."], "UnsupportedInstanceTypes": ["t3.micro"]}'. Omitir o parâmetro remove a restrição. Se lê no describe-images, que devolve o campo InstanceTypeSpecification com os padrões como estão. Um lançamento barrado devolve InvalidParameterCombination no RunInstances, com a mensagem apontando o próprio DescribeImages como lugar de investigar.

Quatro propriedades mudam o desenho, e nenhuma delas está no anúncio:

Replace, não Modify: a operação troca a especificação inteira. Não existe adicionar nem remover item, é read-modify-write, sem versão condicional. Dois pipelines corrigindo a mesma imagem em paralelo produzem last-writer-wins em silêncio, e o perdedor só descobre quando um lançamento legítimo é bloqueado.

Só o dono escreve. Conta que recebeu o AMI compartilhado consome o contrato e não negocia.

CopyImage preserva a especificação. É o que faz o padrão valer a pena em topologia multi-região: você declara uma vez e a réplica em sa-east-1 já nasce com o contrato.

Marketplace é mutuamente exclusivo. Não dá para pôr especificação em AMI listado no Marketplace, nem listar no Marketplace um AMI que já tem uma. Se você é ISV distribuindo appliance, este recurso não existe para você.

Três formas de restringir tipo de instância, e o que cada uma cobre de verdade

Condição IAM / SCP ec2:InstanceTypeExcludedInstanceTypes no ABISInstanceTypeSpecification no AMI
Onde a regra viveNa política do principal, por conta ou OUNa configuração da frota ou do ASGNo artefato, uma vez, na conta dona
Vale para quem lança de outra contaNão, a política é de lá, não suaNão, quem configura a frota é o consumidorSim, o EC2 avalia independente do chamador
Sobrevive a CopyImage e compartilhamentoIrrelevante, não acompanha a imagemIrrelevante, não acompanha a imagemSim, preservada na cópia
Quando a falha apareceUnauthorizedOperation no lançamentoNunca, o tipo só não é escolhidoInvalidParameterCombination no lançamento
Custo de manutençãoAlto: replicar e auditar N contasMédio: uma edição por frota que existirBaixo por lugar, alto por geração de hardware

Onde o glob te trai: string não é predicado de arquitetura

As duas listas aceitam . A documentação dá os exemplos: t3. casa toda a família t3, g5. casa a g5, .12xlarge casa qualquer 12xlarge de qualquer família, *xlarge casa qualquer tipo xlarge ou maior. Parece expressivo. É onde eu pararia e faria a pergunta que importa: você está descrevendo hardware ou está descrevendo nomes?

O que o AMI realmente exige é uma capacidade: arm64 contra x86_64, hypervisor Nitro contra Xen, presença de GPU, presença de disco local NVMe. O que a especificação avalia é um padrão sobre a string do tipo. As duas coisas coincidem hoje porque a AWS batiza famílias Graviton com g e famílias com disco local com d. Elas coincidem por convenção, e convenção de nomenclatura não é contrato: c6gn, c7gd, m7i-flex, u7in-32tb e mac2-m2pro já mostram que o esquema tem exceções, sufixos e infixos que nenhum glob simples cobre. Um g. escrito para excluir Graviton é uma heurística, e heurística escrita à mão, num arquivo que ninguém revisita, é dívida com juros.

A segunda armadilha é temporal, e é a mais cara. Uma allow-list explícita bloqueia toda geração futura por construção. Famílias novas chegam a novas regiões o tempo todo; no dia em que a próxima geração aparecer no seu pool de Spot, a frota que você deixou larga de propósito, porque diversificação larga é a prática correta para capacidade Spot, vai ignorar exatamente a família mais barata e mais disponível. Você não vai receber erro nenhum: o ASG simplesmente não escolhe, o preço sobe um pouco, a taxa de interrupção sobe um pouco, e ninguém liga isso a um JSON escrito oito meses atrás. É a mesma tensão do OnDemandMaxPricePercentageOverLowestPrice, que já vem com 20% de folga por padrão justamente para não estreitar o pool sem avisar.

Gere a lista, não escreva a lista

O único jeito de manter o contrato honesto é derivá-lo de uma consulta de capacidade no mesmo build que produziu a imagem: aws ec2 describe-instance-types --filters Name=processor-info.supported-architectures,Values=x86_64 Name=hypervisor,Values=nitro --query 'InstanceTypes[].InstanceType' e alimentar o resultado direto no replace-image-instance-type-specification. Para frotas que já pensam em atributos, GetInstanceTypesFromInstanceRequirements faz o mesmo papel e te deixa pré-visualizar o conjunto antes de gravar. A lista fica explícita, verbosa e feia, e é exatamente isso que você quer, porque ela é regenerada a cada build, e o atraso em relação ao catálogo da AWS passa a ser a sua cadência de pipeline, não a memória de quem escreveu o glob.

O hard block em dia de incidente, e o sinal que ninguém instrumenta

A documentação é explícita: o EC2 aplica a especificação como bloqueio duro, e launch templates e Auto Scaling groups que apontem para o AMI podem falhar se o tipo configurado não for permitido. Isso não é um detalhe de implementação, é a troca central do padrão. Você converteu uma falha lenta e cara (instância zumbi, health check, loop) numa falha rápida e barata (InvalidParameterCombination no RunInstances). Rápida e barata é melhor em 95% dos dias. Nos outros 5%, você está no meio de um evento de capacidade zonal, o price-capacity-optimized finalmente encontrou um pool com capacidade, e o seu contrato diz não.

Em sistema financeiro isso tem nome: você trocou risco de correção por risco de disponibilidade, e trocou de propósito. Quando o AMI de fato não boota naquele hardware, a troca é trivialmente boa, a instância não ia servir tráfego mesmo. Quando a lista só está desatualizada, você inventou um modo de indisponibilidade que não existia antes, exatamente na janela em que a elasticidade importa. É por isso que allow-list gerada e deny-list mínima não são preferência estética: uma erra para o lado de deixar passar, a outra erra para o lado de barrar.

O buraco é observabilidade. A especificação não afeta instância que já está rodando, não emite métrica própria e não aparece em dashboard nenhum por default. O sinal auditável é o evento RunInstances no CloudTrail com errorCode, dá para fazer metric filter agrupando por requestParameters.imageId e alarmar em qualquer bloqueio, porque em regime normal a taxa esperada é zero. Bloqueio recorrente não é o controle funcionando; é um launch template apontando para um AMI que mudou de contrato debaixo dele. E adicione o par de leitura no runbook: describe-images com o campo InstanceTypeSpecification é a primeira coisa a olhar quando um lançamento falha por parâmetro, a própria mensagem de erro manda você para lá, e quem estiver de plantão às duas da manhã precisa saber disso antes de abrir um caso no suporte.

Como estragar isso

  • Aplicar o contrato em AMI já compartilhado sem inventário de consumidores: você não vê os launch templates das outras 40 contas, e o bloqueio só aparece no próximo scale-out delas, que provavelmente é um pico, não um deploy.
  • Escrever a lista à mão: um glob curado por humano é uma foto do catálogo de instâncias no dia em que foi escrito, e o catálogo muda toda semana.
  • Dois pipelines escrevendo a especificação do mesmo AMI: ReplaceImageInstanceTypeSpecification substitui tudo e não tem escrita condicional; o segundo apaga o primeiro sem erro.
  • Usar isso como controle de custo: bloquear *.24xlarge para conter gasto é política de FinOps disfarçada de compatibilidade, isso pertence a SCP com ec2:InstanceType ou a OnDemandMaxPricePercentageOverLowestPrice, onde a exceção tem dono e processo.
  • Confundir isso com validação em pipeline: o contrato falha no lançamento, não no build. Ele não substitui um teste que sobe a imagem em cada família permitida antes de promover o AMI a produção.

Lendo o padrão pelos pilares

Excelência operacional

O contrato vira código gerado no mesmo pipeline do AMI, versionado com ele. Adicione describe-images ao runbook: a mensagem de erro aponta para lá, e é o primeiro passo do diagnóstico.

Segurança

Restringir a lista não é isolamento nem menor privilégio, só o dono escreve, e a regra segue a imagem, mas ela não substitui condição IAM nem SCP para governança de quem lança o quê.

Confiabilidade

Ganho real ao eliminar o loop de launch/terminate por AMI incompatível; risco real de não escalar em evento de capacidade se a lista estiver desatualizada. Alarme com taxa esperada zero é o que separa os dois.

Otimização de custos

O recurso não custa nada e corta o desperdício das instâncias que subiam para morrer no health check, mas uma allow-list estreita empurra a frota para pools mais caros sem emitir sinal nenhum.

FA
O que eu faria
Arquiteto de TI Especialista

Eu ligaria isso primeiro nos AMIs que realmente têm um limite físico, imagem arm64, imagem com driver que só existe em Nitro, imagem de inferência que assume GPU, e deixaria em paz os AMIs de propósito geral, onde o default permissivo já está certo. Em toda imagem que restringir, eu geraria a lista por describe-instance-types dentro do build e falharia o pipeline se ela ficasse vazia, porque uma lista vazia por bug de query bloqueia tudo silenciosamente. E colocaria um alarme de taxa esperada zero em cima do errorCode do RunInstances no CloudTrail no mesmo dia, não na sprint seguinte. A lição que me custou caro, em plataforma financeira: todo controle que barra alguma coisa e não conta quantas vezes barrou vira, com o tempo, uma causa raiz de incidente que ninguém consegue nomear. O bloqueio é a parte fácil; o contador é o que te salva às duas da manhã.

Referências

AWS What's New: Amazon EC2 now supports specifying compatible instance types on AMIs (Sep 4, 2026)Amazon EC2 User Guide: AMI allowed instance types (evaluation logic, wildcards, considerations)Amazon EC2 API Reference: ReplaceImageInstanceTypeSpecificationAWS CLI Reference, ec2 replace-image-instance-type-specificationEC2 Auto Scaling, attribute-based instance type selection, price and performance protectionAmazon EC2 User Guide, attribute-based instance type selection for EC2 Fleet and Spot FleetAmazon EC2 API Reference: GetInstanceTypesFromInstanceRequirements

Veredito

Adopt with scope

Adote, com escopo estreito e com a lista gerada. Use InstanceTypeSpecification quando três condições valerem juntas: o AMI tem uma incompatibilidade de hardware real e não uma preferência de custo, você não controla todas as contas que lançam a imagem, e o pipeline que constrói o AMI consegue derivar a lista de uma consulta de capacidade a cada build. Faltando qualquer uma delas, a condição ec2:InstanceType em SCP continua sendo a ferramenta certa, ela erra do lado de quem sabe pedir exceção. Não use isso como controle de FinOps, não escreva glob à mão e não ligue em AMI compartilhado sem antes rodar describe-images contra os launch templates que já apontam para ele. O recurso não custa nada e o default permissivo garante que nada quebre até você agir; o preço é integralmente de manutenção, e ele vence toda vez que a AWS lançar uma família nova. Se o seu time não tem onde pendurar essa manutenção, o padrão continua correto e a resposta ainda é não.

#EC2#AMI#golden image#Auto Scaling#Graviton#Spot#governance#FinOps
Compartilhar:LinkedInWhatsAppXBaixar em Markdown
Fonte analisada: Amazon EC2 now supports specifying compatible instance types on AMIs
Próximo passo
Trilha Arquiteto de IA, gratuitaFundamentos, LLMs, RAG, tools, MCP e arquitetura na AWS, em aulas curtas e interativas.Começar a trilhaAgentes de IA em produção na AWSComo eu desenho, oriento e audito agentes que vão ao ar, com os números e as fontes.Ver o IA Builder

Continue lendo

AWS & CloudWell-Architected Agent: a revisão de arquitetura vira processo semanalA AWS colocou em preview um agente que analisa contas, cruza sinais de Trusted Advisor, Compute Optimizer, Security Hub CSPM e Resilience Hub e devolve recomendações priorizadas por metas de negócio em texto livre. O que muda para o arquiteto não é o volume de achados, é que a meta escrita vira função de ranqueamento, e a lista de tipos de recurso não suportados vira ponto cego de auditoria.Ler AWS & CloudApps no Amazon Quick vs. App Studio vs. build próprioA AWS liberou no dia 1º de setembro de 2026 a construção de aplicações internas por linguagem natural dentro do Amazon Quick. A pergunta de arquitetura não é se funciona, é qual das quatro rotas disponíveis suporta o app depois que ele vira parte do fechamento mensal. Comparo assento vs. hora-usuário, propagação de identidade e custo de saída.Ler AWS & CloudMWAA com Airflow 3.3.1: estado, linguagem e disciplina operacionalEu vejo o suporte do Amazon MWAA ao Apache Airflow 3.3.1 como uma evolução importante para pipelines que não cabem mais no modelo puramente stateless. O ganho real está em estado durável, particionamento de assets e melhor ergonomia de operação; o risco está em tratar recursos experimentais como plataforma corporativa madura cedo demais.Ler
AnteriorDaemon crítico ou não-crítico: o contrato de falha do ECSPróximo3LO no Bedrock Managed KB: 5 minutos de setup, 1 decisão irreversível
Gostou desta análise? Receba a próxima.

Deep dives de arquitetura, AWS, IA e mercado: direto no seu email. Grátis.

Sem spam · cancele quando quiser

Pergunte ao Fernando sobre isto

Uma resposta focada sobre este artigo, do meu assistente de IA, baseada no meu trabalho.

Participe da conversa

Entre para comentar

Confirme seu e-mail para participar, você também recebe a newsletter. Sem senha.

Neste artigo
O problema: o contrato existia, mas não era executávelArquiteturaAnatomia: duas listas, uma ordem de avaliação, zero estadoTrês formas de restringir tipo de instância, e o que cada uma cobre de verdadeOnde o glob te trai: string não é predicado de arquiteturaO hard block em dia de incidente, e o sinal que ninguém instrumentaAntipadrõesWell-ArchitectedReferênciasVeredito