Why is this an issue?

Some AWS services create Log Groups implicitly and don’t let the developer choose the Log Group name. This means that CloudFormation does not require the developer to declare the Log Group that the resource will write to.

If a Log Group is not declared within CloudFormation, then this Log Group will be automatically created at run time and it won’t be managed by CloudFormation. The consequences are that the:

These automatically created Log Groups will remain forever which can have huge impact on costs and security (the data stay forever while this is unexpected from company or regulatory rules).

A good practice is to declare the target Log Group with CloudFormation, matching the name that the AWS will use so that the Log Group resource is managed as code.

This rule applies to the following resources:

Noncompliant code example

  # There is no "Log Group" declared corresponding to "MyLambdaFunction": logs will not be managed by CloudFormation
  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: nodejs12.x
      Description: Example of Lambda Function

Compliant solution

Example with Ref

  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: nodejs12.x
      Description: Example of Lambda Function

  MyFunctionLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Join ['/', ['/aws/lambda', !Ref MyLambdaFunction]]
      RetentionInDays: 30

Example with Sub

  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: nodejs12.x
      Description: Example of Lambda Function

  MyFunctionLogGroupSub:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub '/aws/lambda/${MyLambdaFunction}’
      RetentionInDays: 30