Configurando um Alarme de Cobrança no Free Tier da AWS com CloudWatch

Você acabou de criar sua conta AWS, ativou alguns serviços para testar e, algumas semanas depois, recebe uma fatura inesperada. Isso acontece com mais frequência do que deveria — configurar um alarme de cobrança para o AWS Free Tier é a primeira coisa que qualquer engenheiro deveria fazer antes de qualquer outra coisa na conta.

TL;DR — Resumo Rápido

EtapaO que fazerServiço envolvido
1Habilitar métricas de cobrança na contaBilling Console
2Criar tópico SNS e confirmar e-mailAmazon SNS
3Criar alarme no CloudWatch com threshold de $5Amazon CloudWatch
4Verificar o alarme via CLIAWS CLI

Como o Alarme de Cobrança do CloudWatch Funciona

Antes de executar qualquer comando, vale entender o fluxo. A métrica EstimatedCharges do namespace AWS/Billing só é publicada na região us-east-1 — independentemente de onde seus recursos estão rodando. Isso não é configurável. Se você criar o alarme em outra região, ele nunca vai disparar porque a métrica simplesmente não existe lá.

A métrica é atualizada várias vezes ao dia pela AWS, mas não em tempo real. Existe uma defasagem natural entre o consumo do recurso e a atualização do valor estimado. Para fins de controle do Free Tier, isso é suficiente.

graph LR A["AWS Billing Service
Agrega consumo estimado"] -->|"Publica métrica
EstimatedCharges"| B["CloudWatch
us-east-1"] B -->|"Avalia threshold
>= $5 USD"| C{"Estado do Alarme"} C -->|"Abaixo do threshold"| D["Estado: OK"] C -->|"Acima do threshold"| E["Estado: ALARM"] E -->|"Dispara ação"| F["Tópico SNS
billing-alarm-freetier"] F -->|"Entrega notificação"| G["E-mail do Engenheiro"]
  1. Billing Service agrega o consumo estimado da conta e publica a métrica EstimatedCharges no CloudWatch (somente em us-east-1).
  2. CloudWatch avalia o valor da métrica contra o threshold configurado ($5). Quando o valor ultrapassa o limiar, o estado do alarme muda para ALARM.
  3. CloudWatch envia uma notificação para o tópico SNS configurado como ação do alarme.
  4. SNS entrega o e-mail para o endereço inscrito no tópico.

Pré-requisito: Habilitar Métricas de Cobrança

A métrica EstimatedCharges não é habilitada por padrão em contas novas. Sem isso, o CloudWatch não terá dados para avaliar e o alarme ficará em estado INSUFFICIENT_DATA para sempre.

Acesse o AWS Billing ConsoleBilling Preferences → marque a opção 'Receive Billing Alerts' e salve. Essa configuração é feita uma única vez e não tem equivalente direto na CLI de billing padrão — precisa ser feita pelo console ou via API do Billing.

Pense nisso como ligar o medidor antes de instalar o alarme. Sem o medidor funcionando, o alarme não tem sinal para monitorar.

Etapa 1 — Criar o Tópico SNS para Notificação

O alarme do CloudWatch precisa de um destino para enviar a notificação. O SNS atua como intermediário entre o alarme e o seu e-mail. Crie o tópico na região us-east-1 — o mesmo lugar onde a métrica de cobrança existe.

aws sns create-topic \
  --name billing-alarm-freetier \
  --region us-east-1

O retorno será um ARN no formato:

{
    "TopicArn": "arn:aws:sns:us-east-1:123456789012:billing-alarm-freetier"
}

Guarde esse ARN — ele será usado nas próximas etapas.

Etapa 2 — Inscrever seu E-mail no Tópico SNS

Com o tópico criado, inscreva o endereço de e-mail que deve receber os alertas. Substitua seu-email@exemplo.com pelo endereço real e o ARN pelo valor retornado na etapa anterior.

aws sns subscribe \
  --topic-arn arn:aws:sns:us-east-1:123456789012:billing-alarm-freetier \
  --protocol email \
  --notification-endpoint seu-email@exemplo.com \
  --region us-east-1

Após executar o comando, a AWS envia um e-mail de confirmação para o endereço informado. Você precisa clicar no link de confirmação antes que o SNS comece a entregar mensagens para esse endereço.

Para verificar se a confirmação foi concluída, consulte o status da assinatura:

aws sns list-subscriptions-by-topic \
  --topic-arn arn:aws:sns:us-east-1:123456789012:billing-alarm-freetier \
  --region us-east-1

No retorno, verifique o valor do campo SubscriptionArn. Se o valor for PendingConfirmation, o link de confirmação no e-mail ainda não foi clicado. Se for um ARN completo (ex: arn:aws:sns:us-east-1:123456789012:billing-alarm-freetier:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx), a assinatura está confirmada e ativa.

Etapa 3 — Criar o Alarme de Cobrança no CloudWatch

Com o tópico SNS confirmado, crie o alarme. Alguns parâmetros aqui merecem atenção: --namespace AWS/Billing é fixo para métricas de cobrança, --metric-name EstimatedCharges é o único nome de métrica válido para esse caso, e --dimensions Name=Currency,Value=USD filtra pelo total em dólares da conta inteira.

aws cloudwatch put-metric-alarm \
  --alarm-name "Freetier-Billing-Alarm-5USD" \
  --alarm-description "Alerta quando cobranças estimadas excedem 5 USD" \
  --namespace AWS/Billing \
  --metric-name EstimatedCharges \
  --dimensions Name=Currency,Value=USD \
  --statistic Maximum \
  --period 86400 \
  --evaluation-periods 1 \
  --threshold 5 \
  --comparison-operator GreaterThanOrEqualToThreshold \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:billing-alarm-freetier \
  --treat-missing-data notBreaching \
  --region us-east-1

Alguns detalhes sobre os parâmetros escolhidos:

  • --statistic Maximum: A métrica EstimatedCharges representa um valor acumulado. Usar Maximum captura o valor mais alto no período, que é o comportamento correto para uma métrica cumulativa.
  • --period 86400: 86400 segundos equivalem a 24 horas. Como a métrica não é atualizada em tempo real, períodos menores podem resultar em avaliações com dados insuficientes.
  • --treat-missing-data notBreaching: Evita que o alarme dispare falsos positivos quando a métrica ainda não foi publicada no período de avaliação.

Etapa 4 — Verificar o Alarme Criado

Depois de criar o alarme, confirme que ele está configurado corretamente antes de confiar nele. Um alarme em estado INSUFFICIENT_DATA logo após a criação é normal — significa que o CloudWatch ainda não coletou dados suficientes para avaliar. O problema seria se ele ficasse nesse estado por mais de 24-48 horas após você ter habilitado as métricas de cobrança.

aws cloudwatch describe-alarms \
  --alarm-names "Freetier-Billing-Alarm-5USD" \
  --region us-east-1

No retorno, verifique os campos principais:

  • StateValue: Esperado OK ou INSUFFICIENT_DATA inicialmente.
  • Threshold: Deve ser 5.0.
  • AlarmActions: Deve conter o ARN do tópico SNS criado.
  • Namespace: Deve ser AWS/Billing.

Diagnóstico: Alarme Criado mas Nunca Dispara

Esse é o padrão de falha mais comum nessa configuração — e o mais silencioso. O alarme existe, parece correto no console, mas mesmo com cobranças acima do threshold, nenhum e-mail chega.

Sintoma: Alarme permanece em INSUFFICIENT_DATA por dias, ou fica em OK mesmo com cobranças visíveis no Billing Dashboard.

Diagnóstico errado: A maioria das pessoas assume que o SNS está com problema e recria o tópico. O SNS raramente é o culpado aqui.

Causa real: As métricas de cobrança não foram habilitadas no Billing Console (o pré-requisito da seção anterior foi pulado), ou o alarme foi criado em uma região diferente de us-east-1.

Verifique se a métrica existe de fato antes de investigar qualquer outra coisa:

aws cloudwatch list-metrics \
  --namespace AWS/Billing \
  --region us-east-1

Se o retorno for uma lista vazia ({ "Metrics": [] }), as métricas de cobrança não estão habilitadas. Volte ao Billing Console e ative a opção 'Receive Billing Alerts'. Se o retorno contiver a métrica EstimatedCharges, o problema está em outro lugar — provavelmente a região do alarme ou a confirmação do SNS.

IAM: Permissões Necessárias

Se você estiver executando esses comandos com um usuário ou role IAM (não com credenciais de root), as seguintes permissões são necessárias:

🔽 Clique para expandir — Política IAM mínima
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "SNSPermissions",
      "Effect": "Allow",
      "Action": [
        "sns:CreateTopic",
        "sns:Subscribe",
        "sns:ListSubscriptionsByTopic"
      ],
      "Resource": "arn:aws:sns:us-east-1:123456789012:billing-alarm-freetier"
    },
    {
      "Sid": "CloudWatchBillingAlarm",
      "Effect": "Allow",
      "Action": [
        "cloudwatch:PutMetricAlarm",
        "cloudwatch:DescribeAlarms",
        "cloudwatch:ListMetrics"
      ],
      "Resource": "*"
    }
  ]
}

Note que cloudwatch:PutMetricAlarm e cloudwatch:ListMetrics requerem "Resource": "*" — essas ações não suportam restrição por ARN de recurso específico conforme documentado na Service Authorization Reference da AWS.

Configurando um Alarme de Cobrança: Próximos Passos

Com o alarme de cobrança ativo, você tem uma rede de segurança básica para o Free Tier. Para ir além:

  • Configure AWS Budgets para alertas mais granulares por serviço — o CloudWatch Billing Alarm monitora o total da conta, enquanto o Budgets permite definir limites por serviço individual (EC2, S3, Lambda, etc.).
  • Habilite o AWS Cost Explorer para visualizar a tendência de gastos antes que o alarme dispare.
  • Considere criar alarmes adicionais com thresholds progressivos (ex: $1, $3, $5) para ter visibilidade antes de atingir o limite crítico.

Documentação oficial de referência:

Glossário

TermoDefinição
EstimatedChargesMétrica do CloudWatch no namespace AWS/Billing que representa o valor estimado acumulado de cobranças da conta em USD. Publicada somente em us-east-1.
SNS TopicCanal de mensageria da AWS que recebe notificações do CloudWatch e as entrega para os assinantes (e-mail, HTTP, Lambda, etc.).
ThresholdValor numérico que define o limite de disparo do alarme. Quando a métrica ultrapassa esse valor, o estado muda para ALARM.
INSUFFICIENT_DATAEstado do alarme quando não há dados suficientes para avaliação. Normal logo após a criação; problemático se persistir após 48h com métricas habilitadas.
treat-missing-dataParâmetro do CloudWatch que define como o alarme se comporta quando não há dados no período de avaliação. O valor notBreaching evita falsos positivos.

Comentários

Postagens mais visitadas deste blog

EC2 SSH Connection Timeout: Quais Regras do Security Group Verificar

EC2 Sem Acesso à Internet em VPC Customizada: Como Configurar Internet Gateway e Route Table

S3 Access Denied: Por que 'Bloquear Acesso Público' impede seu objeto mesmo após torná-lo público