Pare de queimar dinheiro na AWS: Guia técnico para encontrar recursos zumbis com TypeScript
Source: Dev.to
Custo fantasma na AWS
Se você gerencia infraestrutura na AWS, provavelmente já sentiu aquele calafrio ao abrir a fatura no final do mês.
Não estou falando dos custos óbvios das suas instâncias EC2 de produção. Estou falando do “custo fantasma”:
- O NAT Gateway que ficou ligado em um ambiente de staging deletado há três meses.
- O disco EBS de 500 GB que foi desconectado da instância, mas continua lá, cobrando US$ 0,08/GB todo mês.
Um único NAT Gateway ocioso custa aproximadamente US$ 32,00/mês – cerca de R$ 2.400,00 por um recurso que não trafegou um único byte.
A AWS não facilita a visualização desses desperdícios. O Cost Explorer mostra quanto você gastou, mas raramente aponta o dedo para o ID específico que está drenando seu orçamento.
Uma solução “faça‑você‑mesmo” com TypeScript e AWS SDK v3
Como engenheiro de software, minha primeira reação foi: “Não vou pagar por isso. Vou resolver com código.”
A seguir, mostro como criar um auditor de custos simples que:
- Detecta volumes EBS órfãos (status available).
- Detecta NAT Gateways ociosos (sem conexões nos últimos 7 dias).
Dependências
npm install @aws-sdk/client-ec2 @aws-sdk/client-cloudwatch
npm install -D typescript ts-node @types/node
Script (TypeScript)
import {
EC2Client,
DescribeVolumesCommand,
DescribeNatGatewaysCommand,
} from '@aws-sdk/client-ec2';
import {
CloudWatchClient,
GetMetricStatisticsCommand,
} from '@aws-sdk/client-cloudwatch';
// -------------------------------------------------
// Configuração
// -------------------------------------------------
const REGION = 'us-east-1'; // região alvo
const ec2 = new EC2Client({ region: REGION });
const cw = new CloudWatchClient({ region: REGION });
async function findZombies() {
console.log(`🔍 Iniciando varredura em: ${REGION}...`);
// -------------------------------------------------
// 1️⃣ DETECTAR VOLUMES EBS ÓRFÃOS
// -------------------------------------------------
const volumesData = await ec2.send(
new DescribeVolumesCommand({
Filters: [{ Name: 'status', Values: ['available'] }],
})
);
if (volumesData.Volumes?.length) {
console.log(
`\n🚨 ALERTA: ${volumesData.Volumes.length} volume(s) EBS órfão(s) encontrado(s):`
);
volumesData.Volumes.forEach(vol => {
const cost = (vol.Size ?? 0) * 0.08; // estimativa gp3 (US$ 0,08/GB)
console.log(
` - ID: ${vol.VolumeId} | Tamanho: ${vol.Size} GB | Desperdício: ~$${cost.toFixed(2)}/mês`
);
});
} else {
console.log('\n✅ Nenhum volume EBS órfão.');
}
// -------------------------------------------------
// 2️⃣ DETECTAR NAT GATEWAYS OCIOSOS
// -------------------------------------------------
const natData = await ec2.send(
new DescribeNatGatewaysCommand({
Filters: [{ Name: 'state', Values: ['available'] }],
})
);
if (natData.NatGateways?.length) {
console.log(`\n📡 Analisando ${natData.NatGateways.length} NAT Gateway(s)...`);
for (const nat of natData.NatGateways) {
// Métricas do CloudWatch: ActiveConnectionCount
const metrics = await cw.send(
new GetMetricStatisticsCommand({
Namespace: 'AWS/NATGateway',
MetricName: 'ActiveConnectionCount',
Dimensions: [{ Name: 'NatGatewayId', Value: nat.NatGatewayId! }],
StartTime: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000), // últimos 7 dias
EndTime: new Date(),
Period: 86400, // 1 dia
Statistics: ['Sum'],
})
);
const totalConnections = metrics.Datapoints?.reduce(
(acc, dp) => acc + (dp.Sum ?? 0),
0
) ?? 0;
if (totalConnections === 0) {
console.log(`⚠️ NAT ZUMBI DETECTADO: ${nat.NatGatewayId}`);
console.log(` Custo estimado: ~$32.00/mês | VpcId: ${nat.VpcId}`);
}
}
} else {
console.log('\n✅ Nenhum NAT Gateway ativo.');
}
}
// -------------------------------------------------
findZombies().catch(err => {
console.error('❌ Erro ao executar auditor:', err);
});
Nota técnica
Para manter o exemplo legível, não implementei paginação. Em contas de produção com centenas de recursos, a API da AWS retornará apenas um subconjunto e um NextToken. Você precisará envolver as chamadas em loops while (nextToken) para garantir que nada fique de fora.
Por que não usar scripts caseiros no dia a dia?
| Problema | Impacto |
|---|---|
| Complexidade de paginação | Loops manuais são propensos a erros (infinito ou dados incompletos). |
| Inferno multi‑region | A AWS tem mais de 30 regiões; precisar criar loops para cada uma aumenta a complexidade. |
| Segurança local | É necessário armazenar Access Keys com permissões administrativas na máquina. Se a chave vazar, o risco é total. |
| Manutenção | APIs mudam, métricas evoluem. Manter scripts atualizados consome tempo que poderia ser usado em features do produto. |
A engenharia deve automatizar o tédio, não criar mais manutenção.
InfraLens – Auditoria automática, sem código
Para eliminar esses pontos de atrito, desenvolvi o InfraLens. Ele:
- Encapsula a lógica acima (incluindo paginação automática e varredura multi‑region).
- Empacota tudo em uma ferramenta web gratuita para auditoria.
- Arquitetura 100 % read‑only e agentless – nada é escrito na sua conta.
Segurança por design
| Controle | Como funciona |
|---|---|
| Apenas metadados | A role IAM temporária tem permissão estrita para Describe* e List*. |
| Zero escrita | Não há permissões Create*, Delete* ou Modify*. |
| Sem acesso a dados | Não conseguimos ler o conteúdo de bancos de dados ou objetos S3. |
Dúvida: “Vou conectar minha AWS a uma ferramenta de terceiro?”
Resposta: A conexão é feita via role temporária criada por CloudFormation. Não há chaves permanentes armazenadas localmente.
Resumo
- Identifique recursos ociosos com um script rápido (exemplo acima).
- Considere a complexidade de manutenção, segurança e multi‑region.
- Adote uma solução pronta como o InfraLens para auditoria contínua, segura e sem código.
Se quiser experimentar o script ou conhecer mais sobre o InfraLens, basta comentar abaixo! 🚀
Pode continuar rodando scripts manuais (e debugando paginação no fim de semana), ou pode resolver isso em 5 minutos.
Se você quer ver quanto dinheiro está deixando na mesa agora, liberei o acesso ao Modo Demo (sem login) e ao Scanner Real.
👉 Faça sua auditoria gratuita no InfraLens
Não deixe para descobrir o desperdício só quando o financeiro bater na sua porta.