O problema dos picos inesperados de tráfego em NAT Gateways
Lidar com picos inesperados de tráfego no serviço de Network Address Translation (NAT) Gateways da AWS pode ser bem complicado. Os VPC Flow Logs trazem insights valiosos sobre o tráfego de rede, mas gravá-los o tempo todo gera custos desnecessários de armazenamento e uma enxurrada de dados que talvez nem sejam relevantes durante a operação normal.
E se desse para habilitar os VPC Flow Logs de forma seletiva, só quando um aumento de tráfego fosse detectado?
Este post explora uma solução que cria dinamicamente um gravador temporário de VPC Flow Logs sempre que um limite de tráfego predefinido é ultrapassado. A abordagem garante economia ao reduzir o armazenamento de dados e, ao mesmo tempo, fornece informações cruciais para investigar e entender padrões de tráfego inesperados.
Por que se preocupar com o tráfego que passa pelos NAT Gateways?
Usar NAT Gateways tem um custo. Você paga para mantê-los no ar — na região de North Virginia, US$ 0,045 por hora. E paga também pelo volume de tráfego que passa por eles: US$ 0,045 por GB de entrada/saída. Isso vale para tudo que trafega pelo NAT Gateway, inclusive para um recurso regional como o S3.
A conta sobe rápido, porque para cada TB de dados, você paga:
1.024 GB x US$ 0,045 = US$ 46,08
Para 10 TB, são US$ 460.
E assim por diante.
Este post nasceu de uma dúvida de um cliente sobre tráfego inesperado via NAT Gateway que disparava aleatoriamente para 35 TB, gerando um custo adicional e imprevisto de US$ 1.600 por pico. Eles não faziam ideia do motivo e não queriam ativar os VPC Flow Logs durante o mês inteiro (veja mais adiante a seção sobre custos de VPC Flow Logs para entender o porquê).
Como funcionam os VPC Flow Logs
Citando a documentação da AWS, que explica isso de forma bem clara:
VPC Flow Logs é um recurso que permite capturar informações sobre o tráfego IP que entra e sai das interfaces de rede da sua VPC. Os dados de flow log podem ser publicados nos seguintes destinos: Amazon CloudWatch Logs, Amazon S3 ou Amazon Data Firehose. Depois de criar um flow log, você pode recuperar e visualizar os registros no log group, bucket ou delivery stream que configurou.
Os flow logs ajudam em várias tarefas, como:
\* Diagnosticar regras de security group restritivas demais
\* Monitorar o tráfego que chega à sua instância
\* Determinar a direção do tráfego de e para as interfaces de rede
Os dados dos flow logs são coletados fora do caminho do tráfego de rede e, por isso, não afetam a vazão nem a latência. Você pode criar ou excluir flow logs sem qualquer risco para o desempenho da rede.
Este post e o repositório que o acompanha tratam da gravação do tráfego e da sua ingestão em um log group específico do Amazon CloudWatch Logs, onde todos os logs ficam armazenados e disponíveis para análise.
Por padrão, ao habilitar os VPC Flow Logs para um NAT Gateway, os logs ficam no formato a seguir e podem ser visualizados no respectivo CloudWatch Log Group:

Registros típicos de Flow Logs no CloudWatch Logs
O custo da gravação contínua de VPC Flow Logs
Este post trata do armazenamento dos dados gravados em CloudWatch Log Groups, então é importante entender os custos associados aos dados ingeridos nos logs. Confira a tabela de preços do CloudWatch Logs aqui.
Suponha que você esteja usando 10 NAT Gateways, cada um enviando 1.000 requisições por segundo dos seus serviços para a Internet e recebendo apenas uma resposta para cada requisição. Gravar esse tráfego com VPC Flow Logs faz com que sejam ingeridos 2.000 registros (1.000 enviados + 1.000 das respostas) por segundo no CloudWatch Logs via VPC Flow Logs.
Vamos supor que cada registro tenha 100 bytes (pode ser menor ou maior, dependendo do nível de detalhe). Por mês, o CloudWatch Logs vai ingerir registros com tamanho total de:
10 (NAT Gateways) X 2.000 (registros por segundo) X 100 (bytes por registro) X 86.400 (segundos por dia) X 30,5 (média de dias por mês) = 5.270.400.000.000 bytes.
Ou seja, cerca de 5,2 TB ingeridos por mês.
O cálculo do custo de um mês de ingestão é feito com base na taxa de US$ 0,5 por GB para até 10 TB de dados:
5.200 GB * 0,5 (US$ por GB ) = US$ 2.600 por mês (pode ser metade, ou seja, "apenas" US$ 1.300, se você ingerir em um CloudWatch Logs Group configurado com a Infrequent Access Log Class)
Agora suponha que os picos de tráfego que você quer capturar aconteçam só uma ou duas vezes por mês, durem apenas 15 minutos e movimentem muitos dados pelo NAT Gateway nesse intervalo.
Vale notar que a quantidade de dados transmitidos não significa, necessariamente, que mais registros serão criados no VPC Flow Log.
Pense, por exemplo, na diferença entre passar um arquivo de 10 MB ou um de 1 KB por um NAT Gateway. Cada arquivo transferido pelo NAT Gateway gera apenas um registro. O arquivo de 10 MB não gera mais de um registro de VPC Flow Log, mesmo sendo maior que o de 1 KB, que também gera apenas um registro.
O custo do tráfego do NAT Gateway sobe por um fator de 10⁰⁴ por causa do volume de tráfego muito maior.
Queremos capturar esses picos sem pagar por um mês inteiro de gravação de VPC Flow Logs.
Acionando VPC Flow Logs temporários
A solução garante a gravação dos VPC Flow Logs sempre que o tráfego de um NAT Gateway ultrapassar determinado limite. Por exemplo, se o padrão normal de um NAT Gateway é de 10 MB por minuto, dá para configurar um alarme para disparar quando o tráfego ultrapassar 100 MB por minuto durante um período específico.
A solução não é prática para picos de tráfego muito curtos, já que os VPC Flow Logs só são criados depois que o pico é detectado. O pico não precisa ser muito longo para ser capturado, mas precisa durar mais de 3 minutos para garantir que a gravação do tráfego comece.
Arquitetura da solução
A solução cria um CloudWatch Alarm para cada NAT Gateway que você especificar durante a instalação.
Esses alarmes são correspondidos por uma EventBridge Rule que dispara uma Step Function.
A Step Function é responsável por iniciar a gravação dos VPC Flow Logs para o NAT Gateway em estado de alarme. Em seguida, ela exclui o processo de gravação dos VPC Flow Logs, mas mantém os dados já gravados. Ao final da gravação, o SNS envia um e-mail para o endereço informado durante a instalação.
A solução é implementada com AWS SAM e consiste em duas stacks do CloudFormation. A primeira implanta macros do CloudFormation para simplificar o processo de implantação. Essas macros incluem:
- Uma macro que gera automaticamente alarmes do CloudWatch para cada NAT Gateway especificado, simplificando a configuração.
- Outra macro que contorna uma limitação do CloudFormation, que não permite converter parâmetros do tipo string em inteiros.
A segunda stack cria os componentes principais da solução:
- Tabela DynamoDB: armazena a contagem de gravações realizadas por NAT Gateway e mantém um callback token usado quando o alarme retorna ao estado "OK".
(Um callback token é gerado dentro de uma Task da Step Function. Quando essa task é executada, ela aguarda ser notificada antes de continuar para a próxima etapa. A função Lambda acionada quando o alarme volta ao estado "OK" lê esse token e o utiliza para "avisar" a Step Function que ela pode parar de esperar e retomar a operação.)
Isso ajuda a gerenciar o processo de gravação e garante uma retomada tranquila depois que o alarme é resolvido.
- CloudWatch Alarms: esses alarmes monitoram os NAT Gateways especificados em busca de tráfego acima do limite definido.
- EventBridge Rules: duas regras do EventBridge são configuradas para orquestrar o fluxo. Uma dispara uma Step Function quando o alarme do CloudWatch é ativado; a outra dispara uma função Lambda quando o alarme volta para "OK". Essa abordagem orientada a eventos garante uma resposta rápida às variações de tráfego.
- Step Function: orquestra a criação, o gerenciamento e a exclusão dos VPC Flow Logs. Inclui as seguintes etapas:
— Verificação para garantir que o número máximo de gravações desejadas não foi atingido, evitando gravações desnecessárias.
— Criação de VPC Flow Logs para cada ENI associada ao NAT Gateway, capturando informações detalhadas de tráfego.
— Um estado de espera que pausa o fluxo até que o alarme volte para "OK" ou o limite de tempo predefinido seja atingido, garantindo que a gravação continue por um período suficiente.
— Exclusão da configuração do VPC Flow Log, preservando os logs gravados pelo tempo escolhido durante a implantação da Stack do CloudFormation.
— Envio de uma notificação por e-mail via SNS aos destinatários definidos, com atualizações em tempo hábil sobre o status da gravação.
- Funções Lambda:
São duas funções. Uma é chamada pela Step Function para recuperar as ENIs do NAT Gateway em estado de alarme e criar os VPC Flow Logs para essas ENIs. A outra é acionada pela EventBridge Rule quando o alarme do CloudWatch volta para "OK". Ela recupera o callback token da Step Function no DynamoDB e chama a Step Function para retomar a operação.
A estrutura da Step Function pode ser vista aqui:

Armazenamento e análise eficientes de logs
Esta solução usa a classe de armazenamento Infrequent Access do CloudWatch Logs Group para guardar os VPC Flow Logs. Essa classe oferece uma opção econômica e permite consultas e análises eficientes com o CloudWatch Logs Insights.
Analisando os dados dos VPC Flow Logs
Ao final de uma sessão de gravação de VPC Flow Logs, é enviado um e-mail com um deep link para o VPC Flow Logs Group criado e o prefixo dos log streams gravados.
A solução fornece um formato de consulta predefinido para o CloudWatch Logs Insights, permitindo extrair insights relevantes dos dados coletados. Para gerar uma saída legível, basta acessar o CloudWatch Logs Insights e escolher a consulta "Serverless Auto VPC Flow Log Recorder" na seção "Saved Queries" e executá-la sobre o Flow Log.
fields @timestamp, @message
| parse @message "* * * * * * * * * * * * * *" as action, flowDirection, trafficPathNum, srcAddr, srcPort, dstAddr, dstPort, proto, bytes, type, pkt_srcaddr, SrcService, pkt_dstaddr, DstService
| display @timestamp, action, flowDirection,
if(trafficPathNum == 1, "Through another resource in the same VPC",
if(trafficPathNum == 2, "Through an internet gateway or a gateway VPC endpoint",
if(trafficPathNum == 3, "Through a virtual private gateway",
if(trafficPathNum == 4, "Through an intra-region VPC peering connection",
if(trafficPathNum == 5, "Through an inter-region VPC peering connection",
if(trafficPathNum == 6, "Through a local gateway",
if(trafficPathNum == 7, "Through a gateway VPC endpoint (Nitro-based instances only)",
if(trafficPathNum == 8, "Through an internet gateway (Nitro-based instances only)",
"unknown")))))))) as trafficPath,
srcAddr, srcPort, dstAddr, dstPort,
if(proto == 6, "TCP",
if(proto == 17, "UDP",
proto)) as protocol,
bytes, type, pkt_srcaddr, SrcService, pkt_dstaddr, DstService
| sort @timestamp desc
| limit 1000
Veja abaixo um exemplo da saída dessa consulta, que mostra que o VPC S3 Gateway Endpoint não estava configurado na VPC. Como resultado, o tráfego para o S3 passa pelo NAT Gateway e pela Internet.
Identificando tráfego roteado pela Internet
A solução também ajuda a identificar tráfego que flui pela Internet em vez dos VPC endpoints. Se o tráfego for direcionado a um serviço da AWS via Internet, o nome do serviço aparece nos campos SrcService ou DstService na saída do CloudWatch Logs Insights (veja o exemplo acima, com tráfego destinado ao serviço S3). Essas informações ajudam a decidir se vale a pena configurar VPC endpoints para serviços específicos, aumentando a segurança e reduzindo custos.
Repositório no GitHub
Você pode revisar e seguir as instruções de instalação desta solução neste repositório no GitHub.
Chamada para ação
Espero que este post tenha trazido insights valiosos. Se você quiser saber mais ou tiver interesse nos nossos serviços, fale com a gente. É só entrar em contato aqui
Referências adicionais
Atualização de fevereiro de 2025
O repositório associado no GitHub tem uma nova branch chamada JSONata, com uma versão atualizada do ASL da Step Function que usa JSONata e variáveis para um código menor, mais claro e mais inteligente. O próprio ASL foi extraído do template YAML do SAM para um arquivo JSON próprio, referenciado pelo template.
A solução proposta grava metadados do tráfego que passa pelos NAT Gateways apenas quando o volume ultrapassa determinado limite, reduzindo custos e o registro de dados irrelevantes. Por ser Serverless, a solução reduz ainda mais os custos: você não paga enquanto nada está sendo gravado.