首页 > 解决方案 > 无法将 lambda 与 cloudwatch 事件触发器链接

问题描述

我正在创建一个具有终止生命周期挂钩的 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 端的触发器?我错过了什么?

谢谢大家!

标签: amazon-web-servicesamazon-cloudformation

解决方案


下面的代码片段创建一个 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

推荐阅读