AWS Cost Anomaly Detection is one of the most under-deployed features in AWS. It is free, takes 30 minutes to wire up, and routinely catches misconfigurations that would otherwise burn $5,000 before anyone notices.
This post walks through the full setup, plus a Lambda function that posts anomalies to Slack with rich formatting.
Step-by-step Workflow
- 01Enable Cost Anomaly Detection (Cost Explorer)
Console → Billing → Cost Anomaly Detection. Create a monitor for “AWS services” at the account level.
- 02Create an SNS topic for anomaly events
One topic per environment. We use
finops-anomalies-prodandfinops-anomalies-dev. - 03Subscribe a Lambda function to the SNS topic
The Lambda transforms AWS’s JSON payload into a Slack-friendly Block Kit message.
- 04Configure threshold and Slack channel routing
$50 minimum impact for dev, $500 for prod. Different Slack channels per severity.
- 05Test with the AWS-provided sample event
Console → Lambda → Test → use the SNS sample template; verify the Slack message renders.
The Lambda Function (Python 3.12)
import json
import os
import urllib.request
SLACK_WEBHOOK_URL = os.environ["SLACK_WEBHOOK_URL"]
def lambda_handler(event, context):
"""Forward AWS Cost Anomaly Detection events to Slack."""
for record in event.get("Records", []):
anomaly = json.loads(record["Sns"]["Message"])
impact = anomaly.get("impact", {})
total = impact.get("totalImpact", 0)
service = anomaly.get("anomalyDetails", {}).get("service", "Unknown")
message = {
"text": f":rotating_light: AWS cost anomaly: ${total:.2f} on {service}",
"blocks": [
{
"type": "header",
"text": {"type": "plain_text", "text": ":money_with_wings: Cost Anomaly Detected"},
},
{
"type": "section",
"fields": [
{"type": "mrkdwn", "text": f"*Service:*n{service}"},
{"type": "mrkdwn", "text": f"*Impact:*n${total:,.2f}"},
{"type": "mrkdwn", "text": f"*Account:*n{anomaly.get('accountId', '-')}"},
{"type": "mrkdwn", "text": f"*Region:*n{anomaly.get('region', '-')}"},
],
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {"type": "plain_text", "text": "Open in Cost Explorer"},
"url": "https://console.aws.amazon.com/cost-management/home#/anomaly-detection",
}
],
},
],
}
req = urllib.request.Request(
SLACK_WEBHOOK_URL,
data=json.dumps(message).encode("utf-8"),
headers={"Content-Type": "application/json"},
)
urllib.request.urlopen(req, timeout=5)
return {"statusCode": 200}
The IAM Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
}
What to Watch For
- S3 PUT spikes from a misconfigured CI job
- NAT Gateway data transfer surprises (cross-AZ chatty workloads)
- CloudWatch Logs ingestion explosions (forgotten DEBUG level)
- EC2 instance type drift after a Karpenter config change
Ready to optimize your cloud or AI footprint?
Book a free 30-minute architecture review. We will deliver a written cost-and-architecture audit within 48 hours.
Need help with AWS cost anomaly detection?
Ohveda runs free 30-minute architecture reviews. We will identify your top opportunities in writing within 48 hours — at no cost.