Integration & Automation
Reduce log-storage costs by automating retention settings in Amazon CloudWatch
By default, Amazon CloudWatch Logs stores your log data indefinitely. Persistence of logs from applications and operating systems helps you to search, filter, and store logs for future analysis. However, as your AWS workload logging grows over time, so do your log-storage costs. To reduce log-storage costs, establish a log-retention policy and apply it across all your log groups. You can do this manually, but keeping up with new log groups and propagating policy updates can become tedious.
In this post, I demonstrate how to reduce log-storage costs by automating retention settings in Amazon CloudWatch. I use an Amazon EventBridge rule to invoke an AWS Lambda function when a new CloudWatch Logs log group is created. The Lambda function performs two tasks. First, it sets the retention period of the new log group. Second, it updates nonconforming retention settings in existing log groups. I’ll also show you how to extend the Lambda function’s reach to other AWS Regions with cross-Region event routing. I provide instructions to deploy resources automatically using AWS CloudFormation templates and manually using the AWS Management Console.
About this post | |
Time to read | ~11 min. |
Time to complete | ~30 min. |
Cost to complete | ~$1 |
Learning level | Advanced (300) |
AWS services | Amazon CloudWatch Amazon EventBridge AWS Lambda AWS CloudFormation |
Architecture overview
The following figure shows the automated process that you deploy in the walkthrough.
- A CloudWatch Logs log group is created in any of the deployed Regions.
- A CloudWatch event is invoked.
- An EventBridge rule invokes a Lambda function.
- The Lambda function applies the retention setting to the new log group. It also brings existing log groups in your specified Regions into conformity with the setting.
Prerequisites
Before getting started, make sure that you have the following.
- An AWS account. If you don’t have an AWS account, sign up at https://thinkwithwp.com.
- An Amazon Simple Storage Service (Amazon S3) bucket. Deploy the bucket in the same Region where you will deploy the Lambda function. For more information, refer to Creating a bucket.
- Download
CloudWatchLogGroupRetentionSetter.py
from my GitHub repository, zip it, and then upload the zipped file to the S3 bucket. For more information, refer to Uploading objects.
Walkthrough
Method 1: Automatic deployment using CloudFormation templates
Use this method to deploy the process shown in “Archetecture overview” using CloudFormation templates. To deploy to a single Region, you need to complete only the “Deploy to one Region” section.
Deploy to one Region
- Download
CloudWatchLogGroupRetention-SingleRegion.yml
from my GitHub repository. - Sign into the AWS Management Console, and open the CloudFormation console.
- Choose Create stack, With new resources (standard).
- Under Specify template, select Upload a template file. Choose Choose file and upload
CloudWatchLogGroupRetention-SingleRegion.yml
. Choose Next. - On the Specify stack details page, enter the following parameters:<
- Stack name: Stack name can include letters (A-Z and a-z), numbers (0-9), and dashes (-).
- Lambda memory: Amount of memory that the Lambda function can use at runtime. You can enter 128–1,240MB, in 1MB increments.
- Regions: AWS Regions in which you want to watch for log-group creation and set retention periods. To deploy to multiple Regions, you must complete the steps in “Deploy to multiple Regions.“
- Retention: Retention period (in days).
- S3BucketKey: S3 key of the deployment package (for example,
CloudWatchLogGroupRetentionSetter.py.zip
). - S3BucketName: Name of the S3 bucket you created.
- Choose Next.
- Choose I acknowledge that this template may create IAM resources. Choose Create stack.
Deploy to multiple Regions
To deploy the resources to multiple Regions, complete the following steps.
Step 1. Deploy Identity and Access Management (IAM) roles
- Download
AWSCloudFormationStackSetExecutionAdministrationRoles.yml
from my GitHub repository. - Sign into the AWS Management Console and open the CloudFormation console.
- Choose Create stack, With new resources (standard).
- Under Specify template, select Upload a template file. Choose Choose file and upload
AWSCloudFormationStackSetExecutionAdministrationRoles.yml
. Choose Next. - On the Specify stack details page, enter the following parameters:
- Stack name: Stack name can include letters (A-Z and a-z), numbers (0-9), and dashes (-).
- Administrator Account ID: Your AWS account ID.
- Choose Next.
- Choose I acknowledge that this template may create IAM resources. Choose Create stack.
Step 2. Copy the event bus Amazon Resource Name (ARN)
- Download
CrossRegionEventRule.yaml
from my GitHub repository. - In the EventBridge console, choose Event buses from the left navigation pane.
- Copy the Amazon Resource Name (ARN) of the
default
event bus.
Step 3: Deploy the EventBridge rule
- On the Stack sets page of the CloudFormation console, choose Create stack set.
- Under Permissions, select Self-service permissions.
- For IAM role name, choose
AWSCloudFormationStackSetIAMAdministratorRole
. - For IAM execution role, choose
AWSCloudFormationStackSetIAMExecutionRole
.
- For IAM role name, choose
- Under Specify template, select Upload a template file. Choose Choose file and upload
CrossRegionEventRule.yaml
. Then choose Next. - On the Specify stack details page, enter the following parameters:
- Stack set name: Stack set name can include letters (A-Z and a-z), numbers (0-9), and dashes (-).
- Event bus ARN: The ARN of the event bus you copied.
- Choose Next.
- On the Set deployment options page, enter your AWS account ID in the Accounts section. Select Regions in the Specify regions section. Then choose Next.
- Choose I acknowledge that this template may create IAM resources. Choose Submit.
Method 2: Manual deployment using the AWS Management Console
If you’re unfamiliar with CloudFormation, you can deploy the resources manually using the AWS Management Console.
Step 1. Create a Lambda IAM policy
In this step, you create an IAM policy for the Lambda function, defining its permissions. This policy enables the function to complete its job of enforcing a cost-saving log-group retention policy.
- Sign into the AWS Management Console and open the IAM console.
- Choose Policies in the left navigation pane. Then choose Create Policy.
- Choose the JSON tab.
- Enter the following code.
- Choose Next twice.
- On the Review Policy page, enter a required policy name (for example,
LambdaExecutionRolePolicyCW
). - Choose Create Policy.
Step 2. Create a Lambda-function IAM role
In this step, you create an IAM role for the function with the policy you’ve created.
- On the Roles page of the IAM console, choose Create Role.
- On the Select trusted entity page, keep the default trusted entity type (AWS service). For Use Case, select Lambda. Then choose Next.
- On the Add permissions page, search for and select the policy you created. Then choose Next twice.
- Enter a required role name (for example,
LambdaExecutionRoleCW
). - Choose Create Role.
Step 3. Create a Lambda function
In this step, you create a function and assign it the IAM role.
- On the Functions page of the AWS Lambda console, choose Create function.
- On the Create function page, keep the default Author from scratch option. Enter a function name.
- Under Basic Information, complete the following.
- For Runtime, choose Python 3.9.
- For Architecture, choose x86_64.
- For Permissions, choose Change default execution role. Select Use an existing role. For Existing role, select the role you created.
- Choose Create function.
Step 4. Change the default Python runtime settings
In this step, you change the handler, or the method in your function code that processes events.
- On the Function overview page, in the Runtime settings section, choose Edit.
- For Handler, change the default
lambda_function.lambda_handler
toCloudWatchLogGroupRetentionSetter.lambda_handler
. - Choose Save.
Step 5. Set the retention policy
In this step, you set the retention policy that you want the Lambda function to enforce.
- On the Function overview page, choose the Configuration tab.
- Add two environmental variables.
- Choose Environmental variables, Edit, Add Environmental Variable.
- For Key, enter
REGIONS_TO_SCAN
. For Value, enter the Region or Regions you want to include. Separate multiple Regions with commas. - Choose Add Environmental Variable.
- For Key, enter
RETENTION_DAYS
. For Value, enter the number of days for the retention period. You can enter 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, or 3653.
- Choose Save.
Step 6. Upload Lambda function code
In this step, you use the file you saved to the S3 bucket to configure the Lambda function code.
- On the Function overview page, choose the Code tab.
- For Upload from, choose Amazon S3 location.
- On the Upload a file from Amazon S3 dialog box, enter the Amazon S3 link URL where you uploaded the script. To retrieve the URL from the S3 console, choose the bucket and then choose Copy S3 URI on the Objects page.
- Choose Save.
Step 7. Create an EventBridge rule
In this step, you create the EventBridge rule that will invoke the Lambda function when a log group is created.
- On the Rules page of the EventBridge console, choose Create Rule.
- Enter a name and optional description. Then choose Next.
- In the Event pattern section of the Build event pattern page, for AWS Service, choose CloudWatch logs. For Event type, choose AWS API Call via CloudTrail.
- Choose Specific operation(s) and enter
CreateLogGroup
. Choose Next. - On the Select target(s) page, for Select a target, choose Lambda function. For Function, select the function you created. Then choose Next twice.
- On the Review and Create page, choose Create rule.
Step 8. (Optional) Enable cross-Region event routing
EventBridge supports cross-Region event routing. Complete this section to extend the Lambda function’s reach to other Regions.
- In the EventBridge console, choose Event buses from the left navigation pane.
- Copy the Amazon Resource Name (ARN) of the default event bus.
- Choose another Region you want to include.
- Choose Rules, Create rule. Enter a name and optional description. Then choose Next.
- In the Event pattern section, complete the following steps.
- For AWS Service, choose CloudWatch logs.
- For Event type, choose AWS API Call via CloudTrail.
- Choose Specific operation(s) and enter
CreateLogGroup
in the text field. Then choose Next.
- On the Select target(s) page, complete the following steps.
- For Select a target, choose EventBridge event bus. Then select Event bus in a different account or Region.
- For Event bus as target, enter the ARN of the event bus you copied. Then choose Next.
- On the Review and Create page, choose Create rule. Repeat steps 3–7 for each Region you want to include.
Test the deployment
Follow these steps to create a log group to test the deployment by invoking the Lambda function.
- In the CloudWatch console, choose a Region from the top toolbar that you specified in the Lambda function configuration.
- Choose Logs, Log groups.
- Choose Create log group.
- Enter a log-group name. Then choose Create.
- On the Log groups page, check the Retention column for the log group you created. Verify that it has the retention setting specified in the Lambda function. Also, verify that the retention settings of any existing log groups conform to the same retention period.
Cleanup
Sign in to the AWS Management Console, and delete the resources that you created during the walkthrough, including the following:
- S3 bucket.
- CloudFormation stack set if deployed.
- Lambda function and IAM role.
- EventBridge rule.
- Event bus rule, if deployed.
- Amazon CloudWatch Logs log group.
For more information, refer to How do I terminate active resources that I no longer need on my AWS account? Check each Region in which you allocate resources. In the console, you can change the Region with the Region selector in the navigation bar.
Conclusion
Configuring an Amazon CloudWatch retention policy can help you reduce log-storage costs. In this post, I’ve described how to use Amazon EventBridge and a Lambda function to automatically manage a retention policy for new and existing log groups.
My process works across AWS Regions. You can extend it to work across other AWS accounts. For more information, refer to Sending and receiving Amazon EventBridge events between AWS accounts.
To better understand your CloudWatch usage, I recommend running a Cost and Usage Report (CUR) query for CloudWatch. This query returns monthly unblended and usage information per linked account for CloudWatch. For more information, refer to AWS CloudWatch.
For an overview of CloudWatch costs, refer to How can I determine why I was charged for CloudWatch usage, and then how can I reduce future charges?
To submit feedback for this post, use the comments section.