aboutsummaryrefslogtreecommitdiff

Overview

This project is a Python-based tool that sends a daily plaintext email summarizing key AWS environment metrics and alerts. It is modular, configurable, and intended for solo or small-team AWS accounts that want automated visibility into infrastructure health, security, and cost.

Features

  • ✅ Daily billing breakdown (Cost Explorer)
  • ✅ New Security Hub findings
  • ✅ Route 53 health check status
  • ✅ CloudWatch alarms triggered in the last 24 hours
  • ✅ S3 bucket access/encryption audit
  • ✅ Expiring ACM certificates (next 30 days)
  • ✅ AWS Config non-compliant resources
  • ✅ CloudFront distribution changes (last 48h)
  • ✅ WAF blocked request summary (regional)

The program is configured to be modular and accept new sections to the report as needed. To create a new section, simply create the new_section.py script inside the sections/ directory and update the sections variable inside the config.toml file.

Directory Structure

.
├── README.org             ; This file
├── config.toml            ; Configuration (AWS profile, region, etc.)
├── email_formatter.py     ; Utility to format email body
├── main.py                ; Main entry point for report generation
├── pyproject.toml         ; Project metadata and dependencies
├── utils.py               ; Shared utility functions
├── sections/              ; Modular report generators
   ├── acm.py             ; ACM expiring certs
   ├── cloudfront.py      ; CloudFront changes
   ├── cloudwatch.py      ; Alarms
   ├── config.py          ; Config compliance
   ├── costexplorer.py    ; Billing
   ├── route53.py         ; Health checks
   ├── s3.py              ; Bucket audit
   └── securityhub.py     ; Findings

Usage

1. Configure

Edit config.toml to configure your AWS, email, and report options:

[aws]
profile = "default"
region = "us-east-1"

[email]
from = "you@example.com"
to = ["you@example.com"]
subject = "Daily AWS Report"

[recipients]
emails = [
    "you@example.com"
]

[report]
sections = [
    "acm"
]

If you do not already have an AWS profile (e.g., default), then you will need to install the AWS CLI and configure a profile first:

aws configure --profile default

2. Run

Use Python to run the report and send the email:

python main.py

Or, if you're using uv (which will auto-install dependencies and create a virtual environment):

uv run main.py

Emails are plaintext with ASCII-formatted tables (via tabulate).

UV Run

Installation

Dependencies

Python 3.11+ is recommended. Install dependencies using:

pip install -r requirements.txt
# or if you're using uv:
uv sync

You may need to install:

  • boto3
  • tabulate

AWS Permissions

Ensure your IAM user or role has read access to:

  • Cost Explorer
  • Security Hub
  • S3, CloudFront, CloudWatch
  • Route 53, ACM, Config, WAF
  • SES (if sending emails from within AWS)

Customizing Sections

Each section is defined in a file under sections/ and implements a:

def get_section(config) -> str:
    ...

You can add, remove, or modify these sections in config.toml.

Example Output

Here's an example of the output in plain text format.

Expiring TLS Certificates:
No certs expiring in the next 30 days.

CloudFront Changes:
No distributions changed in the last 48h.

CloudWatch Alarms:
No alarms triggered in the last 24h.

AWS Config Non-Compliant Resources:
[https://eu-west-1.console.aws.amazon.com/config/home#/resources?complianceType=NON_COMPLIANT]
┌───────────────────────────────────────┬────────────────────────┐
 Resource Type                          Resource ID            
├───────────────────────────────────────┼────────────────────────┤
 AWS::::Account                         <account-id>           
├───────────────────────────────────────┼────────────────────────┤
 AWS::EC2::VPC                          vpc-<id>               
├───────────────────────────────────────┼────────────────────────┤
 AWS::EC2::Subnet                       subnet-<id>            
├───────────────────────────────────────┼────────────────────────┤
 AWS::EC2::Subnet                       subnet-<id>            
├───────────────────────────────────────┼────────────────────────┤
 AWS::EC2::Subnet                       subnet-<id>            
├───────────────────────────────────────┼────────────────────────┤
 AWS::EC2::VPCBlockPublicAccessOptions  <account-id>           
├───────────────────────────────────────┼────────────────────────┤
 AWS::EC2::SecurityGroup                sg-<id>                
├───────────────────────────────────────┼────────────────────────┤
 AWS::S3::Bucket                        example-cf-logs        
├───────────────────────────────────────┼────────────────────────┤
 AWS::S3::Bucket                        img.example.com        
└───────────────────────────────────────┴────────────────────────┘

AWS Billing Report for 2025-06-18
[https://eu-west-1.console.aws.amazon.com/costmanagement/]
┌────────────────────────────────────┬────────┐
 Service                               Cost 
├────────────────────────────────────┼────────┤
 AWS CloudShell                       $0.00 
 AWS Config                           $0.17 
 AWS Glue                             $0.00 
 AWS HealthImaging                    $0.00 
 AWS Key Management Service           $0.00 
 AWS Migration Hub Refactor Spaces    $0.00 
 AWS Secrets Manager                  $0.00 
 AWS Security Hub                     $0.00 
 AWS Service Catalog                  $0.00 
 AWS WAF                              $0.29 
 Amazon CloudFront                    $0.00 
 Amazon GuardDuty                     $0.00 
 Amazon Location Service              $0.00 
 Amazon Route 53                      $0.01 
 Amazon Simple Notification Service   $0.00 
 Amazon Simple Queue Service          $0.00 
 Amazon Simple Storage Service        $0.00 
 AmazonCloudWatch                     $0.00 
 CloudWatch Events                    $0.00 
├────────────────────────────────────┼────────┤
 TOTAL                                $0.47 
└────────────────────────────────────┴────────┘

Note: Costs are estimated and may change.

Route 53 Health Checks:
[https://eu-west-1.console.aws.amazon.com/route53/v2/healthchecks/home]
┌────────────────────┬──────────┐
 Domain              Status   
├────────────────────┼──────────┤
 img.example.com     HEALTHY  
└────────────────────┴──────────┘

S3 Bucket Access Summary:
[https://eu-west-1.console.aws.amazon.com/s3/home]
┌──────────────────────────────────────────────┬────────┬────────────┐
 Bucket                                        Public  Encrypted  
├──────────────────────────────────────────────┼────────┼────────────┤
 aws-cloudtrail-logs-<account-id>-<suffix>     No      Yes        
 example-cf-logs                               No      Yes        
 img.example.com                               No      Yes        
└──────────────────────────────────────────────┴────────┴────────────┘

AWS Security Hub Findings (Last 24h): 18 new finding(s)
[https://eu-west-1.console.aws.amazon.com/securityhub/home?region=eu-west-1#/findings]
┌───────────────┬────────────────────────────────────────────────────┬──────────────┬────────────────────────────────┐
 Severity       Title                                               Product       Resource                       
├───────────────┼────────────────────────────────────────────────────┼──────────────┼────────────────────────────────┤
 INFORMATIONAL  S3 buckets should have server access logging        Security Hub  arn:aws:s3:::img.example.com   
 INFORMATIONAL  S3 buckets should require requests to use HTTPS     Security Hub  arn:aws:s3:::img.example.com   
 INFORMATIONAL  S3 buckets should have lifecycle configuration      Security Hub  arn:aws:s3:::img.example.com   
 INFORMATIONAL  S3 buckets should block public access               Security Hub  arn:aws:s3:::example-cf-logs   
 INFORMATIONAL  ACLs should not be used to manage user access       Security Hub  arn:aws:s3:::img.example.com   
 INFORMATIONAL  EC2 subnets shouldn't auto-assign public IPs        Security Hub  arn:aws:ec2:eu-west-1:<acct>   
 INFORMATIONAL  VPC block public access should be enabled           Security Hub  arn:aws:ec2:eu-west-1:<acct>   
 INFORMATIONAL  S3 bucket policies should restrict public access    Security Hub  arn:aws:s3:::img.example.com   
 INFORMATIONAL  Unused network ACLs should be removed               Security Hub  arn:aws:ec2:eu-west-1:<acct>   
 INFORMATIONAL  RSA certs should use 2048-bit+ key lengths          Security Hub  arn:aws:acm:eu-west-1:<acct>   
 INFORMATIONAL  Athena workgroups should enable logging             Security Hub  arn:aws:athena:eu-west-1:<acct>
└───────────────┴────────────────────────────────────────────────────┴──────────────┴────────────────────────────────┘

License

Refer to the LICENSE file for information on the GPL v3 license.

Future Improvements

  • [ ] Email attachment support (e.g., CSV or HTML export)
  • [ ] Slack or Teams notification integration
  • [ ] Cloud deployment (Lambda, Step Functions)