Lab 75 — Registry e promoção com rollback
O problema, e a empresa que o tem
A Cadência, o marketplace de material de construção com 40 lojistas parceiros do L70, usa desde o L72 um modelo de risco de fraude no checkout — o mesmo que o L73 tornou reproduzível a partir de um commit e de um dado. Ele decide em até 200 ms se aprova, manda para revisão manual ou bloqueia um pedido.
Há duas semanas, a Marcela, do time de risco e ML, retreinou o modelo com uma feature nova. A AUC no holdout subiu de 0,912 para 0,931. Pareceu decisão óbvia: ela rodou create-model e update-endpoint direto do notebook, sem passar por revisão de mais ninguém — o pipeline de treino do L73 já estava verde, e um número melhor no offline parecia razão suficiente para promover.
O modelo novo, porém, sub-pondera exatamente o sinal que pega um tipo específico de fraude — cartão de terceiro com endereço de entrega divergente. Ele deixa passar pedidos que o modelo antigo bloqueava. Em cinco dias, a taxa de chargeback por fraude subiu de 0,4% para 1,6% dos pedidos aprovados — cerca de R$ 42 mil em disputas extras — e ninguém percebeu por um alarme: percebeu pelo relatório financeiro semanal.
Quando o time tentou reverter, descobriu o segundo problema: o artifact do modelo anterior tinha sido sobrescrito no mesmo caminho do S3 pelo próprio treino que o substituiu. Não havia um modelo anterior para apontar — só o dado e o código para re-treinar do zero, enquanto o prejuízo seguia acumulando a cada pedido aprovado.
Identidade do pipeline vs. decisão de promover, lado a lado
O L54 resolveu QUEM tem permissão de publicar — federação OIDC, sem chave de longa duração. Este laboratório resolve uma pergunta diferente: dado que alguém TEM permissão de publicar, o que garante que a versão promovida foi revisada, está registrada, e pode ser desfeita depressa se estiver errada? A pipeline deste laboratório reaproveita a mesma role federada do L54 — a identidade não muda; o que muda é o que essa identidade é obrigada a fazer antes de servir tráfego real.
O que este laboratório NÃO é
Não é sobre como o modelo é treinado ou quais features usar — o L72 (feature store) e o L73 (experimento rastreável) já resolvem isso, e este módulo assume os dois prontos. Também não é sobre o MODO de servir o modelo: tempo real, serverless, assíncrono ou lote é escolha do L74, e este laboratório assume tempo real porque é o que o checkout da Cadência precisa. Aqui a pergunta é só uma: como uma versão nova de um modelo já treinado chega a servir tráfego real com segurança, e como voltar atrás se ela chegou errada.
O que você vai conseguir fazer
Objetivos verificáveis: cada um se prova com um comando na seção de implantação, não com a sensação de ter entendido Model Registry.
- Explicar por que um artifact de modelo com nome de arquivo e data não é a mesma coisa que uma versão registrada com status de aprovação.
- Registrar um Model Package num Model Package Group, anexando métrica offline e baseline de produção como metadata comparável.
- Configurar um estágio de aprovação manual bloqueante numa pipeline, disparado por evento de novo pacote pendente.
- Configurar um endpoint SageMaker com deployment blue/green e um peso inicial de tráfego para a variante candidata.
- Configurar um AutoRollbackConfiguration com alarme do CloudWatch, e explicar exatamente o que esse alarme protege e o que ele não protege.
- Medir o tempo de um rollback manual — de comando a endpoint servindo a versão anterior de novo.
- Diagnosticar por que uma promoção aprovada ainda causou prejuízo, distinguindo falha de aprovação de falha de rollback automático.
- Provar, com CloudTrail e o histórico do Model Registry, quem aprovou cada versão e quando.
O que a certificação cobra disto
| Conceito | Certificação | Como aparece aqui | O que dominar |
|---|---|---|---|
| Model Registry e Model Package Group | MLA-C01 | create_model_package grava métrica e status | a diferença entre um Model Package (uma versão) e o Group (o histórico de versões de um mesmo modelo) |
| Ciclo PendingManualApproval → Approved/Rejected | MLA-C01, DOP-C02 | estágio de aprovação manual espelhado no status do pacote | por que aprovar na pipeline sem atualizar o status no Registry deixa os dois sistemas dizendo coisas diferentes |
| Blue/Green deployment guardrails do SageMaker | MLA-C01, MLS-C01 | DeploymentConfig com peso inicial de 10% na variante candidata | a variante antiga continua ativa e servindo durante toda a janela de bake — não é uma troca instantânea |
| AutoRollbackConfiguration + alarme do CloudWatch | MLA-C01, DOP-C02 | alarme de erro e latência acoplado ao UpdateEndpoint | o rollback automático reage a sinal OPERACIONAL, não a métrica de negócio — é a lacuna que este laboratório nomeia |
| EventBridge como gatilho de pipeline de ML | MLA-C01, DOP-C02 | regra dispara a execução a partir do evento de novo pacote | por que orquestrar por evento evita depender de alguém lembrar de rodar a pipeline |
| Estágio de aprovação manual do CodePipeline | DOP-C02, SAA-C03 | estágio que bloqueia a pipeline até uma ação humana | a diferença entre aprovação BLOQUEANTE e uma notificação que não impede nada |
| Identidade do pipeline de ML vs. de aplicação | DOP-C02 | reaproveita a role federada OIDC do L54, sem chave nova | a mesma mecânica de identidade do L54 vale para publicar modelo, não só código |
Onde isto costuma ser cobrado errado
A pergunta clássica descreve um AutoRollbackConfiguration corretamente configurado e um incidente de qualidade de modelo descoberto dias depois, e pede o que está errado na arquitetura. A resposta não é 'o alarme deveria ter disparado' — o alarme fez exatamente o que a configuração pede. O erro de raciocínio mais comum é tratar rollback automático operacional como se fosse validação de qualidade de modelo: são duas coisas diferentes, com janelas de tempo diferentes, e só uma delas cabe numa automação de minutos.
Requisitos, e como cada um muda o desenho
Requisito que não aparece numa condição de pipeline ou numa linha de Terraform é intenção. A coluna da direita é onde cada um deixou marca.
| Requisito | Valor declarado | O que ele decide no desenho |
|---|---|---|
| Nenhuma promoção sem versão registrada | obrigatório, sem exceção | cada treino chama create_model_package em vez de create_model; publicar direto do notebook deixa de ser um caminho válido |
| Aprovação humana antes de servir tráfego real | obrigatória, com motivo registrado | estágio de Manual Approval na pipeline, disparado por evento do Registry — ninguém promove sozinho, e a decisão fica auditável |
| Sinal de negócio ao lado do offline | baseline de chargeback anexado ao pacote | metadata do Model Package carrega os dois números; o revisor nunca vê só a métrica que melhorou |
| Detecção operacional automática | durante a janela de bake do blue/green | AutoRollbackConfiguration com alarme de erro e latência — reversão sem depender de alguém perceber a tempo |
| Rollback sem re-treinar | medido, não presumido | a EndpointConfig anterior continua existindo enquanto o Model Package correspondente estiver Approved — reverter troca configuração, não reconstrói o modelo |
| Rastreabilidade de quem aprovou o quê | por versão, não por pessoa em geral | ApprovalDescription e CloudTrail (UpdateModelPackage) respondem quem aprovou esta versão numa única consulta |
| Reaproveitar identidade federada do pipeline | obrigatório | a role que a pipeline assume vem do provedor OIDC do L54 — nenhuma chave nova só para publicar modelo |
Arquitetura mínima: a promoção que ninguém registrou
Este é o desenho que a Cadência tinha até duas semanas atrás, e ele publica de verdade — é por isso que sobreviveu tanto tempo sem ninguém notar o problema. O laboratório começa por tornar o defeito visível, não por presumir que ele é óbvio.
- → grava o artifact no mesmo caminho, por cima do anterior
- → aponta create-model para o artifact mais recente do bucket
- → update-endpoint troca a versão ativa, sem aprovação de ninguém além de quem publicou
- → InvokeEndpoint síncrono a cada pedido, para decidir aprovar ou bloquear
- IA e machine learning
- Armazenamento
- Fora da AWS
- Conceito de arquitetura
- Compute
Este desenho publica, e é por isso que ninguém percebe o problema até o relatório financeiro aparecer: a métrica que melhora é a que alguém está olhando, e a que piora — chargeback de fraude — não tem ninguém olhando em tempo real. Percorra os passos e repare que o defeito central não é a decisão de promover; é a ausência de qualquer lugar para registrar essa decisão ou desfazê-la depressa.
- O treino mede uma métrica melhor, e isso parece o bastante. O job de treino do L73 roda de novo com uma feature nova, e a AUC no holdout sobe de 0,912 para 0,931. Não existe, neste desenho, nenhum lugar formal para registrar essa comparação — o número vive na tela de quem rodou o experimento.
- O artifact novo apaga o endereço do artifact antigo. model.tar.gz é gravado sempre na mesma chave do S3, sem versionamento de objeto habilitado e sem um Model Package com número de versão — o treino de hoje elimina fisicamente a possibilidade de apontar para o modelo que estava rodando ontem.
- Uma pessoa decide sozinha que o número basta. A Marcela aponta create-model para o artifact mais recente. Não existe um estágio que pare e peça a um segundo revisor — nem sequer um lugar onde ela precisaria registrar a decisão antes de publicar.
- update-endpoint troca a versão sem gate nenhum. A chamada de API que troca o modelo em produção é a mesma usada para qualquer atualização de infraestrutura — não existe uma etapa de aprovação entre a decisão de promover e o tráfego real batendo na versão nova.
- O checkout começa a servir a versão nova imediatamente. Cada pedido novo já é avaliado pelo modelo recém-publicado. Não há período de canário: 100% do tráfego troca de versão no instante em que update-endpoint retorna sucesso.
- Quando o prejuízo aparece, não há para onde voltar rápido. Cinco dias depois, o relatório financeiro mostra a taxa de chargeback subindo — não um alarme, um relatório. Reverter significaria re-treinar do zero, porque o artifact anterior já foi sobrescrito, e ninguém salvou uma cópia à parte.
- Por que alguém publica assim. Porque o pipeline de treino do L73 já estava verde, e uma métrica melhor no holdout parecia razão suficiente para promover. É a mesma lógica do L54 aplicada ao modelo em vez da identidade: o caminho mais curto funciona no primeiro dia e vira hábito antes de virar risco visível.
# auditar-a-promocao.sh -- meça a exposição real antes de mudar qualquer coisa
aws s3api list-object-versions --bucket cadencia-ml \
--prefix fraude-checkout/model.tar.gz \
--query "Versions[].{Key:Key,VersionId:VersionId,LastModified:LastModified}"
# Bucket sem versionamento habilitado: nenhuma versao anterior aparece -- o
# objeto de ontem simplesmente nao existe mais.
aws sagemaker list-model-package-groups \
--query "ModelPackageGroupSummaryList[].ModelPackageGroupName"
# Retorna vazio: nenhum modelo desta empresa jamais passou pelo Model Registry.
# Numero real da Cadencia: taxa de chargeback por fraude subiu de 0,4% para
# 1,6% dos pedidos aprovados em 5 dias -- e o time so descobriu no relatorio
# financeiro semanal, nao por um alarme.O prejuízo que ninguém alarmou
Não foi uma promoção sem cuidado nenhum — foi uma promoção com um número real de melhora (AUC de 0,912 para 0,931), decidida por uma pessoa competente, sem nenhum mecanismo que exigisse comparar com o que já estava em produção. Cinco dias e R$ 42 mil em chargeback depois, a causa raiz não foi o modelo em si: foi a ausência de qualquer coisa entre 'treino terminou' e 'tráfego real está sendo servido'.
Arquitetura para produção
Cada peça nova abaixo rastreia a uma linha da tabela de requisitos. Se você não conseguir apontar o requisito, a peça é adorno — e este desenho não tem nenhuma.
- → create_model_package com métricas, SHA do dado de treino e baseline anexados
- → novo pacote pendente dispara a execução via EventBridge
- → pausa e notifica, aguardando comparação com o baseline
- → aprova (ou rejeita) — a decisão fica registrada com o motivo
- → UpdateEndpoint com deployment blue/green e 10% de peso inicial
- → InvokeEndpoint sem saber qual variante responde
- → publica métrica de erro e latência por variante
- → alarme disparado reverte o peso para 0% na variante nova, automaticamente
- IA e machine learning
- Conceito de arquitetura
- Gestão e governança
- Segurança e identidade
- Compute
A diferença central não é 'aprovação a mais': é que a decisão de promover passa a acontecer ANTES de qualquer tráfego real mudar de versão, com os dois números — offline e baseline — lado a lado, e a reversão de uma falha operacional já não depende de ninguém estar olhando quando ela acontece. Percorra os passos: o gate humano e o alarme automático protegem coisas diferentes, e nenhum dos dois sozinho seria suficiente.
- O treino vira um pacote versionado, não um arquivo solto. create_model_package substitui create_model como a chamada de saída do treino. O pacote nasce com a métrica offline, o SHA do dado usado (rastreável até o L73) e o número de baseline de produção anexado como metadata — não só o número que melhorou.
- Todo pacote novo nasce pendente, nunca aprovado sozinho. ApprovalStatus começa em PendingManualApproval por configuração do grupo, e um evento do EventBridge dispara a execução da pipeline assim que o pacote é registrado — a promoção deixa de depender de alguém lembrar de rodar um comando.
- A pipeline para e espera uma decisão humana. O estágio de Manual Approval mostra os dois números lado a lado: a métrica offline que motivou o treino, e o baseline real de chargeback do modelo em produção — a pergunta que o revisor responde não é se o AUC subiu, é se isso deveria mudar o que está servindo tráfego real.
- Aprovar é um ato registrado, com motivo. A aprovação (ou rejeição) grava um comentário e o usuário no CloudTrail e no próprio Model Package. Não existe aprovação anônima nem aprovação sem que alguém tenha, de fato, olhado o baseline.
- A versão nova entra por uma fração do tráfego, não por inteiro. UpdateEndpoint troca a EndpointConfig usando um deployment blue/green: a variante nova recebe 10% do tráfego, a antiga continua servindo os outros 90%, e as duas ficam ativas ao mesmo tempo durante a janela de bake.
- O checkout não sabe, e não precisa saber, qual variante respondeu. O serviço de checkout chama sempre o mesmo InvokeEndpoint, com o mesmo nome de endpoint de sempre. Quem decide a fração de tráfego por variante é a configuração do SageMaker, não uma lógica que o time de aplicação precisa manter.
- Se o alarme dispara, o rollback muda peso, não código. AutoRollbackConfiguration observa o alarme durante a janela de bake. Se a taxa de erro ou a latência da variante nova ultrapassar o limiar, o SageMaker devolve 100% do peso para a variante antiga sozinho — sem uma chamada manual, sem uma pessoa de plantão precisando perceber primeiro.
A diferença estrutural em relação ao desenho anterior não é 'a mesma coisa com uma caixa a mais': é a existência de um registro versionado, de um estágio que bloqueia até decisão humana, e de duas variantes servindo ao mesmo tempo durante a troca. No desenho mínimo, promover e servir eram o MESMO instante. Aqui, promover é uma decisão registrada ANTES de qualquer tráfego real mudar.
O que o rollback automático NÃO protege
AutoRollbackConfiguration observa Invocation5XXErrors e latência da variante nova durante a janela de bake — minutos. Chargeback de fraude só se confirma em dias, depois que a disputa é processada pelo banco emissor do cartão. Um modelo pode passar pela janela de bake inteira sem erro técnico algum e ainda assim ser pior no trabalho que existe para fazer. O alarme automático é real e útil, mas ele resolve um problema diferente do que causou o incidente da Cadência — e tratar os dois como a mesma proteção é o erro que este laboratório existe para corrigir.
O que fica exatamente igual, de propósito
O serviço de checkout não muda uma linha de código: ele chama o mesmo InvokeEndpoint, com o mesmo nome de endpoint, antes, durante e depois de qualquer promoção ou rollback. A identidade que a pipeline usa para chamar a AWS também não muda — é a mesma role federada por OIDC do L54. Redesenhar consumo e identidade ao mesmo tempo que o mecanismo de promoção é o jeito mais comum de gastar uma tarde depurando o problema errado.
Uma promoção, ponta a ponta
O metadata que acompanha o Model Package não é burocracia: é o que faz o revisor comparar o número certo, em vez de só ver 'AUC melhorou'.
{
"ModelPackageGroupName": "fraude-checkout",
"ModelPackageDescription": "treino v42 - AUC offline 0.931",
"ModelApprovalStatus": "PendingManualApproval",
"CustomerMetadataProperties": {
"auc_offline": "0.931",
"baseline_producao_auc": "0.912",
"baseline_producao_chargeback_pct": "0.4",
"sha_dado_treino": "a1b2c3d4e5f6",
"experimento_l73": "exp-fraude-042"
}
}O campo que faz a diferença entre gate real e carimbo
Sem baseline_producao_auc e baseline_producao_chargeback_pct no metadata, o revisor vê só a métrica que melhorou — exatamente o que já acontecia no desenho mínimo, só que agora com um botão de 'Aprovar' na frente. O Model Registry aceita um Model Package sem esses campos; nada no schema obriga a comparação. É uma convenção da equipe, não uma trava técnica — e por isso a política de revisão de PR do time cobra a presença dos dois campos antes de qualquer merge que toque o script de treino.
As decisões, e o que se perde em cada uma
📋 Promover um modelo de risco de fraude para produção sempre que um treino terminar, com aprovação humana registrada e um jeito comprovadamente rápido de voltar para a versão anterior se a nova se comportar mal.
Resolve os três requisitos com serviços nativos do mesmo provedor que já hospeda o treino (L73): a versão nasce junto do artifact, a aprovação bloqueia antes de qualquer tráfego mudar, e o rollback tem duas velocidades — automático para falha operacional, manual e medido para o resto.
Alt: Deploy direto do notebook (create-model + update-endpoint) — É o desenho mínimo deste módulo: sem versão, sem aprovação, e é exatamente o que causou o incidente.
Alt: CI/CD genérico (o pipeline do L54) chamando update-endpoint sem Model Registry — Resolve identidade — nenhuma chave de longa duração — mas não resolve versão nem aprovação formal do MODELO; falta a metade do requisito deste laboratório.
Alt: Endpoint único sobrescrito direto, sem blue/green — Reverter significaria recriar o endpoint do zero a partir de um artifact salvo à parte — sem o tempo de rollback medido em segundos que este módulo entrega.
Alt: Aprovação assíncrona por chat ou planilha, fora do Registry — Não fica atada à versão nem é auditável por CloudTrail; a mesma decisão registrada de forma informal se perde na primeira limpeza de canal.
| Decisão | Escolha | Alternativas | Motivo | O que se perde |
|---|---|---|---|---|
| Mecanismo de versionamento | Model Registry (create_model_package) | S3 com nome de arquivo e data; MLflow/DVC externo; tag no nome do endpoint | nativo do SageMaker, liga métrica, aprovação e linhagem no mesmo objeto que o L73 já produz | acopla ao SageMaker — migrar de provedor de nuvem custaria reescrever este pedaço inteiro |
| Orquestração da aprovação | CodePipeline com estágio Manual Approval | aprovar direto no console do SageMaker; Step Functions com waitForTaskToken; planilha | reaproveita a mesma ferramenta e a mesma identidade federada do L54, sem sistema novo | fica preso ao modelo de 'estágio de pipeline', menos flexível que uma máquina de estado para fluxos com múltiplos revisores |
| Mecanismo de rollback | blue/green nativo do SageMaker + AutoRollbackConfiguration | endpoint único sobrescrito; dois endpoints com Route 53 ponderado; canário manual via script | nativo, sem infraestrutura extra para manter, e a variante antiga continua ativa até a promoção terminar | só entende sinal operacional — erro e latência —, não sinal de negócio |
| Sinal do rollback automático | alarme de erro/latência da variante candidata | métrica de negócio direta (chargeback em tempo real); nenhum alarme, só rollback manual | chargeback real leva dias para se confirmar — rápido demais não cabe numa janela de bake de minutos | não pega degradação de negócio sozinho; depende do gate de aprovação ter comparado bem e de um rollback manual igualmente rápido |
| Quem aprova | um revisor do time de risco | aprovação automática se a métrica offline melhorar; dois aprovadores obrigatórios | já é uma melhoria enorme sobre zero revisores; dois aprovadores é o nível 5 da evolução, não este módulo | continua sendo um único ponto de decisão — se o revisor não olhar o baseline de verdade, o gate vira carimbo |
A dívida que este laboratório não paga
O gate de aprovação só é tão bom quanto o revisor que olha o baseline. Este módulo não constrói um segundo revisor automático nem uma regra que bloqueie promoção com baseline pior — isso é decisão de processo do time de risco, fora do escopo de infraestrutura. Uma pipeline com aprovação bloqueante e um revisor que clica 'Aprovar' sem olhar nada é só um jeito mais lento de cometer o mesmo erro.
Construir: o Model Package Group e quem pode aprovar
Esta é a peça que faz o modelo deixar de ser um arquivo solto. Tudo o que vem depois — pipeline, aprovação, rollback — existe porque o pacote tem um lugar formal para nascer.
# model_registry.tf -- o Model Package Group, e quem pode mudar o status
resource "aws_sagemaker_model_package_group" "fraude_checkout" {
model_package_group_name = "fraude-checkout"
model_package_group_description = "Modelo de risco de fraude no checkout (L73 -> L75)"
tags = {
Projeto = var.projeto
Time = "risco-e-ml"
}
}
# Politica do grupo: quem pode LER versoes e quem pode MUDAR ApprovalStatus.
# Sem isto, qualquer principal com sagemaker:UpdateModelPackage na conta
# consegue aprovar o proprio modelo -- o mesmo problema do PassRole sem
# Resource do L54, so que aplicado a aprovacao em vez de identidade de deploy.
data "aws_iam_policy_document" "aprovar_modelo" {
statement {
sid = "AprovarVersao"
effect = "Allow"
actions = ["sagemaker:UpdateModelPackage", "sagemaker:DescribeModelPackage"]
resources = ["${aws_sagemaker_model_package_group.fraude_checkout.arn}/*"]
principals {
type = "AWS"
identifiers = [aws_iam_role.revisor_risco.arn] # so o papel do revisor, nunca a conta inteira
}
}
}
resource "aws_sagemaker_model_package_group_policy" "fraude_checkout" {
model_package_group_name = aws_sagemaker_model_package_group.fraude_checkout.model_package_group_name
resource_policy = data.aws_iam_policy_document.aprovar_modelo.json
}Por que restringir quem aprova, e não só quem treina
A role de treino (do L73) e a role de aprovação são propositalmente diferentes. Se a mesma identidade que treina também pode aprovar, o gate de segundo revisor deixa de existir na prática — é a mesma pessoa validando o próprio trabalho, mesmo que a ferramenta mostre um botão de 'Aprovar' separado do botão de 'Treinar'.
Construir: a pipeline de promoção com aprovação
A pipeline reaproveita a role federada por OIDC do L54 — nenhuma chave nova só para publicar modelo. O que muda é o que essa identidade é obrigada a esperar antes de agir.
# pipeline_promocao.tf
resource "aws_codepipeline" "promocao_modelo" {
name = "${var.projeto}-promocao-fraude-checkout"
role_arn = aws_iam_role.deploy_pipeline.arn # a MESMA role federada por OIDC do L54
artifact_store {
location = aws_s3_bucket.artefatos_pipeline.bucket
type = "S3"
}
stage {
name = "Origem"
action {
name = "NovoPacotePendente"
category = "Source"
owner = "AWS"
provider = "EventBridge"
version = "1"
output_artifacts = ["pacote_pendente"]
}
}
stage {
name = "Aprovacao"
action {
name = "RevisarBaselineEAprovar"
category = "Approval"
owner = "AWS"
provider = "Manual"
version = "1"
configuration = {
# O revisor ve este texto na hora de decidir -- e por isso o pacote
# carrega o baseline como metadata, nao so a metrica que melhorou.
CustomData = "Compare auc_offline com baseline_producao_auc e baseline_producao_chargeback_pct antes de aprovar."
}
}
}
stage {
name = "Promover"
action {
name = "AtualizarEndpointBlueGreen"
category = "Build"
owner = "AWS"
provider = "CodeBuild"
version = "1"
input_artifacts = ["pacote_pendente"]
configuration = {
ProjectName = aws_codebuild_project.promover_endpoint.name
}
}
}
}
# Dispara a pipeline no instante em que um Model Package novo entra como
# PendingManualApproval -- ninguem precisa lembrar de rodar isto a mao.
resource "aws_cloudwatch_event_rule" "novo_pacote_pendente" {
name = "${var.projeto}-novo-pacote-modelo"
event_pattern = jsonencode({
source = ["aws.sagemaker"]
"detail-type" = ["SageMaker Model Package State Change"]
detail = {
ModelPackageGroupName = [aws_sagemaker_model_package_group.fraude_checkout.model_package_group_name]
ModelApprovalStatus = ["PendingManualApproval"]
}
})
}
resource "aws_cloudwatch_event_target" "dispara_pipeline" {
rule = aws_cloudwatch_event_rule.novo_pacote_pendente.name
arn = aws_codepipeline.promocao_modelo.arn
role_arn = aws_iam_role.eventbridge_para_pipeline.arn
}# buildspec-promover-endpoint.yml
version: 0.2
phases:
install:
commands:
- pip install boto3
build:
commands:
- echo "Model Package aprovado: $MODEL_PACKAGE_ARN"
- python promover_endpoint.py --model-package-arn "$MODEL_PACKAGE_ARN" \
--endpoint-name fraude-checkout \
--peso-inicial 10
# promover_endpoint.py chama update_endpoint -- o DeploymentConfig
# blue/green e o AutoRollbackConfiguration ja estao na EndpointConfig
# declarada no Terraform; este script so decide QUAL versao entra.
artifacts:
files:
- relatorio-promocao.jsonConstruir: o endpoint com blue/green e rollback automático
O alarme nasce antes do endpoint que o referencia — é ele que dá ao SageMaker o sinal para reverter sozinho.
# endpoint_blue_green.tf
resource "aws_cloudwatch_metric_alarm" "erro_variante_nova" {
alarm_name = "${var.projeto}-fraude-checkout-erro-variante-nova"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 2
metric_name = "Invocation5XXErrors"
namespace = "AWS/SageMaker"
period = 60
statistic = "Sum"
threshold = 5 # mais de 5 erros 5xx por minuto, duas vezes seguidas
dimensions = {
EndpointName = "fraude-checkout"
VariantName = "candidata"
}
}
resource "aws_sagemaker_endpoint" "fraude_checkout" {
name = "fraude-checkout"
endpoint_config_name = aws_sagemaker_endpoint_configuration.candidata.name
deployment_config {
blue_green_update_policy {
traffic_routing_configuration {
type = "CANARY"
wait_interval_in_seconds = 600 # 10 min de bake antes de subir o peso
canary_size {
type = "CAPACITY_PERCENT"
value = 10
}
}
termination_wait_in_seconds = 300 # a variante antiga so sai depois desta folga
}
auto_rollback_configuration {
alarms {
alarm_name = aws_cloudwatch_metric_alarm.erro_variante_nova.alarm_name
}
}
}
}// FraudeCheckoutClient.cs -- o consumidor nao muda nada durante a promocao
public sealed class FraudeCheckoutClient
{
private readonly IAmazonSageMakerRuntime _runtime;
private const string EndpointName = "fraude-checkout"; // nunca muda, mesmo em rollback
public FraudeCheckoutClient(IAmazonSageMakerRuntime runtime) => _runtime = runtime;
public async Task<ScoreFraude> AvaliarAsync(Pedido pedido, CancellationToken ct)
{
var payload = JsonSerializer.SerializeToUtf8Bytes(pedido.ParaFeatures());
var resposta = await _runtime.InvokeEndpointAsync(new InvokeEndpointRequest
{
EndpointName = EndpointName, // o peso entre variantes decide quem responde
ContentType = "application/json",
Body = new MemoryStream(payload)
}, ct);
return ScoreFraude.Desserializar(resposta.Body);
// Se um rollback automatico disparar no meio de uma promocao, este codigo
// nao percebe: o nome do endpoint e identico antes, durante e depois.
}
}Por que 10% de peso inicial, e não 50%
Um peso baixo limita quantos pedidos reais o modelo candidato avalia antes do bake terminar — se ele estiver claramente pior num jeito que o alarme operacional pega (erro, latência), o dano fica contido a uma fração pequena do tráfego. Não protege contra o cenário da Cadência, em que o modelo funciona tecnicamente bem e erra silenciosamente; para isso, o gate é a aprovação humana da seção anterior, não o percentual do canário.
Implantar, e provar que o rollback funciona
Quatro provas. Nenhuma aceita 'a pipeline ficou verde' como resultado — cada uma tem um comando e um número que reprova nomeado.
# provas.sh -- quatro medicoes; nenhuma conclusao vem de "a pipeline ficou verde"
GRUPO="fraude-checkout"
ENDPOINT="fraude-checkout"
# --- Prova 1: promover sem aprovacao falha -----------------------------------
aws sagemaker update-endpoint --endpoint-name "$ENDPOINT" \
--endpoint-config-name config-pendente-sem-aprovacao \
&& echo "FALHA DA PROVA: endpoint aceitou pacote nao aprovado" \
|| echo "OK: SageMaker recusa EndpointConfig atrelada a pacote PendingManualApproval"
# --- Prova 2: o rollback MANUAL tem um tempo medido, nao "deveria ser rapido" --
INICIO=$(date +%s)
aws sagemaker update-endpoint --endpoint-name "$ENDPOINT" \
--endpoint-config-name "$(cat ultima-config-approved.txt)"
aws sagemaker wait endpoint-in-service --endpoint-name "$ENDPOINT"
FIM=$(date +%s)
echo "Rollback manual completo em $((FIM-INICIO)) segundos"
# Medido na Cadencia: 41 segundos, do comando ao endpoint InService de novo
# servindo a variante anterior -- contra os 5 DIAS que levou para notar o
# problema no cenario minimo.
# --- Prova 3: o rollback AUTOMATICO dispara sozinho, sem chamada manual -----
for i in $(seq 1 20); do curl -s -o /dev/null -X POST "$URL_TESTE_CANDIDATA"; done
aws cloudwatch describe-alarms --alarm-names fraude-checkout-erro-variante-nova \
--query "MetricAlarms[].StateValue"
# Esperado: ALARM, seguido em minutos por um evento de rollback automatico no
# historico do endpoint -- sem ninguem ter chamado update-endpoint de novo.
# --- Prova 4: a versao anterior continua aprovada e pronta para servir ------
aws sagemaker list-model-packages --model-package-group-name "$GRUPO" \
--model-approval-status Approved \
--query "ModelPackageSummaryList[].{Versao:ModelPackageVersion,Status:ModelApprovalStatus}"
# Duas linhas Approved -- a antiga (que voltou a servir) e a nova (rejeitada ou
# ainda pendente de nova revisao) -- nenhuma delas foi apagada pelo rollback.| Prova | Comando | Resultado que aprova | O que reprova, e o que significa |
|---|---|---|---|
| 1 · Promoção sem aprovação falha | update-endpoint com config de pacote pendente | chamada recusada | se aceito, o gate de aprovação não está bloqueando a promoção de verdade |
| 2 · Rollback manual medido | update-endpoint para a config Approved anterior, com cronômetro | endpoint InService com a versão antiga em menos de um minuto | acima de poucos minutos indica que a config anterior foi apagada ou é preciso re-treinar |
| 3 · Rollback automático dispara sozinho | erro sintético na variante candidata + describe-alarms | alarme em ALARM, seguido de reversão automática de peso | se o peso não voltar sozinho, o AutoRollbackConfiguration não está referenciando o alarme certo |
| 4 · Versão anterior continua disponível | list-model-packages filtrando Approved | duas versões Approved, nenhuma apagada | só uma versão Approved significa que o rollback já não tem para onde voltar na próxima vez |
Quebrar de propósito: três falhas e o diagnóstico
As três acontecem de verdade em times adotando Model Registry pela primeira vez, e as três se parecem no sintoma superficial — 'a promoção causou o mesmo tipo de problema de antes'. O que separa é ONDE a proteção falhou.
| Falha | Como provocar | Sintoma | Onde olhar | Correção |
|---|---|---|---|---|
| Aprovar sem checar o baseline | clicar em Aprovar sem abrir o CustomData da ação | modelo pior aprovado mesmo com o gate existindo | ApprovalDescription vazia ou genérica no Model Package | exigir que o comentário de aprovação cite os dois números, não só 'ok' |
| Alarme de rollback com limiar alto demais | configurar threshold acima do erro real de operação | variante ruim segue recebendo peso crescente mesmo com erro alto | histórico do alarme mostrando estado OK durante um incidente confirmado | recalibrar o threshold com a taxa de erro real medida antes do laboratório |
| EndpointConfig anterior apagada por limpeza automática | rotina de 'limpar recursos não usados' remove configs antigas | rollback manual falha porque a config antiga não existe mais | describe-endpoint-config retornando 404 na hora do rollback | nunca apagar EndpointConfig referenciada por um Model Package ainda Approved |
A combinação que anula todo o esforço deste laboratório
Um estágio de aprovação que aprova sem comparar, mais um rollback manual que não funciona porque a config antiga sumiu, é pior do que o desenho mínimo: parece seguro — tem Registry, tem pipeline, tem botão de aprovar — mas na hora do incidente real nenhuma das três peças novas ajuda. A prova 2 da seção anterior existe justamente para pegar essa combinação antes que ela apareça num incidente de verdade.
O endpoint da Cadência tem AutoRollbackConfiguration com alarme de erro 5xx da variante nova. Cinco dias depois de uma promoção aprovada, o financeiro relata alta de chargeback — mas o alarme nunca disparou e o rollback automático nunca aconteceu. O que isso significa?
Segurança: o que muda quando aprovar vira um ato registrado
Registrar quem aprova não elimina o risco de uma aprovação ruim — move o risco para quem tem permissão de aprovar, e para o que acontece se essa aprovação for a única linha de defesa.
| Risco | Probabilidade | Impacto | Prevenção | Detecção | Resposta |
|---|---|---|---|---|---|
| Aprovador aprova sem checar baseline (carimbo) | média | alto | metadata obrigatória com baseline anexado, revisão em pares no nível 5 da evolução | auditoria de ApprovalDescription vazia ou genérica | reverter a promoção e cobrar preenchimento antes de reabrir o estágio |
| Resource policy do grupo sem Resource restrito | baixa | alto | resource policy do Model Package Group restrita à role específica do revisor | IAM Access Analyzer sobre a policy do grupo | apertar Resource/Principal e revisar aprovações feitas fora do papel esperado |
| Alarme de rollback automático mal calibrado | média | médio | calibrar limiar com a taxa de erro real, revisar após cada bake | histórico do alarme mostrando threshold nunca cruzado mesmo com erro confirmado | recalibrar e reprocessar o bake da próxima promoção com o novo limiar |
| EndpointConfig anterior apagada por limpeza automática | baixa | alto | retenção amarrada ao status Approved do Model Package correspondente | describe-endpoint-config falhando no momento do rollback | nunca apagar config referenciada por pacote Approved; recriar a partir do artifact se já tiver sumido |
| Chave pessoal reintroduzida 'de garantia' para publicar direto | média | alto | reaproveitar a identidade federada do L54; nenhuma chave nova para SageMaker | CloudTrail mostrando create_model_package ou update_endpoint chamado por IAMUser, não AssumedRole | desativar a chave — a mesma lição do L54, agora aplicada à publicação de modelo |
O aprovador único é um ponto de falha, não só de atraso
Com um único revisor autorizado, comprometer essa identidade — ou simplesmente ela estar de férias e alguém 'emprestar' o acesso — derruba a única linha de defesa humana deste desenho inteiro. É um risco financeiro real, não hipotético: o incidente que abriu este laboratório já mostrou o que uma promoção mal avaliada custa. O nível 5 da evolução (revisão em dupla) existe para fechar exatamente esta lacuna, e vale a pena adotá-lo assim que o volume de promoções justificar.
Observabilidade: as perguntas que o painel tem de responder
Um painel de promoção de modelo tem uma função que o painel de deploy de código não tinha: mostrar não só que a troca funcionou tecnicamente, mas que alguém de fato decidiu que ela deveria acontecer.
| Pergunta | Métrica ou consulta | O que significa mudar | Limiar inicial |
|---|---|---|---|
| Alguma promoção aconteceu sem aprovação registrada? | CloudTrail: UpdateModelPackage com ApprovalDescription vazia | regressão para o comportamento do desenho mínimo | qualquer ocorrência |
| Quanto tempo um pacote fica pendente antes de decisão? | timestamp de create_model_package até update_model_package | aprovador sobrecarregado ou processo travado | acima de 24 h |
| O rollback automático já disparou, e quando? | histórico do alarme + evento de rollback do endpoint | confirma que o mecanismo funciona de verdade, não só na teoria | todo disparo investigado, mesmo que correto |
| A taxa de chargeback da variante nova diverge da antiga? | métrica de negócio calculada em lote no dia seguinte | sinal que o alarme operacional NÃO cobre — é o que o incidente real precisava | acima do baseline mais uma margem |
| Quantas versões ficam Rejected, e por quê? | list-model-packages filtrando Rejected | mede se o gate está filtrando de verdade ou só carimbando aprovação | acompanhar tendência mês a mês |
A métrica que precisa de um painel separado, e por quê
A taxa de chargeback por variante não vem do CloudWatch em tempo real — vem de um job em lote que cruza pedidos aprovados com disputas confirmadas, normalmente no dia seguinte ou depois. Ela não alimenta o AutoRollbackConfiguration porque não existe rápido o bastante para isso; ela alimenta o painel que o revisor consulta antes da PRÓXIMA aprovação, fechando o loop que a promoção anterior deixou aberto.
Escala: um modelo, vários modelos, uma organização
| Volume | O que acontece com versão e aprovação | O que passa a doer | O que fazer |
|---|---|---|---|
| 1 modelo, poucas promoções por mês | um grupo, um pipeline, um revisor | nada; é o cenário deste laboratório | nada |
| Vários modelos do mesmo domínio (fraude, crédito, recomendação) | um Model Package Group por modelo, pipeline reutilizável | manter N pipelines quase idênticos manualmente | módulo Terraform reutilizável, um por modelo (padrão do L55) |
| Múltiplos ambientes (staging/produção) | aprovação por ambiente, não só por modelo | a mesma aprovação promovendo direto em produção sem passar por staging | conta por ambiente (L56), gate de aprovação restrito por conta |
| Dezenas de modelos, vários times | governança central sobre quem pode aprovar o quê | auditar aprovação modelo a modelo deixa de escalar | Access Analyzer organizacional + revisão em dupla obrigatória |
O gargalo que só aparece com muitos modelos
Um revisor humano por modelo escala linearmente com o número de modelos — dobrar os modelos de risco dobra o trabalho de revisão, não o tanto de infraestrutura. É um limite de PROCESSO, não de capacidade da AWS, e nenhum Terraform novo resolve; resolve-se com revisão em dupla distribuída entre mais pessoas (nível 5) ou com o meta-modelo de risco do nível 6, que prioriza quais promoções merecem mais atenção humana.
Custo: o que este laboratório acrescenta à fatura
| Dimensão | Cobra por | Cuidado |
|---|---|---|
| Model Registry (grupo e pacotes) | nada — metadata não tem linha de cobrança própria | não confundir com o armazenamento do artifact no S3, que cobra à parte |
| CodePipeline | pipeline ativo por mês, mais execução acima da faixa gratuita | poucas promoções por mês dificilmente estouram a faixa gratuita |
| Endpoint durante o blue/green | dobra de instâncias na janela de bake — as duas variantes rodam ao mesmo tempo | 10 minutos de bake custam pouco; um bake configurado para horas dobra o custo por esse tempo todo |
| CloudWatch (alarme e métricas) | métrica custom além do free tier mais avaliação de alarme | poucos alarmes por endpoint não é o item que domina a fatura de ML — confira no Pricing Calculator |
O ganho de custo que não está na fatura da AWS
O ganho real não é uma linha de infraestrutura mais barata: é comparar os R$ 42 mil em chargeback do incidente que abriu este laboratório com o custo de rodar um Model Package Group, uma pipeline com poucas execuções por mês e uma janela de bake de dez minutos por promoção. A diferença de ordem de grandeza é o argumento que justifica o esforço de implementar isto antes do próximo incidente, não depois.
Well-Architected nos seis pilares
| Pilar | Situação ao fim deste laboratório | Risco que fica | Melhoria | Prioridade |
|---|---|---|---|---|
| Excelência operacional | toda promoção passa por Registry, aprovação e bake antes de servir 100% do tráfego | ainda depende de um revisor humano interpretar o baseline corretamente | checklist de revisão anexado ao CustomData da aprovação | média |
| Segurança | resource policy restringe quem aprova; identidade do pipeline federada, sem chave nova | aprovador único é ponto de falha único para decisão de negócio | revisão em dupla obrigatória (nível 5 da evolução) | alta |
| Confiabilidade | rollback automático operacional e rollback manual medido em segundos | nenhum dos dois cobre degradação de negócio detectada só em lote, dias depois | painel de chargeback por variante alimentando a PRÓXIMA aprovação | alta |
| Eficiência de performance | bake de 10 min limita exposição da variante nova a uma fração pequena de tráfego | instâncias em dobro durante o bake, ainda que por pouco tempo | ajustar wait_interval_in_seconds com dado real de estabilização, não com o padrão | baixa |
| Otimização de custos | nenhum recurso novo cobrando fora da janela de promoção | nenhum ainda — volume baixo de promoções não justifica otimização | reavaliar se o número de modelos crescer uma ordem de grandeza | baixa |
| Sustentabilidade | instâncias extras do bake existem só durante a janela de troca | nenhum além do padrão do serviço gerenciado | nenhuma ação necessária no volume atual | baixa |
Evolução em níveis: o que muda, e o que passa a doer
A terceira arquitetura não é um desenho: é a resposta a quando trocar de mecanismo de promoção. Cada nível resolve um risco e compra outro.
Deploy manual com create-model direto do notebook, artifact sobrescrito no mesmo caminho do S3. É onde a Cadência estava.Model Registry versionando cada treino, CodePipeline com aprovação bloqueante, endpoint em blue/green com rollback automático operacional.Resource policy do Model Package Group passa a exigir dois aprovadores distintos, nenhum deles o autor do treino.Staging com dados sintéticos e produção em contas diferentes (L56), cada uma com seu próprio gate de aprovação federado pela mesma identidade do L54.Access Analyzer sobre quem pode aprovar em toda a organização, revisão em dupla obrigatória por política central, catálogo de todos os Model Package Groups da empresa.O histórico de promoções — métrica declarada, baseline, decisão do revisor, e o resultado real de negócio observado dias depois — vira DADOS. Um MODELO treinado sobre esse histórico aprende a prever quais promoções têm maior chance de degradar o negócio, mesmo passando pelo bake sem erro operacional, e prioriza a atenção do revisor humano onde o risco calculado é mais alto.A ordem não é negociável, e o motivo é concreto
O nível 6 depende de correlacionar cada promoção a um resultado de negócio observado depois — que depende do nível 2 ter dado a cada promoção uma versão registrada e uma aprovação rastreável. Sem isso, 'quais promoções tendem a degradar o negócio' não tem como ser respondido por dado nenhum, porque não existe um histórico estruturado de promoção: existiria só um log genérico de create-model chamado direto do notebook.
Onde IA entra nesta arquitetura, e onde não entra
O modelo de risco de fraude já É IA — mas a pergunta desta seção é outra: este mecanismo de PROMOÇÃO (versionar, aprovar, reverter) se beneficia de IA? Neste módulo, não, e forçar seria o antipadrão que a própria série existe para evitar.
A decisão de aprovar ou rejeitar uma versão, comparando dois números declarados contra um limiar de bom senso, é um julgamento humano informado por dado — não um problema que um segundo modelo resolveria melhor hoje, com o volume de promoções que a Cadência tem. O lugar onde IA acrescentaria valor real é o do Nível 6: graduar RISCO por promoção, em vez de dar a mesma atenção a toda mudança.
| Pergunta | Resposta honesta para este módulo |
|---|---|
| Qual problema a IA resolveria? | priorizar a atenção do revisor humano nas promoções com maior histórico de causar degradação de negócio, não em toda mudança igualmente |
| Por que uma regra não bastaria? | uma regra cobre o caso óbvio — 'métrica offline pior → rejeitar automaticamente'. IA só se justifica depois que regras simples mostrarem o limite delas, que é justamente o caso da Cadência: a métrica offline estava MELHOR |
| De onde viriam os dados? | histórico de Model Package (métrica declarada, baseline, decisão do revisor) cruzado com o resultado de negócio observado em lote nos dias seguintes — tudo já produzido por este laboratório |
| Qual o risco? | aprender de poucos incidentes (a Cadência promove um modelo algumas vezes por mês) e classificar uma promoção arriscada como segura, ou o oposto |
| Por que não agora? | porque o volume de promoções da Cadência ainda não gera dado suficiente para treinar esse avaliador com confiança — é honesto dizer que a resposta certa hoje é o revisor humano com o baseline na tela |
O uso de IA que parece atraente e é armadilha aqui
Pedir a um modelo para 'decidir se esta promoção deveria ser aprovada' trocaria uma comparação que o revisor consegue fazer em minutos — offline versus baseline, com contexto de negócio que só um humano tem — por uma decisão automatizada sem esse contexto. O incidente que abriu este laboratório não foi causado por falta de modelo de decisão; foi causado por ninguém ter comparado os dois números. IA não substitui essa comparação; ela só teria valor DEPOIS que a comparação já for rotina, priorizando onde ela precisa ser mais cuidadosa.
Anti-padrões deste laboratório
| Anti-padrão | Por que alguém faz | Por que é problema | Sintoma em produção | Forma correta |
|---|---|---|---|---|
| Promover direto do notebook, sem Registry | o pipeline de treino do L73 já estava verde, parecia suficiente | nenhuma versão, nenhuma aprovação, nenhum caminho de rollback além de re-treinar | modelo pior servindo tráfego real sem ninguém ter revisado a troca | create_model_package sempre, e update-endpoint só via pipeline |
| Aprovar automaticamente sempre que a métrica offline melhora | parece reduzir fricção e acelerar a entrega de melhorias | reproduz o incidente da Cadência com um verniz de Registry por cima — versionado, mas ainda sem ninguém decidindo de fato | métrica offline melhor, resultado de negócio pior, descoberto só dias depois | aprovação sempre bloqueante, comparando com o baseline de produção |
| Configurar rollback automático só com alarme operacional | métrica de negócio real (chargeback) leva dias para se confirmar, e é mais difícil de instrumentar do que erro 5xx | cria falsa sensação de proteção completa — o rollback existe, mas não cobre o tipo de falha que mais importa aqui | endpoint saudável tecnicamente, negócio perdendo dinheiro sem nenhum alarme disparando | alarme operacional automático MAIS um painel de negócio alimentando a próxima aprovação |
| Sobrescrever o artifact no mesmo prefixo do S3 | é o caminho de menor esforço herdado do primeiro script de treino, antes de existir Registry | elimina fisicamente a possibilidade de apontar para a versão anterior | rollback vira 're-treinar do zero', com o prejuízo acumulando enquanto isso | create_model_package versiona o artifact junto da metadata, sem depender de convenção de nome de arquivo |
| Nunca exercitar o rollback de propósito | 'deve funcionar, é um recurso nativo da AWS' — ninguém testou de fato | a primeira vez que o rollback roda de verdade costuma ser durante um incidente real, o pior momento para descobrir que ele está quebrado | rollback falha por EndpointConfig apagada, ou por role sem a permissão certa, bem no meio do incidente | prova 2 desta série (rollback manual medido) faz parte da rotina de implantação, não só do incidente |
| Um único aprovador, sem revisão em dupla | menos gente para coordenar, decisão mais rápida | aprovador vira ponto único de falha para uma decisão com impacto financeiro real | promoção ruim aprovada sem segunda opinião, ou aprovador indisponível travando toda promoção | revisão em dupla (nível 3 da evolução) assim que o volume de promoções justificar |
Quando algo não funciona
| Sintoma | Causa provável | Como investigar | Onde olhar | Correção |
|---|---|---|---|---|
| `AccessDeniedException` em `UpdateModelPackage` | o principal que tentou aprovar não é a role restrita na resource policy do grupo | compare o principal da chamada com o Resource/Principal da policy do grupo | resource policy do Model Package Group | adicionar a role certa à policy, nunca abrir para a conta inteira |
| Pipeline não inicia após um treino terminar | a regra do EventBridge não casa com o padrão do evento emitido | confira o event pattern contra um evento real de 'SageMaker Model Package State Change' | aws_cloudwatch_event_rule e o payload do evento no CloudTrail | ajustar ModelPackageGroupName e ModelApprovalStatus no event_pattern |
| Rollback automático não dispara mesmo com erro alto | o alarme não está referenciado no AutoRollbackConfiguration, ou o threshold está alto demais | compare o alarme configurado no endpoint com o que realmente foi criado | bloco deployment_config do aws_sagemaker_endpoint | referenciar o alarm_name certo e recalibrar o threshold com dado real |
| Aprovação feita, mas endpoint não atualizou | a etapa Build da pipeline falhou silenciosamente após a aprovação | veja o log de execução do CodeBuild do estágio Promover | console do CodePipeline, execução da ação AtualizarEndpointBlueGreen | corrigir o script promover_endpoint.py ou a permissão da role para chamar UpdateEndpoint |
| Custo do endpoint dobrou durante uma promoção | comportamento esperado do blue/green — as duas variantes rodam ao mesmo tempo na janela de bake | confira a duração configurada em wait_interval_in_seconds contra o custo observado | Cost Explorer filtrando por EndpointName | não é bug; ajustar a janela de bake se o custo for desproporcional ao benefício de segurança |
| Rollback manual falha com `ValidationException` | a EndpointConfig anterior foi apagada por uma rotina de limpeza | describe-endpoint-config pelo nome salvo em ultima-config-approved.txt | eventos de delete no CloudTrail para aws_sagemaker_endpoint_configuration | recriar a config a partir do Model Package Approved, e revisar a política de retenção |
A pergunta que resolve metade destes casos
Antes de mexer em Terraform, pergunte: a falha aconteceu na APROVAÇÃO (ninguém decidiu, ou decidiu sem permissão) ou na EXECUÇÃO (decidiram, mas a troca técnica não aconteceu)? A primeira aparece como AccessDenied ou pipeline parada; a segunda como erro na etapa de Build depois de uma aprovação registrada com sucesso. São diagnósticos diferentes atrás do mesmo 'a promoção não aconteceu'.
Limpeza: o que o destroy não leva
O endpoint em blue/green e o histórico do Model Registry são as duas coisas que mais sobrevivem a um `terraform destroy` incompleto — o primeiro por continuar cobrando por instância, o segundo por ficar como metadata órfã que confunde a próxima promoção.
# limpar.sh
terraform destroy -auto-approve
# 1. ENDPOINT: confirme que nao ficou nenhuma instancia por tras dele.
aws sagemaker describe-endpoint --endpoint-name fraude-checkout 2>&1 | grep -q . \
&& echo "AINDA EXISTE: cobra por instancia-hora enquanto estiver de pe" \
|| echo "OK: endpoint removido"
# 2. MODEL PACKAGE GROUP: nao cobra, mas apagar perde o historico de
# aprovacao -- confirme que e realmente o fim do modelo, nao so do
# laboratorio.
aws sagemaker list-model-packages --model-package-group-name fraude-checkout
# 3. PIPELINE E EVENTBRIDGE: confirme que a regra nao ficou apontando para
# uma pipeline que ja nao existe -- regra orfa nao cobra, mas falha em
# silencio na proxima vez que alguem depender dela.
aws events list-rules --name-prefix ffv-lab-novo-pacote-modelo
# 4. Prova final: nada com o nome do projeto de pe que nao devia estar.
aws resourcegroupstaggingapi get-resources \
--tag-filters Key=Projeto,Values=ffv-lab --query "ResourceTagMappingList[].ResourceARN"| Recurso | Sai no destroy? | Cobra parado? | Por que fica |
|---|---|---|---|
| Endpoint SageMaker (as duas variantes) | sim, se administrado por este Terraform | sim, por instância-hora | é o item mais caro do laboratório — confirme a remoção, não presuma |
| Model Package Group e suas versões | sim, se explicitamente apagado | não | metadata não tem custo, mas apagar perde o histórico de aprovação e o baseline de todas as promoções passadas |
| CodePipeline e o CodeBuild do estágio Promover | sim | não parado, só por execução | sem execução ativa, uma pipeline ociosa não gera cobrança contínua |
| Regra do EventBridge | sim | não | regras não cobram, mas uma regra órfã aponta para uma pipeline que já não existe |
| Alarme do CloudWatch | sim | não além do free tier | poucos alarmes por endpoint não é o item que domina a fatura |
Resumo: problema, peça e motivo
| Problema | Peça | Por que ela, e não outra |
|---|---|---|
| Artifact sobrescrito, sem versão endereçável | Model Package Group + create_model_package | cada treino vira uma versão com metadata, em vez de um arquivo que o próximo treino apaga |
| Promoção decidida por uma pessoa, sem revisão | estágio de Manual Approval bloqueante na pipeline | ninguém promove sozinho, e a decisão fica registrada com motivo, não só com um clique |
| Métrica offline sem comparação com produção | baseline anexado como metadata do Model Package | o revisor vê os dois números lado a lado, não só o que melhorou |
| Falha operacional só descoberta depois de afetar todo o tráfego | blue/green com AutoRollbackConfiguration | a variante nova recebe uma fração do tráfego, e reverte sozinha se um alarme técnico disparar |
| Reverter significava re-treinar do zero | EndpointConfig anterior preservada enquanto Approved | rollback manual vira troca de configuração, medida em segundos, não em dias |
| Redesenhar identidade junto com o mecanismo de promoção | reaproveitar a role federada OIDC do L54 | trocar COMO se promove não deveria custar reescrever QUEM tem permissão de publicar |
| Falha | O que a protege | O que ela NÃO protege |
|---|---|---|
| Artifact perdido ao sobrescrever | Model Registry versionando cada treino | erro no próprio código de treino, que é o L73 |
| Promoção sem revisão humana | estágio de aprovação bloqueante | revisor que aprova sem olhar o baseline de verdade |
| Falha operacional na variante nova | AutoRollbackConfiguration com alarme de erro/latência | modelo tecnicamente saudável mas pior na tarefa de negócio — é o caso deste laboratório |
| Rollback lento demais para conter prejuízo | EndpointConfig anterior preservada | EndpointConfig apagada por uma rotina de limpeza mal calibrada |
- Treino termina (L73) e chama create_model_package em vez de create_model.
- O Model Package nasce PendingManualApproval, com baseline de produção anexado.
- EventBridge dispara a pipeline; ela para no estágio de aprovação manual.
- Um revisor compara offline com baseline e aprova, com motivo registrado.
- UpdateEndpoint troca para blue/green: 10% de tráfego para a variante candidata.
- CloudWatch observa a variante nova durante o bake; alarme dispara rollback automático se necessário.
- Sem alarme, o peso sobe a 100% — a variante antiga continua Approved e disponível.
- Um rollback manual, se precisar, troca configuração em segundos — não exige novo treino.
Perguntas frequentes
❓ Por que registrar no Model Registry em vez de nomear o artifact com a data?
❓ O que a aprovação manual impede que o Registry sozinho não impediria?
❓ O rollback automático protege contra o modelo ser pior em detectar fraude?
❓ Quanto tempo leva para reverter ao modelo anterior se o automático não disparar?
❓ Por que não aprovar automaticamente sempre que a métrica offline melhora?
❓ O que acontece com a variante antiga depois que a nova assume 100% do tráfego?
❓ Preciso do CodePipeline, ou dá para aprovar só dentro do Model Registry?
Fixando
A Marcela retreina o modelo de fraude e a AUC no holdout sobe de 0,912 para 0,931. No Model Package, essa métrica vem acompanhada do baseline de produção (AUC 0,912, chargeback 0,4%). Por que anexar o baseline junto, em vez de deixar o revisor decidir só pela AUC nova?
No desenho mínimo, reverter para o modelo anterior exigia re-treinar do zero. No desenho de produção, o rollback manual foi medido em 41 segundos. Qual mudança de arquitetura é responsável, especificamente, por essa diferença?
Conhecimentos, próximo módulo e documentação
| Item | Conteúdo |
|---|---|
| Conhecimentos anteriores necessários | L54 (identidade federada do pipeline) e L73 (treino reproduzível, produzindo artifact e métrica) — este módulo assume os dois resolvidos |
| Conhecimentos adquiridos | Model Registry e ciclo de aprovação; deployment blue/green do SageMaker; AutoRollbackConfiguration e o que ele protege; a diferença entre rollback operacional automático e rollback de negócio manual |
| Limitação que fica | a taxa de chargeback ainda é calculada em lote, um dia depois — não existe hoje um sinal de negócio rápido o bastante para entrar no bake automático |
| Próximo exemplo recomendado | L76 — Pipeline de ML de ponta a ponta. Orquestra o treino do L73 e a promoção deste laboratório num fluxo disparado por dado novo, com linhagem completa |
| Também habilitado por este módulo | L77 (drift) usa o mesmo Model Registry para saber qual versão está em produção quando o alarme de drift dispara; L78 (avaliação honesta) usa o baseline anexado ao Model Package como ponto de partida para a métrica de negócio |
| Data da última validação técnica | 8 de agosto de 2026 |
Documentação oficial consultada: Amazon SageMaker Model Registry — o ciclo de vida de Model Package Group e Model Package, e o ApprovalStatus; e Amazon SageMaker: Update an Endpoint using a Blue/Green deployment strategy — o DeploymentConfig, o CANARY traffic routing e o AutoRollbackConfiguration com alarme do CloudWatch. Os valores de preço não aparecem neste módulo por decisão: custo de instância varia por tipo e região — use o AWS Pricing Calculator com o tipo de instância real do seu endpoint.
O que não foi verificado, e você deve conferir na sua conta
O tempo de bake de 10 minutos e o peso inicial de 10% são os valores usados no exemplo da Cadência — não um padrão universal. Ajuste conforme o volume de tráfego real do seu endpoint: um endpoint com poucas requisições por minuto pode precisar de uma janela maior para o alarme ter amostra suficiente antes de decidir. Confira também o limiar do alarme de erro contra a taxa de erro real do SEU endpoint antes de fixar o valor em produção.
Terminou de ler?
Marcar como concluído registra o XP, mantém sua sequência e coloca 3 cartas deste módulo na fila de revisão espaçada.
Próximos passos sugeridos
Temas deste módulo
Discussão
Carregando comentários…