是否可以在从 CloudFormation 模板创建时触发 lambda
Is it possible to trigger a lambda on creation from CloudFormation template
我尝试使用 cloudformation 创建一组 lambda。我希望 lambda 在创建后被触发。我在各种博客上看到要创建 s3
或 sns
的触发器,但 none 似乎是创建后触发 lambda
的选项。有什么选择吗?
您可以选择通知 SNS 主题,您可以构建一个侦听该主题的 lambda,因此工作流程为:Cloudformation 启动 -> SNS 主题 -> Lambda。
是的,这是可能的。这里有几个选项:
手动 create an SNS Topic. Add an AWS::SNS::Subscription
to your stack with the lambda function as the Endpoint
and the SNS topic as the TopicArn
。在堆栈 creation/update 上,配置要发送到此 SNS 主题的堆栈事件通知。
- (请参阅 Setting AWS CloudFormation Stack Options for documentation on how to do this when using the AWS Console to create your stack, or use the equivalent option like
--notification-arns
if creating/updating your stack using the AWS CLI 或其他 AWS SDK。)
添加一个 Custom Resource 引用要在创建时调用的 Lambda 函数。
- 如果您需要在 创建某些特定资源后调用 Lambda 函数,请在引用您要确保的资源的自定义资源上添加
DependsOn
attribute在调用函数之前首先创建。
- 为了成功创建自定义资源(而不是在您的堆栈中导致 failure/rollback),您需要调整您的 Lambda 函数以支持 CloudFormation request/response 格式(请参阅 Custom Resource Reference).
- 此选项将在 stack status 仍为
CREATE_IN_PROGRESS
时调用 Lambda 函数,因为自定义资源是堆栈本身的一部分。
- 删除堆栈(和关联的自定义资源)时,也会再次调用 Lambda 函数。这需要由您的 Lambda 函数正确处理,否则您的堆栈可能会卡在
DELETE_FAILED
状态。
将 Lambda 函数引用添加到 Stack Output,然后编写一个简单的脚本来执行堆栈创建,然后手动调用 Lambda 函数。
寻找类似解决方法的人。
CloudWatch 能够捕获 CloudFormation 的 API 次调用,即 "CreateStack"、"UpdateStack" 和 "DeleteStack",堆栈状态如 "Create_complete" 或 "Complete_Rollback" 是不可捕获的,这意味着这种状态变化无法触发 lambda。
解决方法是SNS,stack可以向SNS发送通知(创建stack时提前设置),SNS可以选择触发lambda,但是不能选择特定状态。因此,lambda 函数负责找出事件的 "Message" 内容中的状态。每个人,只是编码。
以下模板应调用 lambda:
"InvokeLambda" : {
"Type": "Custom::InvokeLambda",
"Version" : "1.0",
"Properties" : {
"ServiceToken": {
"Fn::GetAtt": ["InitFunction","Arn"]
}
}
},
由 yl.
以下内容非常有用!
它调用 lambda 作为部署的一部分:
LambdaFunction2:
Type: AWS::Lambda::Function
Properties:
FunctionName: caller
Code:
ZipFile: |
import boto3, json
import cfnresponse
def handler(event, context):
print('EVENT:[{}]'.format(event))
lambda_client = boto3.client('lambda')
test_event = '{"name":"test1"}'
lambda_client.invoke(
FunctionName='target1',
InvocationType='Event',
Payload=test_event,
)
responseValue = 120
responseData = {}
responseData['Data'] = responseValue
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData)
Handler: index.handler
Role:
arn:aws:iam::11111111111:role/mylambda-role
Runtime: python3.7
Timeout: 60
Primerinvoke:
Type: AWS::CloudFormation::CustomResource
DependsOn: LambdaFunction2
Version: "1.0"
Properties:
ServiceToken: !GetAtt LambdaFunction2.Arn
我知道这有点过时了 - 但解决方案也可以是在模板中使用 CommandRunner 作为资源类型。
https://aws.amazon.com/blogs/mt/running-bash-commands-in-aws-cloudformation-templates/.
您几乎可以 运行 任何 shell 命令。将 DependsOn 属性添加到您的 CommandRunner 类型和 运行 一个 shell 脚本:
aws lambda invoke --function-name my-function --invocation-type RequestRespone --payload '{ "name": "Bob" }'
改进 Kyr 的回答,因为它缺少两个重要的东西:
- 如何将参数传递给您调用的 Lambda
- 如何处理堆栈上的更新和删除(他的解决方案会导致 CloudFormation 在删除时崩溃)
修改改进后的代码如下:
LambdaInvoker:
DependsOn: ## important, add stuff here you need to existe BEFORE the lambda is called
Type: AWS::Lambda::Function
Properties:
FunctionName: YourLambdaName
Description: 'Lambda invoke wrapper for Custom CFN actions'
Code:
ZipFile: !Sub |
import boto3, json
import cfnresponse
def handler(event, context):
print('EVENT:')
print(event)
if event['RequestType'] == "Create":
lambda_client = boto3.client('lambda')
cfn_event = {
"param1" : "${Param1}",
"param2" : "${Param2}"
}
lambda_client.invoke(
FunctionName='scm-custom-cfn-actions',
InvocationType='Event',
Payload=json.dumps(cfn_event)
)
responseValue = 120
responseData = {}
responseData['Data'] = responseValue
cfnresponse.send(event, context, cfnresponse.SUCCESS,
responseData, 'scm-cfn-customresource-id')
Handler: index.handler
Role: YourLambdaRoleARN
Runtime: python3.7
Timeout: 5
我尝试使用 cloudformation 创建一组 lambda。我希望 lambda 在创建后被触发。我在各种博客上看到要创建 s3
或 sns
的触发器,但 none 似乎是创建后触发 lambda
的选项。有什么选择吗?
您可以选择通知 SNS 主题,您可以构建一个侦听该主题的 lambda,因此工作流程为:Cloudformation 启动 -> SNS 主题 -> Lambda。
是的,这是可能的。这里有几个选项:
手动 create an SNS Topic. Add an
AWS::SNS::Subscription
to your stack with the lambda function as theEndpoint
and the SNS topic as theTopicArn
。在堆栈 creation/update 上,配置要发送到此 SNS 主题的堆栈事件通知。- (请参阅 Setting AWS CloudFormation Stack Options for documentation on how to do this when using the AWS Console to create your stack, or use the equivalent option like
--notification-arns
if creating/updating your stack using the AWS CLI 或其他 AWS SDK。)
- (请参阅 Setting AWS CloudFormation Stack Options for documentation on how to do this when using the AWS Console to create your stack, or use the equivalent option like
添加一个 Custom Resource 引用要在创建时调用的 Lambda 函数。
- 如果您需要在 创建某些特定资源后调用 Lambda 函数,请在引用您要确保的资源的自定义资源上添加
DependsOn
attribute在调用函数之前首先创建。 - 为了成功创建自定义资源(而不是在您的堆栈中导致 failure/rollback),您需要调整您的 Lambda 函数以支持 CloudFormation request/response 格式(请参阅 Custom Resource Reference).
- 此选项将在 stack status 仍为
CREATE_IN_PROGRESS
时调用 Lambda 函数,因为自定义资源是堆栈本身的一部分。 - 删除堆栈(和关联的自定义资源)时,也会再次调用 Lambda 函数。这需要由您的 Lambda 函数正确处理,否则您的堆栈可能会卡在
DELETE_FAILED
状态。
- 如果您需要在 创建某些特定资源后调用 Lambda 函数,请在引用您要确保的资源的自定义资源上添加
将 Lambda 函数引用添加到 Stack Output,然后编写一个简单的脚本来执行堆栈创建,然后手动调用 Lambda 函数。
寻找类似解决方法的人。
CloudWatch 能够捕获 CloudFormation 的 API 次调用,即 "CreateStack"、"UpdateStack" 和 "DeleteStack",堆栈状态如 "Create_complete" 或 "Complete_Rollback" 是不可捕获的,这意味着这种状态变化无法触发 lambda。
解决方法是SNS,stack可以向SNS发送通知(创建stack时提前设置),SNS可以选择触发lambda,但是不能选择特定状态。因此,lambda 函数负责找出事件的 "Message" 内容中的状态。每个人,只是编码。
以下模板应调用 lambda:
"InvokeLambda" : {
"Type": "Custom::InvokeLambda",
"Version" : "1.0",
"Properties" : {
"ServiceToken": {
"Fn::GetAtt": ["InitFunction","Arn"]
}
}
},
由 yl.
以下内容非常有用!
它调用 lambda 作为部署的一部分:
LambdaFunction2:
Type: AWS::Lambda::Function
Properties:
FunctionName: caller
Code:
ZipFile: |
import boto3, json
import cfnresponse
def handler(event, context):
print('EVENT:[{}]'.format(event))
lambda_client = boto3.client('lambda')
test_event = '{"name":"test1"}'
lambda_client.invoke(
FunctionName='target1',
InvocationType='Event',
Payload=test_event,
)
responseValue = 120
responseData = {}
responseData['Data'] = responseValue
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData)
Handler: index.handler
Role:
arn:aws:iam::11111111111:role/mylambda-role
Runtime: python3.7
Timeout: 60
Primerinvoke:
Type: AWS::CloudFormation::CustomResource
DependsOn: LambdaFunction2
Version: "1.0"
Properties:
ServiceToken: !GetAtt LambdaFunction2.Arn
我知道这有点过时了 - 但解决方案也可以是在模板中使用 CommandRunner 作为资源类型。
https://aws.amazon.com/blogs/mt/running-bash-commands-in-aws-cloudformation-templates/.
您几乎可以 运行 任何 shell 命令。将 DependsOn 属性添加到您的 CommandRunner 类型和 运行 一个 shell 脚本:
aws lambda invoke --function-name my-function --invocation-type RequestRespone --payload '{ "name": "Bob" }'
改进 Kyr 的回答,因为它缺少两个重要的东西:
- 如何将参数传递给您调用的 Lambda
- 如何处理堆栈上的更新和删除(他的解决方案会导致 CloudFormation 在删除时崩溃)
修改改进后的代码如下:
LambdaInvoker:
DependsOn: ## important, add stuff here you need to existe BEFORE the lambda is called
Type: AWS::Lambda::Function
Properties:
FunctionName: YourLambdaName
Description: 'Lambda invoke wrapper for Custom CFN actions'
Code:
ZipFile: !Sub |
import boto3, json
import cfnresponse
def handler(event, context):
print('EVENT:')
print(event)
if event['RequestType'] == "Create":
lambda_client = boto3.client('lambda')
cfn_event = {
"param1" : "${Param1}",
"param2" : "${Param2}"
}
lambda_client.invoke(
FunctionName='scm-custom-cfn-actions',
InvocationType='Event',
Payload=json.dumps(cfn_event)
)
responseValue = 120
responseData = {}
responseData['Data'] = responseValue
cfnresponse.send(event, context, cfnresponse.SUCCESS,
responseData, 'scm-cfn-customresource-id')
Handler: index.handler
Role: YourLambdaRoleARN
Runtime: python3.7
Timeout: 5