This CloudFormation solution converts the original Terraform-based Athena query automation into AWS CloudFormation templates. The solution automatically runs scheduled Athena queries against your billing data and sends the results via email.
The solution consists of:
- Lambda Function: Executes Athena queries and processes results
- CloudWatch Events Rule: Triggers the Lambda on a schedule
- S3 Bucket: Stores Athena query results
- IAM Roles & Policies: Provides necessary permissions
- CloudWatch Alarms: Monitors Lambda function health
- SES Integration: Sends email notifications with CSV attachments
cloudformation_templates/
├── athena-query-solution-simple.yaml # Simplified all-in-one template
├── parameters.json # Parameter values
├── deploy.sh # Deployment script
├── sql_queries/
│ └── account_monthly_bill.sql # Sample SQL query
└── README.md # This file
- AWS CLI installed and configured
- SES Email Verification: Both sender and receiver emails must be verified in SES
- Athena Database: Your billing database should already exist
- S3 Permissions: Ensure your account has access to create S3 buckets
Edit parameters.json
with your specific values:
[
{
"ParameterKey": "SenderEmail",
"ParameterValue": "[email protected]"
},
{
"ParameterKey": "ReceiverEmail",
"ParameterValue": "[email protected]"
},
{
"ParameterKey": "AthenaDatabase",
"ParameterValue": "your_athena_database"
},
{
"ParameterKey": "AthenaTable",
"ParameterValue": "your_billing_table"
}
]
# Basic deployment
./deploy.sh my-athena-stack us-east-1 prod
# Or manually with AWS CLI
aws cloudformation create-stack \
--stack-name athena-query-solution \
--template-body file://athena-query-solution-simple.yaml \
--parameters file://parameters.json \
--capabilities CAPABILITY_NAMED_IAM \
--region us-east-1
Ensure both sender and receiver email addresses are verified in SES:
# Verify email addresses in SES
aws ses verify-email-identity --email-address [email protected]
aws ses verify-email-identity --email-address [email protected]
Parameter | Description | Default |
---|---|---|
Environment |
Environment suffix for resources | "" |
SenderEmail |
Email address for sending notifications | [email protected] |
ReceiverEmail |
Email address for receiving notifications | [email protected] |
BucketName |
Base name for S3 bucket | buisnesspennybucket |
AthenaDatabase |
Athena database name | athenacurcfn_mybillingreport |
AthenaTable |
Athena table name | mybillingreport |
ScheduleExpression |
CloudWatch Events cron expression | cron(07 1 * ? * *) |
QueryName |
Name for the query execution | account_monthly_bill |
QueryType |
Type of query (finops_bill or finops_report ) |
finops_bill |
The solution uses CloudWatch Events cron expressions:
cron(07 1 * ? * *)
- Daily at 1:07 AMcron(0 10 1 * ? *)
- Monthly on the 1st at 10:00 AMcron(0 9 ? * MON *)
- Weekly on Mondays at 9:00 AM
- Update the CloudWatch Events target input with your new SQL query
- Modify the
QueryName
parameter - Redeploy the stack
- Edit the inline code in the CloudFormation template
- Update the stack to deploy changes
The Lambda function sends results as CSV attachments with filename format {query_name}_{date}.csv
. If no results are found, it sends an email explaining that no results were returned.
The solution includes CloudWatch alarms for:
- Lambda Errors: Triggers when the function fails
- Lambda Duration: Triggers when execution time is high
View logs in CloudWatch Logs under /aws/lambda/athena_query{Environment}
-
SES Email Not Verified
Solution: Verify both sender and receiver emails in SES console
-
Athena Query Fails
Check: Database and table names in parameters Check: IAM permissions for Athena and Glue
-
S3 Access Denied
Check: S3 bucket policy and IAM role permissions Check: Bucket name uniqueness (account ID is appended)
-
Lambda Timeout
Solution: Increase timeout value in template (current: 300 seconds)
- Check CloudWatch Logs for the Lambda function
- Verify Athena query execution in Athena console
- Check S3 bucket for query results
- Verify SES sending statistics
- IAM Permissions: The solution uses least-privilege access
- S3 Encryption: Results are encrypted with SSE-S3
- VPC: Consider deploying Lambda in VPC for additional security
- Secrets: Use AWS Secrets Manager for sensitive configuration
- Lambda Memory: Adjust based on actual usage (current: 512MB)
- S3 Lifecycle: Configure lifecycle policies for old query results
- Athena Optimization: Use partitioning and compression for cost savings
- CloudWatch Logs: Set retention periods appropriately
Key differences from the original Terraform solution:
- Simplified Code: Inline Lambda function with minimal dependencies
- Email Format: Plain text results instead of CSV attachments
- No External Dependencies: All code is embedded in the CloudFormation template
- Reduced Complexity: Single template file with streamlined functionality
For issues or questions:
- Check CloudWatch Logs first
- Verify all prerequisites are met
- Review AWS service limits
- Check IAM permissions
See CONTRIBUTING for more information.
This library is licensed under the MIT-0 License. See the LICENSE file.