Automated Billing Alerts & Daily Recaps
A robust cloud cost management solution built with Infrastructure as Code (IaC) to proactively monitor and report AWS expenditure.
This project automates cloud cost management on AWS. It provides proactive notifications for potential overspending and daily expenditure summaries directly to your inbox, all provisioned using Terraform.
Manual cloud cost monitoring is inefficient and often reactive. AWS Cost Guard offers:
A high-level view of the AWS services orchestrating the Cost Guard solution.
See the AWS Cost Guard in action, from automated budget alerts to daily expenditure summaries delivered right to your inbox.
A sample of the daily cost summary email.
Monitoring the configured budget alerts.
Ensuring notifications are successfully subscribed.
The core Python Lambda function queries the AWS Cost Explorer API and formats the daily spending data for notifications.
import boto3
import os
import json
from datetime import datetime, timedelta
def handler(event, context):
sns_topic_arn = os.environ['SNS_TOPIC_ARN']
ce_client = boto3.client('ce') # Region automatically picked up by Lambda runtime
sns_client = boto3.client('sns')
end_date = datetime.utcnow().date()
start_date = end_date - timedelta(days=1) # Get yesterday's cost
try:
response = ce_client.get_cost_and_usage(
TimePeriod={
'Start': start_date.strftime('%Y-%m-%d'),
'End': end_date.strftime('%Y-%m-%d')
},
Granularity='DAILY',
Metrics=['UnblendedCost']
)
cost_data = response['ResultsByTime'][0]['Total']['UnblendedCost']
amount = float(cost_data['Amount'])
unit = cost_data['Unit']
message = f"Daily AWS Cost Recap for {start_date.strftime('%Y-%m-%d')}:\n" \
f"Total Unblended Cost: {amount:.2f} {unit}\n" \
f"-----------------------------------------\n" \
f"This is an automated notification."
sns_client.publish(
TopicArn=sns_topic_arn,
Message=message,
Subject=f"Daily AWS Cost Recap - {start_date.strftime('%Y-%m-%d')}"
)
print(f"SNS notification sent successfully for {start_date}.")
except Exception as e:
print(f"Error getting cost data or sending SNS: {e}")
raise e # Re-raise for CloudWatch logs to capture errors
return {
'statusCode': 200,
'body': json.dumps('Cost recap processed!')
}
Attempted to set `AWS_REGION` in Lambda, which is a reserved key.
Solution:
Removed `AWS_REGION` from Terraform. Lambda automatically injects it, avoiding conflicts and reinforcing understanding of Lambda's inherent environment variables.
Encountered an error with `time_period_start` in `aws_budgets_budget` due to incorrect timestamp format.
Solution:
Modified `formatdate` in Terraform to match AWS Budgets API's specific `YYYY-MM-DD_HH:mm` format, highlighting the importance of API-specific documentation.
Resources created by Terraform were not visible in the AWS Console.
Solution:
Resolved by verifying and correcting the AWS Console's region and account ID, reinforcing the regional nature of most AWS services.
Confirmation emails for SNS topic subscriptions were not always reaching the specified `admin_email`.
Solution:
Checked spam/junk, used "Request confirmation" in SNS console, and considered alternative email providers to overcome aggressive spam filters.