Skip to content

Lambda Log Retention

Level: Warning

Initial version: 0.1.3

cfn-lint: WS1004

tflint: aws_cloudwatch_log_group_lambda_retention

By default, CloudWatch log groups created by Lambda functions have an unlimited retention time. For cost optimization purposes, you should set a retention duration on all log groups. For log archival, export and set cost-effective storage classes that best suit your needs.

Referencing the function name in the log group

This rule works by matching a Lambda function name in the CloudWatch log group name. For CloudFormation, it supports Fn::Join, Fn::Sub, and hard-coding the Lambda function name into the log group name.

Here are some examples of valid implementations:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
Resources:
  Function:
    Type: AWS::Serverless::Function
    Properties:
      # Omitting other properties

  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName:
        Fn::Join:
        - ""
        - - "/aws/lambda/"
          - !Ref Function
      RetentionInDays: 7
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Resources:
  Function:
    Type: AWS::Serverless::Function
    Properties:
      # Omitting other properties

  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/lambda/${Function}"
      RetentionInDays: 7
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
Resources:
  Function:
    Type: AWS::Serverless::Function
    Properties:
      # Omitting other properties
      FunctionName: my_function_name

  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: "/aws/lambda/my_function_name
      RetentionInDays: 7
Disabled for Terraform

This rule is disabled for Terraform, as the current linter only support static values in expressions. See this issue for more information.

Why is this a warning?

Since serverless-rules evaluate infrastructure-as-code template, it cannot check if you use a solution that will automatically change the configuration of log groups after the fact.

Implementations

 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
import { Code, Function, Runtime } from '@aws-cdk/aws-lambda';
import { LogGroup, RetentionDays } from '@aws-cdk/aws-logs';

export class MyStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const myFunction = new Function(
      scope, 'MyFunction',
      {
        code: Code.fromAsset('src/hello/'),
        handler: 'main.handler',
        runtime: Runtime.PYTHON_3_8,
      }
    );

    // Explicit log group that refers to the Lambda function
    const myLogGroup = new LogGroup(
      scope, 'MyLogGroup',
      {
        logGroupName: `/aws/lambda/${myFunction.functionName}`,
        retention: RetentionDays.ONE_WEEK,
      }
    );
  }
}
 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
{
  "Resources": {
    // Lambda function
    "Function": {
      "Type": "AWS::Serverless::Function",
      "Properties": {
        "CodeUri": ".",
        "Runtime": "python3.8",
        "Handler": "main.handler",
        "Tracing": "Active"
      }
    },

    // Explicit log group that refers to the Lambda function
    "LogGroup": {
      "Type": "AWS::Logs::LogGroup",
      "Properties": {
        "LogGroupName": {
          "Fn::Sub": "/aws/lambda/${Function}"
        },
        // Explicit retention time
        "RetentionInDays": 7
      }
    }
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
Resources:
  Function:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: .
      Runtime: python3.8
      Handler: main.handler
      Tracing: Active

  # Explicit log group that refers to the Lambda function
  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/lambda/${Function}"
      # Explicit retention time
      RetentionInDays: 7
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
provider:
  name: aws
  runtime: python3.8
  lambdaHashingVersion: '20201221'
  # This will automatically create the log group with retention
  logRetentionInDays: 14

functions:
  hello:
    handler: handler.hello
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
resource "aws_lambda_function" "this" {
  function_name = "my-function"
  handler       = "main.handler"
  runtime       = "python3.8"
  filename      = "function.zip"
  role          = "arn:aws:iam::111122223333:role/my-function-role"
}

# Explicit log group
resource "aws_cloudwatch_log_group" "this" {
  name              = "/aws/lambda/${aws_lambda_function.this.function_name}
  # Explicit retention time
  retention_in_days = 7
}

See also