Lab 99 — Multi-região para IA: onde o modelo existe, onde o dado pode estar
O problema, e a empresa que o tem
A Cadência fechou, no mês passado, a primeira operação da história dela fora do Brasil: 40 lojistas parceiros em Portugal, vendendo pelo mesmo marketplace que hoje atende as 900 lojas brasileiras do L58. Comercialmente é uma linha no relatório trimestral. Tecnicamente, é a primeira vez que a Cadência processa dado pessoal de um titular sujeito ao GDPR — e ninguém tinha perguntado, até este momento, para onde esse dado realmente vai.
O time de atendimento fez o óbvio: pegou o RAG do L83 — que já responde, com citação, perguntas de política de devolução e garantia para os atendentes — e apontou o painel português para o mesmo endpoint. Funcionalmente, funcionou de primeira: perguntas em português de Portugal recebem resposta correta, citando o trecho certo da política. O jurídico só perguntou "processado onde?" quando o contrato de adesão dos lojistas portugueses, revisado por um escritório local antes de assinar, exigiu descrever no anexo de proteção de dados EXATAMENTE em qual país o dado pessoal do lojista é tratado.
A resposta, depois de puxar 30 dias de CloudTrail: 2.740 chamadas ao Bedrock com prompt contendo nome, NIF e endereço de lojista português — todas processadas em us-east-1. Nenhuma configuração estava "errada" no sentido de quebrar alguma coisa; o RAG do L83 nunca foi desenhado para saber que um dia existiria uma segunda jurisdição. O defeito é estrutural, não um bug: o sistema não tem o conceito de "de onde veio este dado" em lugar nenhum do caminho.
Residência de dado é requisito legal, não preferência técnica
O erro que este laboratório existe para impedir não é "o modelo errou a resposta" — é processar dado pessoal de um titular da União Europeia fisicamente fora dela. Isso não se resolve com criptografia, com uma rede mais privada ou com um modelo melhor: resolve-se decidindo, de propósito, EM QUE REGIÃO cada chamada acontece, e impedindo qualquer caminho que fure essa decisão — inclusive um caminho privado.
O que este laboratório NÃO é
Não é o laboratório de RAG — isso é o L83, e ele continua exatamente como está: chunking, embedding, citação, golden set, nada disso muda aqui. Não é o laboratório de failover regional — isso é o L58, e o cluster global que ele construiu é reaproveitado sem alteração para o catálogo. Não é o laboratório de tráfego privado — isso é o L44, e o PrivateLink que ele ensina é a peça que impede a chamada de sair para a internet pública, não a peça que decide a região. Este laboratório resolve só a pergunta que nenhum dos três respondia: o que fazer quando o requisito de residência e a disponibilidade regional do modelo apontam para lugares diferentes.
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.
- Configurar roteamento por geolocalização no Route 53, com registro por país e registro Default obrigatório.
- Distinguir Aurora Global Database (replica sempre, mesmo sem failover) de Aurora Multi-AZ (fica dentro da região) e escolher a certa por requisito de residência.
- Explicar por que PrivateLink garante privacidade de rede e não decide em que região a chamada acontece — e por que essa distinção é o erro mais caro desta banda.
- Configurar VPC endpoints de interface para o Bedrock Runtime em duas regiões diferentes.
- Escrever uma condição de IAM (`aws:RequestedRegion`) que bloqueia, na camada de permissão, qualquer chamada fora da jurisdição — independente de a aplicação estar configurada certo.
- Documentar e justificar a escolha de um modelo comparável (não idêntico) quando o modelo preferido não está disponível na região que a residência exige.
- Provar, com CloudTrail, que nenhuma chamada de origem restrita foi processada fora da região correta — durante operação normal e durante um failover simulado.
- Medir RTO e RPO do failover regional do cluster de dado restrito, e explicar por que eles são estruturalmente diferentes dos números do L58.
O que a certificação cobra disto
| Conceito | Certificação | Como aparece aqui | O que dominar |
|---|---|---|---|
| Residência de dado como requisito não funcional | SAP-C02 | requisito legal que decide topologia, não uma linha de configuração isolada | residência não se resolve com criptografia nem com rede privada — resolve-se decidindo em que região o processamento acontece |
| Route 53: roteamento por geolocalização | SAP-C02 | registro por país/continente e registro Default obrigatório | geolocalização decide pela ORIGEM da consulta DNS, e não observa saúde do serviço — é uma política diferente da de failover do L58 |
| Aurora Global Database vs Aurora Multi-AZ | SAP-C02, SOA-C02 | a mesma tecnologia de banco, duas topologias com implicações de residência opostas | Global replica CONTINUAMENTE para outra região, independente de failover; Multi-AZ fica inteiro dentro de uma região |
| PrivateLink: o que ele garante e o que ele não garante | SAP-C02, SCS-C02 | tráfego privado entre VPC e serviço regional, sem decidir qual região é chamada | privacidade de rede e residência de dado são garantias independentes — uma não implica a outra |
| IAM com `aws:RequestedRegion` | SAP-C02, SCS-C02 | condição que nega chamada fora da jurisdição, como segunda camada além do roteamento | defesa em profundidade: o roteamento evita o erro, a condição de IAM impede que ele tenha efeito se acontecer |
| Disponibilidade regional de modelo gerenciado | AIF-C01, SAP-C02 | decisão explícita e documentada de usar modelo comparável quando o preferido não está na região exigida | disponibilidade de modelo no Bedrock varia por região e por data de lançamento — não existe garantia de que todo modelo chega a toda região |
| Well-Architected — Reliability e Security sob restrição regulatória | SAP-C02 | requisito de conformidade tratado como requisito de arquitetura desde a primeira linha do desenho | residência que aparece só depois de construído vira retrabalho caro; a prova cobrada pela certificação é decisão de projeto, não patch |
Onde isto costuma ser cobrado errado
A pergunta clássica descreve um cenário com requisito de residência e apresenta PrivateLink ou criptografia como a resposta certa, torcendo para que o candidato confunda "tráfego privado" com "dado nunca sai da região". As duas coisas não têm relação de causa e efeito: um VPC endpoint de interface pode estar corretamente configurado e apontar, ainda assim, para o serviço na região errada. A resposta certa envolve SEMPRE uma decisão explícita de roteamento e, na maioria dos enunciados de nível especialista, uma segunda camada de controle — geralmente IAM — que não depende de a aplicação estar configurada certo.
Requisitos, e como cada um muda o desenho
Requisito não funcional que não aparece numa linha de configuração é intenção. A terceira coluna é onde cada um deixou marca — e é ela que decide qual peça entra e qual fica de fora.
| Requisito | Valor declarado | O que muda no desenho |
|---|---|---|
| Residência de dado pessoal da UE | nunca processado fisicamente fora da União Europeia | descarta rota única para us-east-1 e descarta Aurora Global para a tabela de cadastro — exige roteamento por origem e um cluster que não replica para fora |
| Disponibilidade do modelo preferido varia por região | anthropic.claude-sonnet-4 não disponível em eu-central-1 no momento da escrita | obriga uma decisão documentada de modelo comparável (amazon.nova-pro) para a região restrita, em vez de rotear a chamada para onde o preferido está |
| Tráfego nunca sai para a internet pública | herdado do L44, agora em DUAS regiões | exige VPC endpoint de interface para o Bedrock Runtime em cada região, não só na região original |
| Falha de uma AZ não pode virar violação de residência | declarado pela diretoria depois do L58 | descarta Aurora Global para o cluster restrito mesmo para fins de alta disponibilidade — usa Multi-AZ síncrono dentro da própria região |
| Auditabilidade da região de processamento | toda chamada ao Bedrock tem de ser rastreável por região e por origem | exige CloudTrail multi-região habilitado e uma consulta que cruza `awsRegion` com a origem declarada da requisição |
| Falha de roteamento não pode ficar só na aplicação | declarado pelo time de segurança depois da descoberta de agosto | adiciona condição de IAM `aws:RequestedRegion` como segunda barreira, independente de a variável de configuração da aplicação estar certa |
| Continuidade do catálogo e do pedido (herdado do L58) | RTO de até 30 minutos, RPO de até 5 minutos, sem alteração | reaproveita o `cadencia-cluster-global` do L58 sem mudança — esse dado pode replicar, e já replica |
| Orçamento aprovado, sem infraestrutura dobrada indefinidamente | segunda região só para o que a residência exige | descarta duplicar TODA a stack para eu-central-1 — só o cadastro pessoal e a chamada de inferência ficam locais; o resto continua servido por us-east-1 |
Arquitetura mínima: um endpoint só, para qualquer país
Este é o desenho que a Cadência tinha até a semana passada, e ele nasceu de uma decisão razoável — reaproveitar o L83 sem reescrever nada. O laboratório começa por medir o tamanho do problema: quantas chamadas, dos últimos 30 dias, deveriam ter sido tratadas como jurisdição restrita e não foram.
- → pergunta do lojista português, com nome, NIF e endereço no corpo
- → lê o cadastro — mesma tabela para Brasil e Portugal
- → recupera trecho de política, igual para qualquer origem
- → prompt com o cadastro pessoal do lojista, processado em us-east-1
- → log da chamada, sem coluna de país de origem
- Fora da AWS
- Compute
- IA e machine learning
- Banco de dados
- Gestão e governança
Isto publica, e por isso sobrevive: o RAG do L83 respondendo corretamente, com citação, para o lojista português — funcionalmente perfeito. O defeito não é nenhuma resposta errada; é que TODO o processamento, inclusive o dado pessoal do lojista da UE, acontece em us-east-1, e nada no caminho verifica isso. Percorra os passos: o defeito só aparece quando alguém pergunta "processado onde?".
- Um único endereço, para qualquer país. O painel de atendimento chama sempre o mesmo endpoint, herdado direto do L83. Não existe, em lugar nenhum do fluxo, uma pergunta "de onde veio isto".
- O cadastro de todo mundo mora na mesma tabela. A tabela `lojistas` do `cadencia-cluster-global` guarda o lojista brasileiro e o português lado a lado, sem coluna de jurisdição — a mesma query serve os dois.
- A base de conhecimento não distingue origem. A Knowledge Base do L83 devolve o mesmo trecho de política para qualquer atendente, o que é correto — o conteúdo da política não é dado pessoal. O problema não está aqui.
- O prompt carrega dado pessoal para processamento nos EUA. O prompt final combina a pergunta, o trecho recuperado e, quando o atendente cola o contexto do lojista para personalizar a resposta, o cadastro dele. Esse prompt inteiro é processado fisicamente em us-east-1.
- O log não registra de onde veio o dado. O CloudWatch Logs do L83 grava latência, contagem de tokens e o texto da resposta — nunca a origem geográfica de quem perguntou. Não há como consultar "quantas chamadas vieram de fora do Brasil" sem reconstruir isso na mão.
- O defeito só aparece quando alguém audita. Foi assim que a Cadência descobriu: não um incidente, não um erro visível — uma cláusula de contrato que pediu para descrever, por escrito, onde o dado é processado, e ninguém tinha essa resposta pronta.
Antes de propor qualquer arquitetura nova, meça o que já aconteceu. Este roteiro cruza o CloudTrail dos últimos 30 dias com a lista de lojistas portugueses, e conta quantas chamadas ao Bedrock levaram dado pessoal deles para fora da jurisdição.
#!/usr/bin/env bash
# medir-violacao.sh — quantas chamadas de origem restrita foram para a regiao errada
set -euo pipefail
REGIAO_ERRADA=us-east-1
INICIO=$(date -u -d "30 days ago" +%FT%TZ)
# 1. Lista de identificadores de lojista portugues (jurisdicao restrita).
aws rds-data execute-statement --resource-arn "$CLUSTER_ARN" --secret-arn "$SECRET_ARN" \
--database cadencia --sql \
"select lojista_id from lojistas where pais = 'PT'" \
--query "records[][].[stringValue]" --output text > /tmp/lojistas_pt.txt
# 2. Eventos InvokeModel do Bedrock no CloudTrail, no periodo.
aws cloudtrail lookup-events --region "$REGIAO_ERRADA" \
--lookup-attributes AttributeKey=EventName,AttributeValue=InvokeModel \
--start-time "$INICIO" \
--query "Events[].CloudTrailEvent" --output text > /tmp/eventos_bedrock.json
# 3. Cruza: quantos eventos em us-east-1 tem o identificador de um lojista de /tmp/lojistas_pt.txt
# no corpo da requisicao (o painel injeta o lojista_id como metadado da chamada).
TOTAL=$(grep -c -f /tmp/lojistas_pt.txt /tmp/eventos_bedrock.json || true)
echo "Chamadas de lojista de Portugal processadas em $REGIAO_ERRADA nos ultimos 30 dias: $TOTAL"
# Na Cadencia: 2.740 chamadas. O requisito e ZERO.Duas mil setecentas e quarenta chamadas é o número que abriu este laboratório
Nenhuma dessas 2.740 chamadas gerou uma resposta errada — o RAG do L83 funcionou perfeitamente do ponto de vista de qualidade de resposta. O risco aqui não é técnico, é regulatório: é uma transferência internacional de dado pessoal sem base legal documentada para ela, descoberta só porque um contrato exigiu a pergunta certa. Se a Cadência tivesse assinado o anexo de proteção de dados antes de medir isso, teria assinado uma declaração falsa.
Arquitetura para produção: roteamento por região com residência respeitada
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.
- → resolve o domínio; geolocalização do resolvedor identifica o país de origem
- → mesmo domínio, origem fora da União Europeia
- → registro de país (PT/UE) → sempre eu-central-1, sem exceção
- → registro Default → us-east-1, para qualquer origem não restrita
- → lê/escreve cadastro do lojista — nunca sai da região
- → chamada de inferência, dentro da VPC
- → tráfego privado, nunca toca a internet pública
- → lê catálogo e pedido — cluster também usado pelo L58
- → chamada de inferência, dentro da VPC
- → tráfego privado, nunca toca a internet pública
- Fora da AWS
- Rede e entrega
- Compute
- Banco de dados
- IA e machine learning
O que muda não é uma caixa a mais — é que a origem da requisição, não a saúde do serviço, decide qual região atende, e o cadastro pessoal de cada jurisdição fica preso à sua própria região por desenho, não por convenção. Percorra os passos: cada peça nova rastreia a uma linha da tabela de requisitos, e o modelo usado em cada região é uma decisão documentada, não um acidente de configuração.
- O Route 53 decide pela origem, não pela saúde. Geolocalização é uma política diferente da de failover: ela resolve por CORRESPONDÊNCIA de país declarado no registro, verificado contra a origem geográfica inferida do resolvedor que fez a consulta — nunca por health check.
- Registro por país, sem exceção manual. O registro para Portugal (e, mais amplamente, para o continente Europa) aponta sempre para eu-central-1. Não existe caminho de configuração para "só desta vez" apontar para us-east-1.
- Fora da UE, cai no registro Default. Toda origem sem registro específico cai no registro Default, que aponta para us-east-1. Sem ele, um país novo — como aconteceu quando a Espanha entrou, na seção de anti-padrões — recebe NXDOMAIN em vez de qualquer resposta.
- O cadastro pessoal fica preso à região. O cluster `cadencia-cadastro-ue` é Aurora PostgreSQL Multi-AZ comum, não Aurora Global. A alta disponibilidade vem de réplicas SÍNCRONAS dentro de eu-central-1 — nunca existe uma cópia fora da fronteira, nem em repouso, nem em trânsito de failover.
- A chamada ao modelo nunca sai da rede da AWS, em nenhuma das duas regiões. O VPC endpoint de interface para `bedrock-runtime` existe em cada região separadamente — não existe um único PrivateLink "global"; cada região tem o seu, alcançando o serviço regional correspondente.
- O modelo preferido não está na região — a decisão é documentada, não acidental. Em eu-central-1, a Cadência usa amazon.nova-pro em vez de anthropic.claude-sonnet-4, porque o modelo preferido não estava disponível nessa região quando este laboratório foi escrito. A alternativa — rotear a chamada para us-east-1 para usar o modelo preferido — violaria exatamente o requisito que este laboratório resolve.
- O catálogo pode replicar; o cadastro pessoal, nunca. O `cadencia-cluster-global` do L58 continua replicando para us-west-2 sem nenhuma mudança — porque catálogo e pedido não carregam dado pessoal de lojista da UE. É a mesma distinção da tabela de requisitos: nem todo dado tem a mesma restrição.
- us-east-1 usa o modelo preferido, com o mesmo isolamento de rede. Fora da jurisdição restrita, nada mudou de qualidade: o anthropic.claude-sonnet-4 continua sendo a escolha, atrás do mesmo PrivateLink que o L44 ensinou — só que agora essa garantia existe nas duas regiões, não numa só.
A diferença estrutural em relação ao desenho anterior não é uma caixa a mais: é que a ORIGEM da requisição passa a decidir, antes de qualquer linha de código de aplicação rodar, qual região processa o dado — e o cadastro pessoal de cada jurisdição vive num cluster que estruturalmente não pode replicar para fora dela.
A garantia mais forte não é a rota — é o que o cluster restrito NÃO PODE fazer
Um erro de configuração no Route 53 pode, na pior hipótese, mandar uma requisição para a região errada. Mas mesmo nesse cenário de falha, o cluster `cadencia-cadastro-ue` continua sendo Multi-AZ comum — ele não tem PARA ONDE replicar o dado pessoal, porque a topologia inteira não criou esse caminho. A defesa mais confiável não é "configuramos certo", é "o desenho não permite configurar errado nesse ponto".
Como funciona, ponta a ponta
O payload de exemplo abaixo é o que a função registra no log estruturado — note o campo `regiao_processamento`, que não existia antes deste laboratório e é exatamente o dado que a auditoria de agosto não conseguiu produzir.
{
"requisicao_id": "6f2a1c9e-...",
"origem_declarada": "PT",
"regiao_roteamento": "eu-central-1",
"regiao_processamento": "eu-central-1",
"modelo": "amazon.nova-pro-v1:0",
"modelo_preferido_disponivel_na_regiao": false,
"cluster_cadastro": "cadencia-cadastro-ue",
"chamada_via_privatelink": true,
"citacao": {
"documento": "politica-devolucao-eletronicos.pdf",
"trecho": "produtos de material elétrico podem ser devolvidos em até 7 dias, com nota fiscal e produto lacrado"
},
"latencia_ms": 890,
"tokens_entrada": 612,
"tokens_saida": 134
}As decisões, e o que se perde em cada uma
📋 A Cadência precisa que 7,6% do tráfego do RAG do L83 — o de origem europeia — nunca seja processado fora da União Europeia, sem reescrever o RAG e sem duplicar 100% da infraestrutura para atender uma fração pequena do volume.
Geolocalização resolve "quem decide a região" sem exigir que o cliente declare a própria jurisdição — ela infere da origem da consulta DNS. Duplicar só o cadastro pessoal e a chamada de inferência (não a Knowledge Base inteira, não o catálogo) mantém o custo proporcional ao requisito real. E a condição de IAM cobre o cenário em que o roteamento, por algum motivo, falha — sem depender de ninguém lembrar de configurar a aplicação certo todas as vezes.
Alt: Mover TODA a operação para eu-central-1, para simplificar — resolveria a residência da UE às custas de tirar o modelo preferido do resto do negócio — o Brasil, que é a maior parte do volume, perderia acesso ao anthropic.claude-sonnet-4 sem nenhum requisito legal que justifique isso.
Alt: Manter Aurora Global para o cadastro, e só prometer nunca promover o secundário — não resolve nada: a replicação contínua já copia o dado pessoal para fora da região no momento da escrita, independente de o secundário ser promovido — é o erro central do quiz 2 deste módulo.
Alt: Confiar só em PrivateLink e criptografia, sem roteamento nem IAM por região — protege a REDE, não decide a REGIÃO — o endpoint pode estar perfeito e ainda assim apontar para o serviço errado; é o antipadrão mais caro desta banda.
Alt: Pedir para o cliente declarar a própria jurisdição num campo de formulário — depende de o cliente preencher certo e de ninguém burlar o campo — geolocalização de origem de rede é um sinal mais difícil de falsificar por acidente, e não depende de UX correta em cada tela.
| Peça | O que ela decide | O que acontece sem ela |
|---|---|---|
| Registro Route 53 por país | para qual região a requisição vai, antes de qualquer código rodar | sem ele, o tráfego cai no Default e a origem restrita nunca chega à região certa |
| Registro Route 53 Default | para onde vai origem sem registro específico | sem ele, um país novo recebe NXDOMAIN em vez de cair em alguma região |
| Aurora Multi-AZ (não Global) para cadastro restrito | que o dado pessoal nunca tenha cópia fora da região | sem essa escolha, a réplica cross-region do Aurora Global já viola residência, mesmo sem failover |
| VPC endpoint por região | que a chamada de inferência não saia para a internet pública | sem ele, o tráfego passaria por NAT/IGW — reabrindo o problema que o L44 resolveu, e agora em duas regiões |
| Condição de IAM `aws:RequestedRegion` | bloquear, na permissão, qualquer chamada fora da jurisdição | sem ela, um erro de configuração na aplicação é o único obstáculo entre o dado e a região errada |
Construir: Route 53 decidindo pela origem
Dois registros de geolocalização e um Default. A ordem de avaliação importa: o Route 53 tenta o registro mais específico primeiro (país), depois continente, depois Default — nunca o contrário.
resource "aws_route53_record" "atendimento_pt" {
zone_id = data.aws_route53_zone.cadencia.zone_id
name = "atendimento.cadencia.example"
type = "A"
set_identifier = "eu-portugal"
geolocation_routing_policy {
country = "PT"
}
alias {
name = aws_lb.eu_central_1.dns_name
zone_id = aws_lb.eu_central_1.zone_id
evaluate_target_health = true
}
}
# Continente inteiro, para cobrir qualquer país da UE que ainda nao tenha
# registro proprio — a Cadencia so tem lojistas em Portugal hoje, mas o
# requisito de residencia e da UNIAO EUROPEIA, nao so de Portugal.
resource "aws_route53_record" "atendimento_ue" {
zone_id = data.aws_route53_zone.cadencia.zone_id
name = "atendimento.cadencia.example"
type = "A"
set_identifier = "eu-continente"
geolocation_routing_policy {
continent = "EU"
}
alias {
name = aws_lb.eu_central_1.dns_name
zone_id = aws_lb.eu_central_1.zone_id
evaluate_target_health = true
}
}
# OBRIGATORIO: sem este registro, qualquer origem sem match especifico
# recebe NXDOMAIN — nao um fallback silencioso para us-east-1.
resource "aws_route53_record" "atendimento_default" {
zone_id = data.aws_route53_zone.cadencia.zone_id
name = "atendimento.cadencia.example"
type = "A"
set_identifier = "global-default"
geolocation_routing_policy {
country = "*"
}
alias {
name = aws_lb.us_east_1.dns_name
zone_id = aws_lb.us_east_1.zone_id
evaluate_target_health = true
}
}Geolocalização não é failover, e os dois não se substituem
O L58 usa `failover_routing_policy`, que decide pela SAÚDE do alvo. Este módulo usa `geolocation_routing_policy`, que decide pela ORIGEM da consulta. São mecanismos independentes do Route 53, e um cliente português com a região eu-central-1 fora do ar não "cai" automaticamente para us-east-1 só porque existe um registro Default — o Default cobre origem SEM registro específico, não origem cujo registro específico está insalubre. Resolver isso exige combinar geolocalização com health check, o que este módulo não aprofunda porque o requisito da Cadência aceita, por ora, uma janela de indisponibilidade da região específica em vez de processar fora da jurisdição.
Construir: dois Aurora — um que replica, um que não pode
O cluster global do L58 não muda uma linha. O que entra é um segundo cluster, deliberadamente comum, sem nenhuma configuração de replicação cross-region.
# Cluster ja existente do L58 — citado aqui so para deixar explicito o que
# NAO muda. Catalogo e pedido continuam podendo replicar.
# resource "aws_rds_global_cluster" "cadencia_global" { ... } (ver L58)
# Cluster NOVO, deliberadamente SEM aws_rds_global_cluster associado.
# Nao existe campo de configuracao que o transforme em Aurora Global por
# engano — a ausencia do bloco e a garantia, nao uma flag que alguem
# poderia esquecer de marcar.
resource "aws_rds_cluster" "cadencia_cadastro_ue" {
cluster_identifier = "cadencia-cadastro-ue"
engine = "aurora-postgresql"
engine_version = "15.4"
database_name = "cadastro_ue"
master_username = "cadencia_admin"
manage_master_user_password = true
# Regiao do provider deste modulo: eu-central-1. Nao ha parametro de
# replicacao cross-region em lugar nenhum deste recurso.
db_subnet_group_name = aws_db_subnet_group.eu_central_1.name
vpc_security_group_ids = [aws_security_group.aurora_ue.id]
storage_encrypted = true
kms_key_id = aws_kms_key.cadastro_ue.arn
backup_retention_period = 14
# PITR fica DENTRO da regiao — nunca copia snapshot para fora dela.
copy_tags_to_snapshot = true
tags = {
Projeto = "cadencia"
Jurisdicao = "UE"
Residencia = "obrigatoria"
}
}
resource "aws_rds_cluster_instance" "cadastro_ue" {
count = 2 # Multi-AZ: primaria + standby sincrono, mesma regiao
identifier = "cadencia-cadastro-ue-${count.index}"
cluster_identifier = aws_rds_cluster.cadencia_cadastro_ue.id
instance_class = "db.r6g.large"
engine = aws_rds_cluster.cadencia_cadastro_ue.engine
availability_zone = element(["eu-central-1a", "eu-central-1b"], count.index)
}A garantia estrutural vale mais que a promessa de processo
Não existe, neste desenho, um passo em que alguém "esquece" de configurar residência — porque o cluster restrito nunca teve o recurso `aws_rds_global_cluster` associado a ele. Comparar com o antipadrão da seção correspondente: reaproveitar o módulo Terraform do L58 por engano, associando o cluster novo ao cluster global existente, é o erro que a tabela de troubleshooting deste módulo cobre.
Construir: PrivateLink em cada região, e a decisão de modelo por região
O L44 criou um VPC endpoint por serviço, numa região. Aqui o padrão se repete, mas duplicado — porque um endpoint de interface é um recurso regional, e não existe "um PrivateLink" que cubra duas regiões ao mesmo tempo.
# Endpoint de interface para o Bedrock Runtime, DENTRO da VPC de eu-central-1.
resource "aws_vpc_endpoint" "bedrock_eu" {
vpc_id = aws_vpc.eu_central_1.id
service_name = "com.amazonaws.eu-central-1.bedrock-runtime"
vpc_endpoint_type = "Interface"
subnet_ids = aws_subnet.privada_eu_central_1[*].id
security_group_ids = [aws_security_group.bedrock_endpoint_eu.id]
private_dns_enabled = true
tags = { Nome = "cadencia-vpce-bedrock-eu-central-1" }
}
# O MESMO padrao, replicado na regiao global — o L44 criou isto so para
# S3/ECR/Secrets Manager/CloudWatch Logs; agora o Bedrock entra na lista
# tambem em us-east-1.
resource "aws_vpc_endpoint" "bedrock_us" {
vpc_id = aws_vpc.us_east_1.id
service_name = "com.amazonaws.us-east-1.bedrock-runtime"
vpc_endpoint_type = "Interface"
subnet_ids = aws_subnet.privada_us_east_1[*].id
security_group_ids = [aws_security_group.bedrock_endpoint_us.id]
private_dns_enabled = true
tags = { Nome = "cadencia-vpce-bedrock-us-east-1" }
}A decisão de qual modelo chamar em cada região não é uma variável de ambiente solta — é uma configuração central, versionada, que a aplicação lê em vez de decidir sozinha.
public sealed class ModeloPorRegiao
{
// Fonte unica da decisao. Uma variavel de ambiente errada num deploy
// futuro nao basta para chamar o modelo da regiao errada, porque o
// mapeamento vem daqui, nao de uma string solta no appsettings.
private static readonly IReadOnlyDictionary<string, ModeloConfig> PorRegiao =
new Dictionary<string, ModeloConfig>
{
["eu-central-1"] = new ModeloConfig(
ModelId: "amazon.nova-pro-v1:0",
Preferido: false,
Motivo: "anthropic.claude-sonnet-4-20250514-v1 indisponivel em eu-central-1 " +
"em ago/2026 — confira Model access no console antes de assumir " +
"que isto ainda vale."),
["us-east-1"] = new ModeloConfig(
ModelId: "anthropic.claude-sonnet-4-20250514-v1",
Preferido: true,
Motivo: "modelo preferido, mesmo do L83, disponivel nesta regiao."),
};
public static ModeloConfig Resolver(string regiaoAtual)
{
if (!PorRegiao.TryGetValue(regiaoAtual, out var config))
{
// Falhar alto, nunca cair para um modelo de outra regiao por default.
// O ponto inteiro deste modulo e nao existir fallback implicito de regiao.
throw new InvalidOperationException(
$"Nenhum modelo configurado para a regiao {regiaoAtual}. " +
"Adicionar aqui e uma decisao explicita, nao um acidente de deploy.");
}
return config;
}
}
public sealed record ModeloConfig(string ModelId, bool Preferido, string Motivo);Segurança: os riscos que só existem porque há residência
| Risco | Probabilidade | Impacto | Prevenção | Detecção | Resposta |
|---|---|---|---|---|---|
| Deploy aponta a função eu-central-1 para o Bedrock de us-east-1 por erro de configuração | Média — variável de ambiente errada é o erro mais comum de deploy multi-região | Alto — dado pessoal processado fora da jurisdição, violação regulatória real | Fonte única de configuração (ModeloPorRegiao), sem fallback implícito entre regiões | Condição de IAM nega a chamada antes dela sair; CloudTrail alerta em qualquer InvokeModel fora da região esperada | Rollback do deploy; notificação ao encarregado de proteção de dados conforme prazo do GDPR |
| Engenheiro reaproveita o módulo Terraform do L58 e associa o cluster restrito a um `aws_rds_global_cluster` | Baixa, mas já quase aconteceu na revisão de código deste módulo | Alto — a replicação começa a copiar dado pessoal para outra região desde o primeiro `apply` | Revisão de código exige checar ausência de bloco `aws_rds_global_cluster` para este cluster específico | Alarme em `describe-global-clusters` listando `cadencia-cadastro-ue` (não deveria aparecer nunca) | Remover o cluster do grupo global imediatamente; investigar se alguma transação já replicou |
| Registro Default do Route 53 é removido numa limpeza de infraestrutura | Baixa | Médio — origem sem registro específico recebe NXDOMAIN, não erro de residência | Terraform state com `prevent_destroy = true` no registro Default | Alarme de disponibilidade de domínio para países fora do mapa de registros | Recriar o registro Default; revisar por que a proteção de state não bloqueou |
| Política de IAM sem `aws:RequestedRegion` deployada por engano numa atualização | Média — condição de IAM é fácil de esquecer numa refatoração de policy | Alto — remove a segunda camada de defesa; um erro de roteamento deixa de ser bloqueado | Teste automatizado que tenta chamar `InvokeModel` fora da região esperada e espera `AccessDenied` | Esse mesmo teste, rodando no pipeline de CI a cada deploy | Bloquear o deploy até a condição voltar; revisar o diff de policy que a removeu |
A política de IAM é a peça que faz a diferença entre "configuramos certo" e "não tem como configurar errado sem ser barrado".
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "InvokeApenasNaRegiaoDaJurisdicao",
"Effect": "Allow",
"Action": ["bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream"],
"Resource": "arn:aws:bedrock:eu-central-1::foundation-model/amazon.nova-pro-v1:0",
"Condition": {
"StringEquals": { "aws:RequestedRegion": "eu-central-1" }
}
}
]
}A `task role` da função em eu-central-1 recebe SÓ esta policy — sem a permissão equivalente para us-east-1. Não é redundância com a `execution role` do ECS/Lambda, que continua controlando puxar imagem e escrever log: aqui é a aplicação em si, com uma permissão que fisicamente não alcança o modelo da região errada, mesmo que o código tentasse.
Implantar, e provar que o dado nunca atravessa a fronteira
Este é o coração do laboratório. Seis provas: as três primeiras mostram que o roteamento funciona em operação normal; a quarta mede o failover do cluster restrito; a quinta mede o failover do cluster global, reaproveitando o padrão do L58; a sexta é a auditoria completa, repetindo o script da arquitetura mínima — agora esperando zero.
#!/usr/bin/env bash
# provas.sh — residencia se prova com numero, nao se assume
set -euo pipefail
# -- Prova 1: origem portuguesa resolve para eu-central-1 --
dig +short atendimento.cadencia.example @8.8.8.8 -b <IP_DE_TESTE_PT>
# Esperado: o IP do ALB de eu-central-1. Testar com um resolvedor real de
# origem europeia (ou o simulador de geolocalizacao do proprio Route 53
# Console, em "Test record").
# -- Prova 2: origem sem registro cai no Default, nao em NXDOMAIN --
dig +short atendimento.cadencia.example @8.8.8.8 -b <IP_DE_TESTE_ARGENTINA>
# Esperado: o IP do ALB de us-east-1 — nao "no servers could be reached".
# -- Prova 3: 500 requisicoes sinteticas de origem PT, zero fora de eu-central-1 --
TOTAL=500; FORA=0
for i in $(seq 1 $TOTAL); do
REGIAO=$(curl -s -H "X-Simula-Origem: PT" https://atendimento.cadencia.example/debug/regiao)
[ "$REGIAO" != "eu-central-1" ] && FORA=$((FORA+1))
done
echo "Requisicoes PT processadas fora de eu-central-1: $FORA de $TOTAL"
# Esperado: 0. Qualquer numero acima de zero e falha da prova, nao ruido.
# -- Prova 4: failover do cluster restrito, medido, sem sair da regiao --
INICIO=$(date +%s%3N)
aws rds failover-db-cluster --region eu-central-1 \
--db-cluster-identifier cadencia-cadastro-ue
until aws rds describe-db-clusters --region eu-central-1 \
--db-cluster-identifier cadencia-cadastro-ue \
--query "DBClusters[0].Status" --output text | grep -q available; do sleep 2; done
FIM=$(date +%s%3N)
echo "RTO do cluster UE: $(( (FIM - INICIO) / 1000 )) segundos"
# Na Cadencia: 24 segundos — Multi-AZ sincrono, promocao local, sem cruzar
# fronteira em nenhum momento do processo.
aws rds describe-db-clusters --region eu-central-1 \
--db-cluster-identifier cadencia-cadastro-ue \
--query "DBClusters[0].AvailabilityZones" --output text
# Esperado: so zonas DENTRO de eu-central-1. Qualquer regiao diferente
# aqui seria evidencia de que o cluster virou Aurora Global por engano.
# -- Prova 5: failover do cluster global, padrao do L58, sem alteracao --
# (ver medir-rto-minima.sh e o roteiro de failover do L58 — nao repetido
# aqui porque este cluster nao guarda dado pessoal de jurisdicao restrita)
# -- Prova 6: auditoria completa, 30 dias depois da correcao --
# (mesmo script de medir-violacao.sh da arquitetura minima)
bash medir-violacao.sh
# Esperado: 0. Era 2.740 antes deste laboratorio.| Prova | Comando | Resultado que aprova | O que reprova, e o que significa |
|---|---|---|---|
| 1 · Origem PT resolve para eu-central-1 | teste de geolocalização no Route 53 | IP do ALB europeu | IP do ALB americano significa registro de país ausente ou mal configurado |
| 2 · Origem sem registro cai no Default | `dig` de origem não mapeada | IP do ALB de us-east-1 | NXDOMAIN significa que o registro Default foi removido ou nunca existiu |
| 3 · Amostra de 500 requisições PT, zero fora da região | laço de 500 chamadas sintéticas | 0 fora de eu-central-1 | qualquer valor acima de 0 é a mesma classe de defeito que abriu este laboratório |
| 4 · Failover do cluster restrito sem cruzar fronteira | `failover-db-cluster` + `describe-db-clusters` | RTO medido, AZs todas dentro de eu-central-1 | qualquer AZ fora de eu-central-1 significa que o cluster virou Global por engano |
| 5 · Failover do cluster global, sem alteração | roteiro do L58, reaproveitado | RTO/RPO nos mesmos números do L58 | divergência grande do L58 sugere que algo no cluster global foi alterado sem necessidade |
| 6 · Auditoria completa 30 dias depois | `medir-violacao.sh` | 0 chamadas de origem PT fora de eu-central-1 | qualquer valor acima de 0 é o mesmo defeito medido antes — 2.740 — só que menor ou maior |
A prova 4 é a que sustenta a promessa mais difícil de vender
É fácil provar que o roteamento funciona em operação normal — a prova 3 faz isso. O que convence jurídico e auditoria é a prova 4: mesmo QUEBRANDO de propósito uma AZ inteira dentro de eu-central-1, o cluster nunca teve para onde ir a não ser outra AZ da mesma região. A garantia não depende de ninguém lembrar de não fazer failover para fora — o desenho não criou esse caminho.
A Cadência decide simplesmente sempre chamar o anthropic.claude-sonnet-4 em us-east-1 para QUALQUER lojista, brasileiro ou português, porque é o modelo com melhor qualidade de resposta medida. Qual é o problema central dessa decisão?
Quebrar de propósito: quatro falhas, e a que não tem saída boa
As seis provas acima testam o caminho que funciona. As quatro falhas abaixo são as que aparecem de verdade num desenho com residência — e três delas têm sintoma que aponta para o lugar errado. A quarta não tem sintoma nenhum, que é justamente o que a torna a pior.
| Falha injetada | Como injetar | Sintoma enganoso | Diagnóstico correto |
|---|---|---|---|
| Registro Default removido do Route 53 | `aws route53 change-resource-record-sets` com `DELETE` no registro de `Default`, mantendo os de PT e DE | Clientes de Argentina e Japão passam a receber falha de DNS. Parece propagação incompleta, e alguém vai esperar 48h por um TTL que nunca vai resolver | Roteamento por geolocalização não tem fallback implícito: origem sem registro correspondente recebe **resposta vazia**, não o registro mais próximo. O Default não é opcional, é a cláusula `else` do roteamento — e o alarme `Route53RegistroDefaultAusente` existe por isso |
| Condição `aws:RequestedRegion` removida da policy | Aplicar a policy sem o bloco `Condition` na role da aplicação de eu-central-1 | **Nada quebra. A latência até melhora** em algumas requisições, porque a chamada passa a poder usar o modelo maior de us-east-1 | A falha que se manifesta como melhoria é a mais perigosa desta banda. A condição não era redundante com o roteamento: era a barreira que pegava o roteamento quando ELE falhava. Sem ela, um bug de geolocalização deixa de gerar `AccessDenied` e passa a gerar violação silenciosa de residência — descoberta na auditoria, meses depois. Ausência de erro não é prova de conformidade |
| Zona de eu-central-1 indisponível | `aws ec2 create-network-acl-entry` bloqueando a sub-rede do ALB europeu, ou o experimento de FIS do L57 apontado para eu-central-1 | Usuários europeus recebem 503 enquanto us-east-1 está saudável e ocioso. O reflexo treinado nos 98 laboratórios anteriores — "faça failover para a região que está de pé" — é exatamente o errado aqui | Esta é a falha sem saída boa, e a razão de ela estar no laboratório. Failover para us-east-1 restaura a disponibilidade **violando a residência**; não fazer failover preserva a residência mantendo a indisponibilidade. A resposta correta é ter decidido antes: redundância dentro da jurisdição (segunda AZ em eu-central-1, e Aurora Multi-AZ dentro da mesma região), e um plano de degradação declarado — não um failover que atravessa fronteira sob pressão de incidente, decidido às 3h por quem não conhece o contrato |
| Cluster restrito associado a um cluster global | `aws rds create-global-cluster --source-db-cluster-identifier cadencia-cadastro-ue` | Nenhum. A replicação sobe, a aplicação não percebe, o painel de latência não muda, e o dado europeu passa a existir em us-east-1 a partir daquele instante | É o antipadrão mais grave da banda e o único cujo sintoma é a ausência de sintoma. Só o alarme sobre `describe-global-clusters` no CloudTrail pega — e é por isso que ele está no painel, apesar de parecer paranoia. Repare que nenhuma métrica de aplicação jamais denunciaria isto |
A terceira falha é a lição da banda inteira
Os 98 laboratórios anteriores treinam um reflexo: quando uma região cai, sirva da outra. Residência de dado é o primeiro contexto da série em que esse reflexo produz o incidente em vez de resolvê-lo. Rode esta injeção com o time antes de precisar dela — a hora de descobrir que "failover" e "conformidade" apontam para lados opostos não é durante a indisponibilidade.
Observabilidade: o painel que separa jurisdição, não só região
As perguntas que este painel tem de responder são diferentes das do L58 — ali a pergunta era "a região primária está saudável?"; aqui é "algum byte foi processado onde não deveria?".
- Alguma chamada `bedrock:InvokeModel` nos últimos 30 dias tem `awsRegion` diferente da jurisdição de origem esperada?
- O registro Default do Route 53 continua existindo e apontando para o alvo certo?
- O cluster `cadencia-cadastro-ue` teve algum evento de `describe-global-clusters` — que não deveria existir nunca?
- Qual a diferença de latência p95 entre amazon.nova-pro (eu-central-1) e anthropic.claude-sonnet-4 (us-east-1) para perguntas comparáveis?
- Quantas chamadas foram negadas pela condição `aws:RequestedRegion` da política de IAM — cada uma é um roteamento que teria violado residência se a barreira não existisse?
| Alarme | Limiar inicial | O que ele pega |
|---|---|---|
| ChamadaBedrockForaDaJurisdicao (Athena sobre CloudTrail, agendado) | qualquer valor acima de 0 nas últimas 24h | a mesma classe de defeito medida em medir-violacao.sh, detectada em horas em vez de em auditoria trimestral |
| NegacaoIamPorRegiao (métrica derivada de CloudTrail `AccessDenied`) | qualquer valor acima de 0 | a barreira funcionou — mas também significa que o roteamento falhou antes dela; investigar a causa raiz |
| Route53RegistroDefaultAusente (config drift, AWS Config) | qualquer drift detectado | alguém removeu ou alterou o registro Default fora do fluxo de Terraform |
| AuroraUEEventoDeReplicacaoCrossRegion (CloudTrail `describe-global-clusters` listando o cluster UE) | qualquer ocorrência | o cluster restrito foi associado a um cluster global — o antipadrão mais grave desta banda |
| LatenciaBedrockEuP95 | acima do dobro da latência medida em us-east-1 para o mesmo tipo de pergunta | capacidade insuficiente do modelo comparável na região menor |
Escala: de 10 lojistas europeus a 1 milhão de requisições
| Ordem de grandeza | O que muda no roteamento e nos dados | O que NÃO muda |
|---|---|---|
| 10 lojistas na UE | um registro de país basta; Multi-AZ com 2 instâncias no cluster UE cobre a carga inteira | a condição de IAM e o VPC endpoint já existem desde o primeiro deploy — não são coisa de escala |
| 10 mil lojistas na UE | considerar registros por país individual (PT, ES, DE…) em vez de só o continente, para health check mais granular | o cluster continua Multi-AZ dentro de eu-central-1 — volume não é motivo para virar Aurora Global |
| 1 milhão de requisições/mês de origem UE | capacidade do amazon.nova-pro pode exigir provisioned throughput em vez de on-demand | a fronteira jurisdicional continua sendo a mesma — mais tráfego não relaxa o requisito de residência |
| Pico de campanha simultâneo nas duas regiões | Auto Scaling independente por região; um pico em us-east-1 não deve afetar capacidade reservada em eu-central-1 | o roteamento por origem continua determinístico — pico não muda para onde uma requisição vai |
| Falha de uma AZ dentro de eu-central-1 | o cluster UE promove localmente, como medido na prova 4 | a região de recuperação continua sendo a mesma região — nunca vira us-east-1 ou us-west-2 |
Custo: o preço de duas plataformas de IA, uma por jurisdição
| Cenário | O que pesa na fatura | A decisão de custo que este laboratório defende |
|---|---|---|
| Protótipo (poucos lojistas UE) | capacidade mínima do cluster Multi-AZ (2 instâncias) e do VPC endpoint, cobrando mesmo com tráfego baixo | aceitar o custo fixo baixo em vez de atrasar a correção do requisito legal |
| Produção pequena (centenas de lojistas UE) | endpoint de interface cobra por hora E por GB processado, duplicado em relação ao L44 — agora em duas regiões | medir o tráfego real antes de provisionar throughput dedicado no Bedrock; on-demand cobre a maior parte deste estágio |
| Alta escala (a UE vira fração relevante do negócio) | a duplicação de stack deixa de ser proporcionalmente cara e passa a fazer sentido como operação própria | reavaliar se eu-central-1 merece o mesmo nível de investimento em observabilidade e automação que us-east-1 já tem — não é mais "a região pequena" |
O número que este módulo não vai te dar
Preço de VPC endpoint por hora, de instância Aurora e de token do Bedrock mudam por região e por trimestre — qualquer número aqui envelheceria antes deste texto ser lido de novo. O que não muda é o MODELO de cobrança: hora ligada mais GB processado no endpoint, hora ligada por instância no Aurora, token de entrada e de saída no Bedrock. Calcule o seu caso no AWS Pricing Calculator, por região.
Well-Architected nos seis pilares
| Pilar | Situação antes deste laboratório | Risco | Melhoria | Prioridade |
|---|---|---|---|---|
| Segurança | nenhum controle distinguia jurisdição de origem | 2.740 chamadas processando dado pessoal fora da jurisdição, sem base legal documentada | roteamento por origem + condição de IAM por região | Crítica |
| Confiabilidade | cluster restrito dependeria de Aurora Global para HA, violando residência para ganhar disponibilidade | trade-off errado: comprar disponibilidade com uma violação legal | Multi-AZ síncrono dentro da região, sem cluster secundário externo | Alta |
| Excelência operacional | nenhuma métrica separava chamadas por jurisdição de origem | defeito só descoberto por auditoria manual, meses depois de existir | CloudTrail + Athena consultando `awsRegion` versus origem declarada, com alarme | Alta |
| Eficiência de desempenho | modelo único para todo o tráfego | nenhum — a troca de modelo em eu-central-1 é consequência da residência, não um ganho de performance buscado | medir latência do modelo comparável e ajustar capacidade se necessário | Média |
| Otimização de custo | nenhuma infraestrutura duplicada existia (porque o requisito nem era atendido) | duplicar tudo para 7,6% do tráfego seria desperdício | duplicar só o que a residência exige — cadastro e inferência, não a Knowledge Base inteira | Média |
| Sustentabilidade | uma segunda região sempre ativa consome capacidade adicional independente de utilização | capacidade ociosa em horários de baixo tráfego europeu | avaliar Aurora Serverless v2 para o cluster UE em vez de instância fixa, se o padrão de carga permitir | Baixa |
Evolução em níveis: de uma região só a dados e IA por jurisdição
A terceira arquitetura não é um desenho: é a resposta a QUANDO a Cadência precisa tratar uma nova jurisdição, e o que cada nível compra e cobra.
Um único endpoint, uma única região, para qualquer país. É a arquitetura mínima deste módulo, e é exatamente o estado que uma auditoria descobre tarde.Roteamento por origem no Route 53, cluster local para dado restrito, PrivateLink por região, IAM com condição de região como segunda camada.A auditoria de `medir-violacao.sh` deixa de ser um script rodado manualmente e vira um job agendado com alarme, alimentando um painel de conformidade revisado mensalmente.A Cadência expande para um país com requisito de residência diferente (por exemplo, um país que exige o dado num datacenter local específico, não só "na União Europeia"). O padrão de roteamento por origem se generaliza para N regiões, não só duas.Toda nova carga da Cadência que toca dado pessoal nasce consultando um catálogo central de "qual dado pode replicar, para onde, e qual modelo está aprovado em cada região" — em vez de cada time decidir isso de novo.O histórico de latência, custo e disponibilidade de modelo por região vira DADO: quando a Cadência avalia expandir para uma quarta jurisdição, um MODELO simples sobre esse histórico ajuda a estimar custo e risco de operar lá — nunca decide sozinho se a expansão atende ao requisito legal, que continua sendo checagem jurídica humana.A ordem não é negociável, pelo mesmo motivo do L58
Automatizar a auditoria de conformidade (nível 3) antes de ter o roteamento correto (nível 2) só automatiza a detecção de um problema que continua existindo. E generalizar para N jurisdições (nível 4) antes de ter provado o caso de duas é resolver um problema mais difícil sem ter comprovado que se resolve o mais fácil — o mesmo raciocínio que o L58 aplica a DR.
Onde IA entra nesta arquitetura, e onde a decisão continua sendo do desenho
A pergunta "para qual região esta requisição deve ir" tem resposta determinística — geolocalização de origem, cruzada com uma tabela fixa de jurisdição — e não há ganho em trocar isso por um modelo probabilístico. Um classificador de IA decidindo "acho que isto é dado da UE" no lugar de uma regra exata trocaria uma garantia auditável por uma que erra, exatamente no ponto que este laboratório existe para blindar.
Onde IA ajudaria de verdade é diferente: hoje, escolher o modelo comparável para uma região nova (como a decisão de usar amazon.nova-pro em vez de anthropic.claude-sonnet-4) é um julgamento humano, feito uma vez, documentado em código. Um sistema que comparasse a qualidade de resposta dos modelos disponíveis em cada região, contra o mesmo golden set do L83, poderia informar essa escolha com número em vez de opinião — mas a decisão final, de qual modelo aceitar como "comparável o suficiente" para um caso de uso com implicação legal, continua sendo humana.
| Pergunta | Resposta honesta para este módulo |
|---|---|
| Qual problema a IA resolveria? | comparar, com número, a qualidade de resposta de modelos alternativos numa região restrita — hoje essa comparação é feita uma vez, manualmente, ao escolher o modelo |
| Por que uma regra não bastaria? | para ESCOLHER a região, uma regra já é suficiente e mais confiável — geolocalização determinística. Para AVALIAR qualidade de modelo comparável, o golden set do L83 já é o mecanismo, e ele não precisa de IA para funcionar, só de rodar com mais frequência |
| De onde viriam os dados? | o mesmo golden set do L83, rodado contra cada modelo candidato disponível numa região, com a taxa de acerto registrada por modelo e por região |
| Qual o risco? | tratar a comparação de qualidade como se decidisse sozinha a escolha do modelo, ignorando que "comparável o suficiente" para um caso de uso regulado é, em parte, julgamento jurídico, não só técnico |
| Por que não agora? | a Cadência tem uma jurisdição nova e uma escolha de modelo feita uma vez — não há histórico suficiente para um sistema de comparação automática valer o investimento antes do nível 4 da evolução em níveis |
O uso de IA que parece atraente e é armadilha aqui
Pedir a um modelo para "detectar automaticamente se uma requisição contém dado pessoal sujeito a residência" e rotear com base nisso substitui um sinal exato — a origem geográfica, verificável e auditável — por um sinal probabilístico, exatamente no ponto em que este laboratório escolheu, de propósito, manter uma regra determinística. Um falso negativo aqui não é um incômodo: é a mesma classe de defeito que abriu este laboratório, só que decidida por um modelo em vez de por ausência de roteamento.
Anti-padrões deste laboratório
| Anti-padrão | Por que alguém faz | Por que é problema | Sintoma em produção | Forma correta |
|---|---|---|---|---|
| Rotear para o modelo mais capaz, ignorando onde ele está disponível | o time técnico avalia qualidade de resposta, não jurisdição de dado — até o jurídico perguntar | residência de dado é requisito legal, não preferência técnica que se ignora por conveniência de engenharia | CloudTrail mostra 100% das chamadas de uma origem restrita caindo na região do modelo preferido | roteamento explícito por origem, testado antes de abrir o mercado novo, com o modelo comparável documentado como decisão aceita |
| Achar que PrivateLink resolve residência de dado | o time de segurança confirma "tráfego nunca sai para a internet pública" e encerra a revisão ali | PrivateLink garante privacidade de REDE, não decide a REGIÃO chamada; o endpoint pode estar corretamente configurado e ainda assim apontar para o serviço na região errada | auditoria de residência reprovada mesmo com o checklist de rede 100% verde | revisar para qual região o client SDK está configurado, além de checar se o tráfego é privado — as duas coisas, não uma no lugar da outra |
| Usar Aurora Global Database para o cadastro pessoal, "para ter alta disponibilidade também" | Aurora Global já resolveu DR no L58, e reaproveitar o mesmo padrão parece econômico e consistente | a replicação contínua já é, por si só, uma transferência internacional de dado pessoal — o problema existe mesmo que o failover nunca seja acionado | dado pessoal de lojista da UE aparece em snapshot ou réplica de uma região que não deveria tê-lo | Multi-AZ síncrono dentro da própria região, sem cluster secundário fora dela, mesmo custando disponibilidade cross-region |
| Esquecer o registro Default no roteamento por geolocalização | os testes cobrem só os países que já existem hoje na base de lojistas | origem sem registro específico e sem Default recebe NXDOMAIN, não um fallback razoável | usuários de um país novo reportam "site fora do ar" enquanto o painel de status mostra tudo saudável | sempre criar o registro Default como rede de segurança, mesmo quando parece redundante no dia do deploy |
| Deixar a política de IAM sem `aws:RequestedRegion`, confiando só na configuração da aplicação | a configuração já força a região certa hoje, e a condição de IAM parece redundante | um valor de ambiente errado num deploy futuro chama a região errada sem nenhuma barreira que impeça — a única proteção era a disciplina de configurar certo, sempre | só descoberto na próxima auditoria, não no incidente — porque nada bloqueou nem alertou em tempo real | IAM nega, por condição de região, qualquer chamada fora da jurisdição — camada que não depende de ninguém lembrar de configurar certo |
Quando algo não funciona
| Sintoma | Causa provável | Como investigar | Onde olhar | Correção |
|---|---|---|---|---|
| Cliente de um país novo recebe NXDOMAIN | falta registro geolocation para esse país e o Default foi removido ou nunca existiu | `dig` do domínio a partir de um resolvedor com origem naquele país | registros do Route 53 para o domínio | criar o registro Default, ou o registro de país/continente específico |
| Chamada ao Bedrock aparece em us-east-1 mesmo vindo de origem UE | variável de ambiente de região da função não seguiu o deploy correto, ou deploy usou o pacote errado | comparar `AWS_REGION` efetivo da função com o `awsRegion` do evento no CloudTrail | configuração da função Lambda/ECS vs. CloudTrail | corrigir a configuração; confirmar que a condição de IAM teria bloqueado — se não bloqueou, revisar a policy também |
| Latência alta em eu-central-1, mesmo com tráfego baixo | amazon.nova-pro sem capacidade reservada suficiente, ou cold start de função | métricas de latência do Bedrock por modelo, comparadas entre regiões | CloudWatch, painel de latência p95 por região | avaliar provisioned throughput; revisar configuração de concorrência da função |
| `describe-global-clusters` lista o cluster de cadastro UE | engenheiro reaproveitou o módulo Terraform do L58 e associou o cluster novo a um cluster global por engano | `aws rds describe-global-clusters` procurando `cadencia-cadastro-ue` nos membros | estado do Terraform e configuração do cluster | desassociar imediatamente do cluster global; investigar se alguma transação já replicou para outra região |
| Auditoria não consegue provar isolamento | CloudTrail não habilitado como trilha multi-região nessa conta, ou retenção insuficiente | checar configuração da trilha e período de retenção | console do CloudTrail, configuração da trilha | habilitar trilha multi-região com retenção compatível com o ciclo de auditoria exigido pelo contrato |
Limpeza: o que o destroy não leva, em duas jurisdições
A ordem importa mais aqui do que em qualquer outro laboratório desta banda: remover o VPC endpoint antes de confirmar que não há tráfego pendente corta a aplicação da única rota privada que ela tem para o modelo.
#!/usr/bin/env bash
# limpeza.sh — ordem que evita cortar trafego vivo, em DUAS regioes
set -euo pipefail
# 1. Confirmar que nao ha trafego real de origem UE nas ultimas 2h antes
# de tocar em qualquer recurso de eu-central-1.
aws cloudwatch get-metric-statistics --region eu-central-1 \
--namespace AWS/ApplicationELB --metric-name RequestCount \
--statistics Sum --period 7200 \
--start-time "$(date -u -d "2 hours ago" +%FT%TZ)" --end-time "$(date -u +%FT%TZ)"
# 2. Remover os registros Route 53 (pais, continente e Default) ANTES do
# ALB — senao o dominio aponta para um alvo morto por alguns minutos.
terraform destroy -target=aws_route53_record.atendimento_pt \
-target=aws_route53_record.atendimento_ue \
-target=aws_route53_record.atendimento_default
# 3. Remover a funcao e o VPC endpoint de eu-central-1.
terraform destroy -target=aws_lambda_function.responder_com_citacao_eu \
-target=aws_vpc_endpoint.bedrock_eu
# 4. O cluster Aurora exige snapshot final explicito — skip_final_snapshot
# default e false, e um cluster com dado pessoal NAO deve pular isso.
aws rds delete-db-cluster --region eu-central-1 \
--db-cluster-identifier cadencia-cadastro-ue \
--final-db-snapshot-identifier cadencia-cadastro-ue-final
# 5. Repetir 2-4 para us-east-1, SE o objetivo for desmontar o laboratorio
# inteiro. Normalmente NAO: a stack de us-east-1 e a mesma que o L58 e
# o L83 usam em producao.O que o destroy não leva, e você paga se esquecer
O snapshot final do cluster `cadencia-cadastro-ue` continua existindo depois do `destroy` — e ele contém dado pessoal sujeito ao mesmo requisito de residência do cluster vivo. Snapshot não é exceção à regra: ele precisa ser apagado, com retenção documentada, dentro da mesma política de residência, ou vira o próximo achado de auditoria. O VPC endpoint de interface também continua cobrando por hora até ser destruído explicitamente — o `terraform destroy` só remove o que está no state; um endpoint criado fora do fluxo do Terraform fica órfão e cobrando.
Resumo: problema, peça e motivo
| Problema | Serviço | Motivo |
|---|---|---|
| Requisito legal decide onde o dado é processado | Route 53 — roteamento por geolocalização | a origem da requisição escolhe a região antes de qualquer código de aplicação rodar |
| Réplica cross-region viola residência mesmo sem failover | Aurora PostgreSQL Multi-AZ (não Global) para o cadastro restrito | alta disponibilidade sem cópia do dado fora da fronteira |
| Rede privada não é a mesma coisa que região certa | PrivateLink, um VPC endpoint por região | garante que a chamada nunca toca a internet pública — e nada além disso |
| Erro de configuração não pode ser a única barreira | IAM com condição `aws:RequestedRegion` | bloqueia, na permissão, qualquer chamada fora da jurisdição, independente da aplicação |
| Modelo preferido nem sempre está na região exigida | decisão documentada de modelo comparável (amazon.nova-pro) | aceitar explicitamente um modelo diferente é melhor do que rotear a chamada para fora da jurisdição |
| Afirmação de conformidade precisa de prova, não de crença | CloudTrail + script de auditoria cruzando origem e região | transforma "achamos que está isolado" em um número — 2.740 chamadas antes, 0 depois |
Perguntas frequentes
❓ PrivateLink sozinho garante que o dado da UE não sai da União Europeia?
❓ Por que o cadastro de lojista da UE não usa Aurora Global Database?
❓ O modelo usado em eu-central-1 é o mesmo Claude que a Cadência usa em us-east-1?
❓ Como o Route 53 sabe que uma requisição vem de Portugal?
❓ Se eu-central-1 cair inteira, o cadastro dos lojistas da UE some?
❓ Por que não seria mais simples processar tudo em eu-central-1, para todo mundo?
❓ IAM com condição de região substitui o roteamento correto no Route 53?
❓ Isso serve só para GDPR, ou qualquer requisito de residência de dado?
Fixando
O time da Cadência configura o cadastro do lojista português num cluster Aurora Global Database, com o secundário em us-west-2, mas configura o Route 53 para NUNCA disparar failover para essa região — o secundário existe só "para os dados estarem seguros". Esse desenho respeita a residência de dado da UE?
A Cadência lança o roteamento por geolocalização, mas esquece de criar o registro Default no Route 53. Uma nova parceria comercial adiciona lojistas na Espanha antes de existir um registro específico para esse país. O que acontece com as requisições desses lojistas?
Conhecimentos, próximo módulo e documentação
| Item | Conteúdo |
|---|---|
| Conhecimentos anteriores necessários | L44 (PrivateLink), L58 (Aurora Global, Route 53 de failover, RTO/RPO medidos) e L83 (RAG com citação) no ar; Terraform e .NET 8 básicos |
| Conhecimentos adquiridos | roteamento por geolocalização versus failover; Aurora Global versus Multi-AZ como decisão de residência; PrivateLink como garantia de rede, não de região; IAM com `aws:RequestedRegion` como segunda camada; decisão documentada de modelo comparável por região |
| Limitação que fica | o roteamento cobre duas regiões com uma decisão binária (UE / resto do mundo) — uma terceira jurisdição com regra própria exigiria generalizar o padrão, como descrito no nível 4 da evolução |
| Próximo exemplo recomendado | L100 — o projeto final da série, reunindo os seis pilares do Well-Architected e o DR ensaiado sobre um sistema que integra o que as dez bandas construíram, este laboratório incluído |
| Também habilitado por este módulo | qualquer carga que precise declarar, para um cliente, regulador ou parceiro comercial, exatamente onde um dado pessoal é processado — com prova em CloudTrail, não em promessa de arquitetura |
| Data da última validação técnica | 8 de agosto de 2026 |
Documentação oficial consultada: Amazon Route 53 Developer Guide — Geolocation routing, origem do comportamento de correspondência por país/continente e da necessidade do registro Default; Amazon Aurora User Guide — Aurora Global Database, fonte do comportamento de replicação contínua independente de failover; AWS PrivateLink concepts — Interface VPC endpoints, fonte do escopo regional do endpoint de interface; e IAM JSON policy elements — Condition, aws:RequestedRegion. A lista de modelos disponível por região do Bedrock não tem fonte estável para citar aqui — ela muda com frequência maior que a de qualquer outro serviço citado nesta série; confira sempre "Model access" no console da região antes de decidir.
O que não foi verificado, e você deve conferir na sua conta
O número de "2.740 chamadas" na arquitetura mínima e o RTO de "24 segundos" na seção de prova são medidas da conta de exemplo desta série, não garantias da AWS nem valores que se repetem na sua conta. A disponibilidade do anthropic.claude-sonnet-4 e do amazon.nova-pro por região é o dado mais volátil deste módulo inteiro — o Bedrock adiciona modelo e região continuamente, e a lista de agosto de 2026 pode já estar errada quando você ler isto. Confirme em "Model access", no console da região exata que a sua aplicação usa, antes de copiar qualquer ID de modelo deste laboratório.
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…