1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
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)
|