diff options
author | Christian Cleberg <hello@cleberg.net> | 2025-08-02 12:50:34 -0500 |
---|---|---|
committer | Christian Cleberg <hello@cleberg.net> | 2025-08-02 12:50:34 -0500 |
commit | f398469aab82fd36868b13afe8c92d9ad076e225 (patch) | |
tree | d893718e17bad17f0cd5bfced351a8d7f9f58200 | |
parent | 0ac3e4788af9287b6df287f8cff6beda36b555aa (diff) | |
download | aws-summary-report-f398469aab82fd36868b13afe8c92d9ad076e225.tar.gz aws-summary-report-f398469aab82fd36868b13afe8c92d9ad076e225.tar.bz2 aws-summary-report-f398469aab82fd36868b13afe8c92d9ad076e225.zip |
fix: convert README.org to README.md
-rw-r--r-- | README.md | 249 | ||||
-rw-r--r-- | aws-summary/README.md | 238 |
2 files changed, 487 insertions, 0 deletions
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) |