Atualizando Conteúdo no CloudFront: Como Criar uma Invalidação para Limpar o Cache da Edge
Você substituiu um arquivo no S3, fez o deploy, abriu o navegador — e o CloudFront continua servindo a versão antiga. Esse é um dos problemas mais comuns em operações com CloudFront, e a solução passa por entender como a invalidação de cache do CloudFront funciona antes de sair clicando em botões.
TL;DR — Invalidação de Cache no CloudFront
| Situação | Ação Recomendada |
|---|---|
| Arquivo específico desatualizado | Invalidar o path exato: /imagens/logo.png |
| Múltiplos arquivos em um diretório | Invalidar com wildcard: /assets/* |
| Deploy completo do site | Invalidar tudo: /* |
| Evitar custo de invalidação recorrente | Usar versionamento de arquivo no nome (cache busting) |
Como o Cache do CloudFront Funciona
O CloudFront opera com uma rede de pontos de presença (PoPs) distribuídos globalmente, chamados de edge locations. Quando um usuário requisita um objeto, o edge verifica se tem uma cópia em cache. Se tiver e o TTL ainda não expirou, ele serve direto — sem consultar o S3. Isso é exatamente o que você quer em produção para performance, e exatamente o que te atrapalha quando você precisa propagar uma mudança imediatamente.
O TTL de um objeto no edge é controlado pelos cabeçalhos Cache-Control e Expires que o S3 retorna, combinados com as configurações de TTL mínimo, padrão e máximo definidas no behavior da distribuição. Se o S3 não retornar esses cabeçalhos, o CloudFront usa o TTL padrão configurado no behavior — que por padrão é 86.400 segundos (24 horas).
Uma invalidação força o CloudFront a marcar os objetos em cache como expirados em todos os edge locations, fazendo com que a próxima requisição busque o conteúdo atualizado diretamente na origem.
- Requisição normal com cache válido: o edge serve o objeto diretamente sem contatar o S3.
- Após invalidação: o objeto é marcado como expirado no edge. A próxima requisição vai até o S3, busca o arquivo atualizado, e o edge armazena a nova versão em cache.
- Propagação: a invalidação se propaga para todos os edge locations da distribuição, não apenas para um PoP específico.
Criando uma Invalidação de Cache no CloudFront
A invalidação pode ser criada via Console, AWS CLI ou API. Em pipelines de CI/CD, o CLI é o caminho natural. Abaixo os dois métodos principais.
Via AWS Console
- Acesse o serviço CloudFront no Console AWS.
- Clique na distribuição desejada.
- Vá até a aba Invalidations.
- Clique em Create invalidation.
- Informe os paths desejados — um por linha. Use
/*para invalidar tudo. - Clique em Create invalidation e aguarde o status mudar para
Completed.
Via AWS CLI
Para invalidar um arquivo específico:
aws cloudfront create-invalidation \
--distribution-id E1EXAMPLE123456 \
--paths '/imagens/logo.png'
Para invalidar múltiplos paths em uma única chamada:
aws cloudfront create-invalidation \
--distribution-id E1EXAMPLE123456 \
--paths '/index.html' '/assets/app.js' '/assets/style.css'
Para invalidar toda a distribuição:
aws cloudfront create-invalidation \
--distribution-id E1EXAMPLE123456 \
--paths '/*'
Para verificar o status da invalidação criada:
aws cloudfront get-invalidation \
--distribution-id E1EXAMPLE123456 \
--id INVALIDATION_ID
Para listar invalidações recentes de uma distribuição:
aws cloudfront list-invalidations \
--distribution-id E1EXAMPLE123456
Permissões IAM Necessárias
A conta ou role que executa a invalidação precisa das seguintes permissões:
🔽 Clique para expandir — Política IAM mínima para invalidação
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudFrontInvalidation",
"Effect": "Allow",
"Action": [
"cloudfront:CreateInvalidation",
"cloudfront:GetInvalidation",
"cloudfront:ListInvalidations"
],
"Resource": "arn:aws:cloudfront::123456789012:distribution/E1EXAMPLE123456"
}
]
}
Substitua 123456789012 pelo seu Account ID e E1EXAMPLE123456 pelo ID real da sua distribuição. A ação cloudfront:ListDistributions requer "Resource": "*" — verifique o Service Authorization Reference para confirmar o suporte a resource-level por ação antes de restringir.
Diagnóstico: Por Que o Arquivo Ainda Aparece Desatualizado Após a Invalidação?
Aqui é onde a maioria das pessoas perde tempo. A invalidação foi criada, o status está Completed, mas o navegador ainda mostra o arquivo antigo. Antes de criar outra invalidação, vale verificar cada camada do problema.
no CloudFront"] --> B{"S3 tem o arquivo
atualizado?"}; B -- Não --> C["Refaça o upload
para o S3"]; B -- Sim --> D{"Invalidação está
Completed?"}; D -- InProgress --> E["Aguarde a propagação"]; D -- Completed --> F{"curl retorna
conteúdo correto?"}; F -- Não --> G{"Path da invalidação
bate exatamente?"}; G -- Não --> H["Crie nova invalidação
com path correto"]; G -- Sim --> I["Verifique MinTTL
no behavior"]; F -- Sim --> J["Problema é cache
local do navegador"]; J --> K["Limpe o cache
do navegador"];
Passo 1 — Confirme que o arquivo no S3 realmente foi atualizado
Parece óbvio, mas em pipelines com múltiplos estágios é comum o upload falhar silenciosamente ou sobrescrever o bucket errado. Verifique o ETag e o LastModified do objeto diretamente:
aws s3api head-object \
--bucket meu-bucket-exemplo \
--key imagens/logo.png
Compare o ETag retornado com o hash do arquivo local. Se forem iguais, o upload não aconteceu.
Passo 2 — Verifique se a invalidação foi concluída com sucesso
Uma invalidação no estado InProgress ainda não propagou para todos os edge locations. O tempo de propagação varia — consulte a documentação oficial para valores atuais. Confirme o status:
aws cloudfront list-invalidations \
--distribution-id E1EXAMPLE123456 \
--query 'InvalidationList.Items[*].{ID:Id,Status:Status,CreateTime:CreateTime}' \
--output table
Passo 3 — Descarte o cache do navegador antes de concluir qualquer coisa
O cache do navegador é independente do cache do CloudFront. Um arquivo com Cache-Control: max-age=3600 pode estar armazenado localmente por até uma hora, mesmo após a invalidação no edge ter sido concluída. Teste com curl para eliminar essa variável:
curl -I https://d1example.cloudfront.net/imagens/logo.png
Observe o cabeçalho X-Cache na resposta. O valor Hit from cloudfront indica que o edge ainda está servindo do cache. O valor Miss from cloudfront indica que a requisição foi até a origem. Se o curl retorna o conteúdo correto mas o navegador não, o problema é local.
Passo 4 — Verifique o path da invalidação contra o path real do objeto
Invalidações são case-sensitive e precisam corresponder exatamente ao path do objeto na distribuição, incluindo query strings se a distribuição estiver configurada para encaminhar e cachear por query string. Um path /Imagens/Logo.png não invalida /imagens/logo.png. Confirme os paths dos objetos no S3 e compare com o que foi enviado na invalidação.
Pense no path de invalidação como uma chave de cache exata. O CloudFront não faz correspondência parcial nem normaliza capitalização. Se o path não bater bit a bit com o que está em cache, a invalidação passa em branco.
Passo 5 — Verifique se há um behavior com TTL mínimo alto sobrepondo a invalidação
Esse é o cenário que mais gera confusão. Se o behavior da distribuição tiver um Minimum TTL configurado com um valor alto, o CloudFront pode ignorar o cabeçalho Cache-Control: no-cache da origem e manter o objeto em cache além do esperado. Uma invalidação limpa o cache atual, mas se a origem continuar retornando cabeçalhos que conflitam com o TTL mínimo do behavior, o objeto será recacheado com o TTL antigo na próxima requisição.
Verifique o TTL mínimo configurado no behavior:
aws cloudfront get-distribution-config \
--id E1EXAMPLE123456 \
--query 'DistributionConfig.DefaultCacheBehavior.{MinTTL:MinTTL,DefaultTTL:DefaultTTL,MaxTTL:MaxTTL}'
Se o MinTTL estiver em um valor alto, ajuste-o ou corrija os cabeçalhos de cache retornados pelo S3.
Cache Busting: A Alternativa Estrutural à Invalidação
Invalidações têm custo. A AWS oferece as primeiras 1.000 paths de invalidação por mês sem custo — após isso, há cobrança por path. Verifique os valores atuais na página de preços do CloudFront. Além do custo, invalidar /* em toda distribuição a cada deploy é uma abordagem que escala mal.
A alternativa operacionalmente mais robusta é o cache busting por versionamento de nome de arquivo: em vez de sobrescrever app.js, você publica app.v2.js ou app.a1b2c3d4.js (hash do conteúdo). O HTML referencia o novo nome, o CloudFront trata como um objeto diferente e busca da origem automaticamente. Nenhuma invalidação necessária.
Essa abordagem é padrão em frameworks modernos de frontend como Next.js, Vite e webpack, que geram hashes de conteúdo nos nomes dos assets automaticamente.
/app.js"] INV --> EDGE1["Edge atualizado"] end subgraph CacheBusting B1["app.a1b2c3.js"] -->|novo objeto| B2["app.d4e5f6.js"] B2 --> EDGE2["Edge busca automaticamente
objeto novo"] end
Invalidação de Cache no CloudFront em Pipelines de CI/CD
Em pipelines automatizados, a sequência correta é: upload dos arquivos para o S3 primeiro, invalidação depois. Inverter a ordem cria uma janela onde o CloudFront tenta buscar da origem um arquivo que ainda não chegou ao S3.
Exemplo de sequência em shell script para um pipeline:
🔽 Clique para expandir — Script de deploy com invalidação
#!/bin/bash
set -e
DISTRIBUTION_ID="E1EXAMPLE123456"
BUCKET="meu-bucket-exemplo"
BUILD_DIR="./dist"
echo "Fazendo upload dos arquivos para o S3..."
aws s3 sync "$BUILD_DIR" "s3://$BUCKET" \
--delete \
--cache-control "max-age=31536000,public" \
--exclude "index.html"
aws s3 cp "$BUILD_DIR/index.html" "s3://$BUCKET/index.html" \
--cache-control "no-cache,no-store,must-revalidate" \
--content-type "text/html"
echo "Criando invalidação no CloudFront..."
INVALIDATION_ID=$(aws cloudfront create-invalidation \
--distribution-id "$DISTRIBUTION_ID" \
--paths '/index.html' \
--query 'Invalidation.Id' \
--output text)
echo "Invalidação criada: $INVALIDATION_ID"
echo "Aguardando conclusão da invalidação..."
aws cloudfront wait invalidation-completed \
--distribution-id "$DISTRIBUTION_ID" \
--id "$INVALIDATION_ID"
echo "Deploy concluído com sucesso."
O comando aws cloudfront wait invalidation-completed bloqueia a execução do pipeline até que a invalidação seja concluída, evitando que etapas subsequentes de smoke test rodem contra conteúdo ainda desatualizado.
Conclusão e Próximos Passos para Gerenciar Cache no CloudFront
Substituir um arquivo no S3 não é suficiente para atualizar o conteúdo servido pelo CloudFront — o cache da edge precisa ser explicitamente invalidado ou o objeto precisa ter um nome diferente. Para deploys pontuais, a invalidação via CLI é direta e eficaz. Para operações recorrentes, estruture seu pipeline com cache busting por hash de conteúdo e reserve invalidações para casos excepcionais.
Recursos oficiais para aprofundamento:
- Invalidating Files — CloudFront Developer Guide
- Managing How Long Content Stays in an Edge Cache (Expiration)
- CloudFront Pricing
Glossário
| Termo | Definição |
|---|---|
| Edge Location | Ponto de presença do CloudFront onde o conteúdo é armazenado em cache e servido aos usuários finais. |
| Invalidação | Operação que marca objetos em cache no CloudFront como expirados, forçando a busca da versão atualizada na origem na próxima requisição. |
| TTL (Time to Live) | Tempo em segundos que um objeto permanece válido no cache do edge antes de ser revalidado ou removido. |
| Cache Busting | Técnica de incluir um hash ou versão no nome do arquivo para forçar o navegador e o CDN a tratarem o novo arquivo como um objeto diferente. |
| Behavior | Regra de configuração em uma distribuição CloudFront que define como requisições para um determinado path pattern são tratadas, incluindo TTL, métodos HTTP permitidos e política de cache. |
Comentários
Postar um comentário