我正在创建一个ASG组,该组具有用于终止的生命周期挂钩:
LifecycleHook:
Type: AWS::AutoScaling::LifecycleHook
Properties:
AutoScalingGroupName: !Ref NodeGroup
DefaultResult: CONTINUE
HeartbeatTimeout: 60
LifecycleHookName: !Sub "${AWS::StackName}-lifecycle-hook"
LifecycleTransition: autoscaling:EC2_INSTANCE_TERMINATING
现在我也创建一个lambda函数:
LambdaCreation:
Type: "AWS::Lambda::Function"
Properties:
Handler: "lambda_function.lambda_handler"
Environment:
Variables:
aws_region : !Ref AWSRegion
Role: !GetAtt LambdaExecutionRole.Arn
Code:
S3Bucket: !Ref LambdaCodeBucket
S3Key: "lambda-functions/function.zip"
Runtime: "python3.6"
Timeout: 60
在cloudwatch事件中,我为上述事件创建了一条规则:
CloudwatchEvent:
Type: AWS::Events::Rule
Properties:
Description: ASG scale-in event to lambda
EventPattern: {
"source": [
"aws.autoscaling"
],
"detail-type": [
"EC2 Instance-terminate Lifecycle Action"
],
"detail": {
"AutoScalingGroupName":
[
{
"Fn::ImportValue" :
{
"Fn::Sub" : "${RootStackName}-nodes-asg-name"
}
}
]
}
}
State: ENABLED
Targets:
-
Arn:
!GetAtt LambdaCreation.Arn
Id:
!Ref LambdaCreation
但是lambda永远不会触发。
现在,在AWS控制台上,我没有在设计器上看到触发器。但是,如果我为创建的规则手动添加了一个cloudwatch触发器,它将开始工作...
为什么未创建lambda端的触发器?我想念什么?
谢谢!
答案 0 :(得分:1)
我面对同样的挫败感。唯一的不同是,我使用的是terraform,但这没有关系。
您缺少this:
{
"Type" : "AWS::Lambda::Permission",
"Properties" : {
"Action" : String,
"EventSourceToken" : String,
"FunctionName" : String,
"Principal" : String,
"SourceAccount" : String,
"SourceArn" : String
}
}
“手动方式”起作用的原因是,它创建了触发器和权限。当您使用Cloudformation / terraform之类的IaC工具配置内容时,您需要明确指定此Lambda权限对象。
答案 1 :(得分:0)
下面的代码段创建一个lambda函数,并创建一个cloudwatch事件以使用必要的特权触发lambda函数。
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Path: "/"
Policies:
- PolicyName: root
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:*
Resource: arn:aws:logs:*:*:*
- Effect: Allow
Action:
- s3:ListBucket
Resource: !Join [ '', [ 'arn:aws:s3:::', !Ref LambdaS3Bucket ] ]
- Effect: Allow
Action:
- s3:GetObject
Resource: !Join [ '', [ 'arn:aws:s3:::', !Ref LambdaS3Bucket, '/*' ] ]
- Effect: Allow
Action:
- sts:GetCallerIdentity
Resource: '*'
LambdaFunction:
Type: "AWS::Lambda::Function"
Properties:
Description: "Lambda function"
FunctionName: !Ref LambdaFunctionName
Handler: !Ref LambdaHandler
Runtime: !Ref LambdaRuntime
Timeout: !Ref LambdaTimeout
MemorySize: !Ref LambdaMemorysize
Role: !GetAtt LambdaExecutionRole.Arn
Code:
S3Bucket: !Ref LambdaS3Bucket
S3Key: !Ref LambdaS3BucketKey
Environment:
Variables:
time_interval_in_hours: !Ref TimeIntervalInHours
DependsOn: LambdaExecutionRole
CleanupEventRule:
Type: AWS::Events::Rule
Properties:
Description: "Cloudwatch Rule"
ScheduleExpression: !Ref CloudwatchScheduleExpression
State: !Ref CloudWatchEventState
Targets:
- Arn: !Sub ${LambdaFunction.Arn}
Id: "CleanupEventRule"
DependsOn: LambdaFunction
LambdaSchedulePermission:
Type: AWS::Lambda::Permission
Properties:
Action: 'lambda:InvokeFunction'
FunctionName: !Sub ${LambdaFunction.Arn}
Principal: 'events.amazonaws.com'
SourceArn: !Sub ${CleanupEventRule.Arn}
DependsOn: LambdaFunction