设置Lambda以使用CloudFormation从CloudWatch触发

时间:2017-08-05 00:58:05

标签: amazon-web-services aws-lambda amazon-cloudformation

我想在调用CloudWatch函数时使用CloudFormation触发Lambda。我有以下,但它不起作用。

CloudWatch规则创建正常

"CloudWatchNewEc2": {
  "Type": "AWS::Events::Rule",
  "DependsOn": ["LambdaNewEc2"],
  "Properties": {
    "Description": "Triggered on new EC2 instances",
    "EventPattern": {
      "source": [
        "aws.ec2"
      ],
      "detail-type": [
        "AWS API Call via CloudTrail"
      ],
      "detail": {
        "eventSource": [
          "ec2.amazonaws.com"
        ],
        "eventName": [
          "RunInstances"
        ]
      }
    },
    "Targets": [
      {
        "Arn": {
          "Fn::GetAtt": ["LambdaNewEc2", "Arn"]
        },
        "Id": "NewEc2AutoTag"
      }
    ]
  }
},

已创建Lambda但未触发

"LambdaNewEc2": {
  "Type": "AWS::Lambda::Function",
  "DependsOn": ["S3Lambda", "IAMRoleLambda"],
  "Properties": {
    "Code": {
      "S3Bucket": {"Ref": "LambdaBucketName"},
      "S3Key": "skynet-lambda.zip"
    },
    "Description": "When new EC2 instances are created, auto tag them",
    "FunctionName": "newEc2AutoTag",
    "Handler": "index.newEc2_autoTag",
    "Role": {"Fn::GetAtt": ["IAMRoleLambda", "Arn"]},
    "Runtime": "nodejs6.10",
    "Timeout": "30"
  }
}

},

看起来CloudWatch Target还不够?

更新(完整CloudFormation模板)

{
  "Parameters": {
    "Environment": {
      "Type": "String",
      "Default": "Staging",
      "AllowedValues": [
        "Testing",
        "Staging",
        "Production"
      ],
      "Description": "Environment name"
    },
    "BucketName": {
      "Type": "String",
      "Default": "skynet-staging",
      "Description": "Bucket Name"
    },
    "LambdaBucketName": {
      "Type": "String",
      "Default": "skynet-lambda",
      "Description": "Lambda Bucket Name"
    },
    "Owner": {
      "Type": "String",
      "Description": "Owner"
    }
  },
  "Resources": {
    "S3Web": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "BucketName": {
          "Ref": "BucketName"
        },
        "WebsiteConfiguration": {
          "IndexDocument": "index.html",
          "RoutingRules": [
            {
              "RedirectRule": {
                "ReplaceKeyPrefixWith": "#"
              },
              "RoutingRuleCondition": {
                "HttpErrorCodeReturnedEquals": "404"
              }
            }
          ]
        },
        "AccessControl": "PublicRead",
        "Tags": [
          {
            "Key": "Cost Center",
            "Value": "Skynet"
          },
          {
            "Key": "Environment",
            "Value": {
              "Ref": "Environment"
            }
          },
          {
            "Key": "Owner",
            "Value": {
              "Ref": "Owner"
            }
          }
        ]
      }
    },
    "S3Lambda": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "BucketName": {
          "Ref": "LambdaBucketName"
        },
        "VersioningConfiguration": {
          "Status": "Enabled"
        },
        "Tags": [
          {
            "Key": "Cost Center",
            "Value": "Skynet"
          },
          {
            "Key": "Owner",
            "Value": {
              "Ref": "Owner"
            }
          }
        ]
      }
    },
    "CloudWatchNewEc2": {
      "Type": "AWS::Events::Rule",
      "DependsOn": ["LambdaNewEc2"],
      "Properties": {
        "Description": "Triggered on new EC2 instances",
        "EventPattern": {
          "source": [
            "aws.ec2"
          ],
          "detail-type": [
            "AWS API Call via CloudTrail"
          ],
          "detail": {
            "eventSource": [
              "ec2.amazonaws.com"
            ],
            "eventName": [
              "RunInstances"
            ]
          }
        },
        "Targets": [
          {
            "Arn": {
              "Fn::GetAtt": ["LambdaNewEc2", "Arn"]
            },
            "Id": "NewEc2AutoTag"
          }
        ]
      }
    },
    "IAMRoleLambda": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "RoleName": "skynet-lambda-role",
        "AssumeRolePolicyDocument": {
          "Version" : "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                  "Service": [ "lambda.amazonaws.com" ]
              },
              "Action": [ "sts:AssumeRole" ]
            }
          ]
        },
        "ManagedPolicyArns": [
          "arn:aws:iam::aws:policy/AmazonEC2FullAccess",
          "arn:aws:iam::aws:policy/AWSLambdaFullAccess",
          "arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess",
          "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
        ]
      }
    },
    "LambdaNewEc2": {
      "Type": "AWS::Lambda::Function",
      "DependsOn": ["S3Lambda", "IAMRoleLambda"],
      "Properties": {
        "Code": {
          "S3Bucket": {"Ref": "LambdaBucketName"},
          "S3Key": "skynet-lambda.zip"
        },
        "Description": "When new EC2 instances are created, auto tag them",
        "FunctionName": "newEc2AutoTag",
        "Handler": "index.newEc2_autoTag",
        "Role": {"Fn::GetAtt": ["IAMRoleLambda", "Arn"]},
        "Runtime": "nodejs6.10",
        "Timeout": "30"
      }
    }
  },
  "Outputs": {
    "WebUrl": {
      "Value": {
        "Fn::GetAtt": [
          "S3Web",
          "WebsiteURL"
        ]
      },
      "Description": "S3 bucket for web files"
    }
  }
}

1 个答案:

答案 0 :(得分:1)

我设法将您的模板部署到CloudFormation堆栈中(通过删除LambdaBucket并指向我自己的zip文件)。它似乎正确地创建了所有资源。

const PAGES = [ { path:'/', label:'Asset Manager', Body:AssetManager }, { path:'/tags', label:'Tag Manager', Body:TagManager }, { path:'/tag-groups', label:'Tag Group Manager', Body:TagGroupManager }, ] class App extends Component { render() { return ( <Provider store={store}> <BrowserRouter> <div className="App"> <Header /> <p className="App-intro"> Gotta <code>catch'em</code> all!! </p> <Switch> { PAGES.map( ({ Body, path }) => <Route path={path} key={path} exact component={Body} /> ) } <Route component={Body404} /> </Switch> </div> </BrowserRouter> </Provider> ) } } 事件大约需要10分钟才会显示在CloudTrail中。然后它成功触发了规则,但我的规则的CloudWatch指标显示调用失败,因为我伪造了模板的Lambda函数。

一旦我编辑规则以指向更好的功能并重新测试,它就可以正常工作。

底线:似乎有效!