Skip to content

ccleberg/aws-summary-report

Repository files navigation

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 = "[email protected]"
to = ["[email protected]"]
subject = "Daily AWS Report"

[recipients]
emails = [
    "[email protected]"
]

[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)

About

Daily AWS metrics and alerts straight to your email.

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Languages