# 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: ``` toml [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: ``` bash aws configure --profile default ``` ## 2. Run Use Python to run the report and send the email: ``` bash python main.py ``` Or, if you're using [uv](https://github.com/astral-sh/uv) (which will auto-install dependencies and create a virtual environment): ``` bash 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: ``` bash 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: ``` python 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 │ │ ├───────────────────────────────────────┼────────────────────────┤ │ AWS::EC2::VPC │ vpc- │ ├───────────────────────────────────────┼────────────────────────┤ │ AWS::EC2::Subnet │ subnet- │ ├───────────────────────────────────────┼────────────────────────┤ │ AWS::EC2::Subnet │ subnet- │ ├───────────────────────────────────────┼────────────────────────┤ │ AWS::EC2::Subnet │ subnet- │ ├───────────────────────────────────────┼────────────────────────┤ │ AWS::EC2::VPCBlockPublicAccessOptions │ │ ├───────────────────────────────────────┼────────────────────────┤ │ AWS::EC2::SecurityGroup │ sg- │ ├───────────────────────────────────────┼────────────────────────┤ │ 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-- │ 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: │ │ INFORMATIONAL │ VPC block public access should be enabled │ Security Hub │ arn:aws:ec2:eu-west-1: │ │ 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: │ │ INFORMATIONAL │ RSA certs should use 2048-bit+ key lengths │ Security Hub │ arn:aws:acm:eu-west-1: │ │ INFORMATIONAL │ Athena workgroups should enable logging │ Security Hub │ arn:aws:athena:eu-west-1:│ └───────────────┴────────────────────────────────────────────────────┴──────────────┴────────────────────────────────┘ # 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)