krz/aws-summary-report

Automated AWS summary reports, straight to your inbox.

clone: git clone https://gitbay.org/krz/aws-summary-report.git

f398469aab82fd36868b13afe8c92d9ad076e225

verified · cmc

author: Christian Cleberg <hello@cleberg.net> · 2025-08-02T17:50:34Z

fix: convert README.org to README.md
 README.md             | 249 ++++++++++++++++++++++++++++++++++++++++++++++++++
 aws-summary/README.md | 238 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 487 insertions(+)

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..194de50
--- /dev/null
+++ b/README.md
@@ -0,0 +1,249 @@
+# 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`).
+
+<figure>
+<img src="./screenshots/uv.png" />
+<figcaption>UV Run</figcaption>
+</figure>
+
+# 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                        │ <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)
diff --git a/aws-summary/README.md b/aws-summary/README.md
new file mode 100644
index 0000000..e1d486d
--- /dev/null
+++ b/aws-summary/README.md
@@ -0,0 +1,238 @@
+# 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"
+]
+```
+
+## 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 main.py
+```
+
+Emails are plaintext with ASCII-formatted tables (via `tabulate`).
+
+# 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 and control their order in
+`main.py`.
+
+# Example Output
+
+Here is an example of the output produced by the program.
+
+    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.
+
+# Future Improvements
+
+- [ ] Email attachment support (e.g., CSV or HTML export)
+- [ ] Slack or Teams notification integration
+- [ ] Cloud deployment (Lambda, Step Functions)