无法将Lambda与CloudWatch事件触发器链接

时间:2019-05-23 20:53:42

标签: amazon-web-services amazon-cloudformation

我正在创建一个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端的触发器?我想念什么?

谢谢!

2 个答案:

答案 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