我有一个lambda,它具有一个日志组,例如LG-1,其保留时间设置为“永不过期”(默认)。我需要将此“永不过期”更改为1个月。我正在使用CloudFormation进行此操作。由于日志组已经存在,当我尝试使用模板中的更改再次部署lambda时:
LambdaFunctionLogGroup:
Type: 'AWS::Logs::LogGroup'
DependsOn: MyLambda
Properties:
RetentionInDays: 30
LogGroupName: !Join
- ''
- - /aws/lambda/
- !Ref MyLambda
更新失败,并显示错误:
[LogGroup名称]已经存在。
一种可行的解决方案是删除日志组,然后再次进行新的更改以创建日志组,如上图所示。
但是我需要在不删除日志组的情况下执行此操作,因为这将导致删除我以前拥有的所有日志。
有没有可行的解决方法?
答案 0 :(得分:3)
我认为不可能从CF中操纵已经存在于堆栈之外的资源。
一种解决方法是更改my-lambda-v2
之类的Lambda的名称,以将旧日志组与新日志组保持在一起。
一个月后,您可以删除旧的。
答案 1 :(得分:1)
在cloudformation模板中使用customresource支持的lambda。自定义资源将在第一次时自动触发,并更新现有日志组的保留策略。如果需要,可以每次触发一次定制资源lambda,然后使用jinja2之类的模板引擎。
import boto3
client = boto3.client('logs')
response = client.put_retention_policy(
logGroupName='string',
retentionInDays=123
)
您基本上可以使用“自定义资源”使CF模板(几乎)做您想做的一切
更多信息(Boto3,您可以找到所使用语言的相应SDK)-https://boto3.amazonaws.com/v1/documentation/api/1.9.42/reference/services/logs.html#CloudWatchLogs.Client.put_retention_policy
编辑:在CloudFormation模板中,它看起来类似于以下内容:
LogRetentionSetFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src
Handler: set_retention_period.handler
Role: !GetAtt LambdaRole.Arn
DeploymentPreference:
Type: AllAtOnce
PermissionForLogRetentionSetup:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:invokeFunction
FunctionName:
Fn::GetAtt: [ LogRetentionSetFunction, Arn ]
Principal: lambda.amazonaws.com
InvokeLambdaFunctionToSetLogRetention:
DependsOn: [PermissionForLogRetentionSetup]
Type: Custom::SetLogRetention
Properties:
ServiceToken: !GetAtt LogRetentionSetFunction.Arn
StackName: !Ref AWS::StackName
AnyVariable: "Choose whatever you want to send"
Tags:
'owner': !Ref owner
'task': !Ref task
lambda函数将具有根据我之前指定的代码设置日志保留的代码。
有关更多信息,请谷歌“自定义资源支持的lambda”。另外,为了让您早日入门,我在下面添加了墨水: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources.html
答案 2 :(得分:0)
@ttulka回答:
“ ..无法从CF中操纵已经存在于堆栈之外的资源。”
但是实际上问题比这更普遍,并且适用于在堆栈内部 创建的资源。它与AWS CloudFormation资源"Replacement policy"有关。对于某些资源,CloudFormation“更新”资源的方式是创建新资源,然后删除旧资源(这称为"Replacement"更新策略)。这意味着在一段时间内,您将拥有两个相同类型的资源,并且同时存在许多相同的属性。但是,如果某个资源属性必须是唯一的,则如果两个资源对此属性具有相同的值,则这两个资源不能同时存在,因此... CloudFormation会崩溃。
AWS::Logs::LogGroup.LogGroupName属性就是这样的属性之一。 AWS::CloudWatch::Alarm.AlarmName是另一个示例。
一种解决方法是取消设置名称,以便使用随机名称,执行更新,然后将名称重新设置为可预测的固定值,然后再次更新。
Rant:这是一个烦人的问题,确实不应该存在。即AWS CF应该足够聪明,不必使用这种奇怪的笨拙资源替换实现。但是...这就是适合您的AWS CF ...