Proactive AWS cost monitoring and alerting system
The AWS Billing Monitor is an automated solution that tracks AWS spending and alerts your team when costs change significantly. After experiencing billing incidents that weren't caught by existing monitoring solutions, this system was created to provide proactive cost oversight.
There have been 2 incidents in the last few months that weren't triggered by our existing monitoring solutions. To prevent future billing surprises, we implemented aws-billing-monitor-production which tracks the Cost Explorer data daily and automatically alerts when costs deviate from expected patterns.
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β CloudWatch β β Lambda β β Cost Explorer β
β Events βββββΆβ Function βββββΆβ API β
β (Daily) β β β β β
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β
β
βββββββββββββΌββββββββββββ
β β
βΌ βΌ
ββββββββββββββββ ββββββββββββββββ
β SNS β β Slack β
β (Email) β β Webhook β
ββββββββββββββββ ββββββββββββββββ
- π Rolling 7-Day Comparison: Compares last 7 days vs previous 7 days for fair analysis
- π― Configurable Thresholds: Alert when cost changes exceed specified percentage (default: 15%)
- π§ Multi-Channel Alerts: Email (SNS) and Slack notifications
- π Service-Level Analysis: Identifies which AWS services are driving cost changes
- π CloudWatch Dashboard: Monitor function performance and billing trends
- π Secure: Follows AWS security best practices with least-privilege IAM
- π Infrastructure as Code: Complete Terraform deployment
- AWS CLI configured with appropriate permissions
- Terraform >= 1.0 installed
- Cost Explorer enabled in your AWS account
- Email addresses for notifications
- Slack webhook URL (optional)
Edit terraform.tfvars:
aws_region = "us-east-1"
environment = "production"
threshold_percentage = 1
email_addresses = [
"sunil@xyz.com"
]
slack_webhook_url = "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK"
lambda_schedule = "rate(1 day)"terraform init
terraform plan
terraform applyCheck your email for AWS SNS confirmation messages and click the confirmation links.
# Manual test
aws lambda invoke \
--function-name aws-billing-monitor-production \
--payload '{}' \
response.json
# View logs
aws logs tail /aws/lambda/aws-billing-monitor-production --followThe monitor uses rolling 7-day periods for fair comparison:
Today: Friday, Sept 13, 2025
Current Period: [Sept 7] β [Sept 13] (7 days)
Previous Period: [Aug 31] β [Sept 6] (7 days)
This ensures equal comparison periods regardless of when the function runs.
- Fetch Cost Data: Retrieves costs from AWS Cost Explorer API
- Calculate Changes: Compares total costs and service-level costs
- Threshold Check: Alerts if change exceeds configured percentage
- Service Breakdown: Identifies which services changed most significantly
{
"statusCode": 200,
"body": {
"message": "Billing analysis completed",
"alert_sent": true,
"total_current": "1250.45",
"total_previous": "980.32",
"percentage_change": 27.54
}
}| Variable | Description | Default |
|---|---|---|
THRESHOLD_PERCENTAGE |
Alert threshold (%) | 10 |
SNS_TOPIC_ARN |
SNS topic for emails | - |
SLACK_WEBHOOK_URL |
Slack webhook URL | - |
| Variable | Description | Default |
|---|---|---|
threshold_percentage |
Alert threshold | 15 |
email_addresses |
Email list for alerts | [] |
slack_webhook_url |
Slack webhook | "" |
lambda_schedule |
Execution schedule | "rate(1 day)" |
rate(1 day)- Daily at midnight UTCrate(12 hours)- Twice dailycron(0 9 ? * MON *)- Every Monday at 9 AMcron(0 18 ? * FRI *)- Every Friday at 6 PM
Subject: AWS Billing Alert - Significant Cost Change
AWS Billing Alert - Significant Cost Change Detected
SUMMARY:
========
Current Period (2025-09-07 to 2025-09-13): $1,250.45
Previous Period (2025-08-31 to 2025-09-06): $980.32
Change: $270.13 (27.54%)
SERVICE-LEVEL CHANGES:
=====================
Amazon Elastic Compute Cloud - Compute:
Current: $450.23
Previous: $320.15
Change: $130.08 (40.63%)
Amazon Simple Storage Service:
Current: $89.45
Previous: $65.23
Change: $24.22 (37.12%)
Rich Slack notifications with:
- Color-coded alerts (red for increases, green for decreases)
- Cost comparison tables
- Service breakdown
- Direct links to AWS Console
Access the dashboard at:
https://us-east-1.console.aws.amazon.com/cloudwatch/home?region=us-east-1#dashboards:name=aws-billing-monitor-production-dashboard
# Real-time logs
aws logs tail /aws/lambda/aws-billing-monitor-production --follow
# Search for alerts
aws logs filter-log-events \
--log-group-name /aws/lambda/aws-billing-monitor-production \
--filter-pattern "Alert required"
# Error tracking
aws logs filter-log-events \
--log-group-name /aws/lambda/aws-billing-monitor-production \
--filter-pattern "ERROR"- Check spam/junk folders
- Confirm SNS subscription via email
- Verify email addresses in
terraform.tfvars
# Check subscription status
aws sns list-subscriptions-by-topic \
--topic-arn $(terraform output -raw sns_topic_arn)- Ensure Cost Explorer is enabled (24-hour delay for data)
- Verify Lambda has Cost Explorer permissions
- Check date ranges in logs
# Test Cost Explorer access
aws ce get-cost-and-usage \
--time-period Start=2025-01-01,End=2025-01-02 \
--granularity DAILY \
--metrics BlendedCost- Increase timeout in Terraform (default: 300s)
- Check for large number of services in account
# Function status
aws lambda get-function --function-name aws-billing-monitor-production
# Manual invoke with logs
aws lambda invoke \
--function-name aws-billing-monitor-production \
--log-type Tail \
--payload '{}' \
response.json
# Test SNS
aws sns publish \
--topic-arn $(terraform output -raw sns_topic_arn) \
--subject "Test" \
--message "Test message"The Lambda function uses minimal required permissions:
- Cost Explorer read access
- SNS publish to specific topic
- CloudWatch Logs write access
- No sensitive data in logs
- Environment variables for configuration
- Encryption at rest for SNS topics
- VPC deployment option available
Modify the Lambda function for service-specific thresholds:
service_thresholds = {
'Amazon Elastic Compute Cloud - Compute': 20, # 20% for EC2
'Amazon Simple Storage Service': 15, # 15% for S3
'default': 10 # 10% for others
}Deploy across multiple AWS accounts using cross-account roles.
- ServiceNow incident creation
- Datadog metrics export
- PagerDuty integration
- Custom webhooks
- Estimated monthly cost: $2-5 (including logs, SNS)
- Execution time: ~30-60 seconds daily
- Memory: 256MB (optimized)
- CloudWatch Logs: 14 days (configurable)
- Cost Explorer: No additional charges
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
- Initial release with basic cost monitoring
- Email and Slack notifications
- Terraform deployment
- Added rolling 7-day comparison
- Service-level cost breakdown
- CloudWatch dashboard
- Enhanced error handling
For issues or questions:
- Check troubleshooting section above
- Review CloudWatch logs
- Open GitHub issue with logs and configuration
MIT License - see LICENSE file for details.
Built with β€οΈ to prevent billing surprises