如何在CloudFormation中配置Lambda的CloudWatch日志过期策略
解决CloudFormation中配置Lambda日志组过期规则的问题
首先澄清一个点:Lambda自动创建的日志组(格式为/aws/lambda/[你的Lambda函数名])并不属于AWS保留资源(AWS保留资源是那些以AWS/开头的日志组,比如AWS/CloudTrail),只是默认由Lambda服务自动创建,没有纳入你的CloudFormation栈管理,所以你没法直接修改它的保留策略。下面是两种可行的解决方式:
方法一:显式定义Lambda日志组(推荐)
通过在CloudFormation中手动创建对应Lambda的日志组,并指定Lambda函数使用这个日志组,就能直接配置过期规则。这种方式最直接,也符合CloudFormation的基础设施即代码理念。
示例代码:
# 显式创建Lambda对应的日志组,设置保留天数 MyLambdaLogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub "/aws/lambda/${MyLambda}" RetentionInDays: 30 # 这里设置你需要的过期天数,比如30天 Tags: - Key: Name Value: MyLambdaLogs # Lambda执行角色 MyLambdaRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: "myPolicy" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: - "logs:CreateLogStream" - "logs:PutLogEvents" Resource: !GetAtt [MyLambdaLogGroup, Arn] # 如果你有其他日志操作需求,可以补充权限,这里因为已经显式创建了日志组,所以不需要CreateLogGroup权限 # Lambda函数定义,指定使用我们创建的日志组 MyLambda: Type: AWS::Lambda::Function Properties: Handler: index.handler # 替换为你的实际Handler Runtime: python3.11 # 替换为你的实际Runtime Code: S3Bucket: your-bucket-name # 替换为你的代码存储桶 S3Key: lambda-code.zip # 替换为你的代码包路径 Role: !GetAtt [MyLambdaRole, Arn] LogGroupName: !Ref MyLambdaLogGroup # 关键:指定使用我们定义的日志组
注意事项:
- 使用
!Sub拼接日志组名称,确保和Lambda函数名称完全对应,避免手动输入错误。 - 如果你的环境中已经存在Lambda自动创建的同名日志组,需要先删除它,否则CloudFormation创建时会报错(因为资源已存在)。
方法二:使用自定义资源修改现有日志组
如果你不想显式定义日志组(比如担心现有环境中已存在自动创建的日志组,不想删除),可以通过CloudFormation自定义资源,调用Lambda来设置日志组的保留策略。
步骤1:创建辅助Lambda函数(用于修改日志组策略)
# 辅助Lambda的执行角色 SetLogRetentionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: "SetLogRetentionPermissions" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: - "logs:PutRetentionPolicy" - "logs:DeleteRetentionPolicy" Resource: !Sub "/aws/lambda/${MyLambda}" - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${SetLogRetentionFunction}:*" # 辅助Lambda函数,负责修改日志组保留策略 SetLogRetentionFunction: Type: AWS::Lambda::Function Properties: Handler: index.handler Runtime: python3.11 Role: !GetAtt [SetLogRetentionRole, Arn] Code: ZipFile: | import boto3 import cfnresponse logs_client = boto3.client('logs') def handler(event, context): try: log_group_name = event['ResourceProperties']['LogGroupName'] retention_days = event['ResourceProperties']['RetentionInDays'] if event['RequestType'] in ['Create', 'Update']: # 设置保留策略 logs_client.put_retention_policy( logGroupName=log_group_name, retentionInDays=retention_days ) elif event['RequestType'] == 'Delete': # 可选:删除保留策略,恢复永久保留 logs_client.delete_retention_policy(logGroupName=log_group_name) cfnresponse.send(event, context, cfnresponse.SUCCESS, {}) except Exception as e: print(f"Error setting log retention: {str(e)}") cfnresponse.send(event, context, cfnresponse.FAILED, {'Error': str(e)})
步骤2:在主栈中添加自定义资源
# 自定义资源,触发辅助Lambda设置日志组保留策略 SetLambdaLogRetention: Type: Custom::SetLogRetention Properties: ServiceToken: !GetAtt [SetLogRetentionFunction, Arn] LogGroupName: !Sub "/aws/lambda/${MyLambda}" RetentionInDays: 30 DependsOn: MyLambda # 确保Lambda函数创建完成后再执行
这种方式会在CloudFormation创建完Lambda函数后,自动调用辅助Lambda去修改默认日志组的保留策略,不需要手动干预。
内容的提问来源于stack exchange,提问作者Efren
相关产品推荐
相关产品推荐

