Back

AWS Cost Guard

Automated Billing Alerts & Daily Recaps

A robust cloud cost management solution built with Infrastructure as Code (IaC) to proactively monitor and report AWS expenditure.

Key AWS Services

AWS Lambda Logo Lambda
AWS SNS Logo SNS
AWS Budgets Logo Budgets
AWS CloudWatch Logo CloudWatch Events
AWS IAM Logo IAM
AWS Cost Explorer Logo Cost Explorer
Python Logo Python 3.9

Project Goal

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.

Addressing the Challenge

Manual cloud cost monitoring is inefficient and often reactive. AWS Cost Guard offers:

  • Proactive Alerts: Email notifications for budget thresholds.
  • Daily Recaps: Concise daily email summaries.
  • IaC Deployment: Consistent, repeatable, and version-controlled infrastructure.

Architecture Overview

AWS Cost Guard Architecture Diagram

A high-level view of the AWS services orchestrating the Cost Guard solution.

Results & Demonstration

See the AWS Cost Guard in action, from automated budget alerts to daily expenditure summaries delivered right to your inbox.

Daily Cost Recap Email

Daily Cost Recap Email Screenshot

A sample of the daily cost summary email.

AWS Budgets Console

AWS Budgets Console Screenshot

Monitoring the configured budget alerts.

SNS Subscription Screenshot

Ensuring notifications are successfully subscribed.

Implementation Details & Code Highlights

The core Python Lambda function queries the AWS Cost Explorer API and formats the daily spending data for notifications.

Python Lambda Function (`lambda_function.py` excerpt)


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!')
    }
            

Challenges & Solutions

`AWS_REGION` Environment Variable Conflict

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.

`time_period_start` Format Error in AWS Budgets

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.

AWS Console Region/Account Mismatch

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.

SNS Subscription Confirmation Emails Not Arriving

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.

Lessons Learned