我已使用 Amazon CDK 部署了 Lambda 函数。我想在每次部署时自动调用此 Lambda 函数。是否可以使用 Amazon CDK 构造来实现此目的?
执行此操作的规范方法是使用 CDK 触发器,但正如 @ipbearden 在评论中正确指出的那样,尚未添加在每个部署上运行触发器的功能。您可以使用 hack 在每次部署时始终重新创建触发器:
import * as triggers from 'aws-cdk-lib/triggers';
const func: lambda.Function;
new triggers.Trigger(this, 'MyTrigger-' + Date.now().toString(), {
handler: func,
});
您甚至可以让它在部署特定构造之后(或之前)执行。
您应该能够使用类似于下面的 CustomResource 来执行此操作:
const lambdaTrigger = new cr.AwsCustomResource(this, 'MyFunctionTrigger', {
policy: cr.AwsCustomResourcePolicy.fromStatements([
new iam.PolicyStatement({
actions: ['lambda:InvokeFunction'],
effect: iam.Effect.ALLOW,
resources: [myFunction.functionArn],
}),
]),
timeout: Duration.minutes(2),
onCreate: {
service: 'Lambda',
action: 'invoke',
parameters: {
FunctionName: myFunction.functionName,
InvocationType: 'Event',
},
physicalResourceId: cr.PhysicalResourceId.of(Date.now().toString()),
},
onUpdate: {
service: 'Lambda',
action: 'invoke',
parameters: {
FunctionName: myFunction.functionName,
InvocationType: 'Event'
},
physicalResourceId: cr.PhysicalResourceId.of(Date.now().toString())
}
});
通过将
physicalResourceId
设置为部署时的当前时间,它应该会触发它执行每个部署。
我尝试过
triggers.Trigger
解决方案和 customResources.AwsCustomResource
解决方案,但最终发现它们的缺点并不适合我。
前者的缺点是它不接受现有的
lambda.Function
,后者的缺点是它试图将临时函数调用形状的钉子装入生命周期控制资源形状的孔中,这意味着我们必须根据传入事件的某些假设来编写我们的函数,更重要的是,每次都会得到一个非空的 cdk
diff。
但是后来我想出了这个解决方案,它使用
EventBridge
规则在 myFunction
堆栈部署完成后触发 CloudFormation
,我对此非常满意:
import * as cdk from "aws-cdk-lib/core";
import * as events from "aws-cdk-lib/aws-events";
import * as eventsTargets from "aws-cdk-lib/aws-events-targets";
new events.Rule(this, "DeploymentHook", {
eventPattern: {
detailType: ["CloudFormation Stack Status Change"],
source: ["aws.cloudformation"],
detail: {
"stack-id": [cdk.Stack.of(this).stackId],
"status-details": {
status: ["CREATE_COMPLETE", "UPDATE_COMPLETE"],
},
},
},
targets: [new eventsTargets.LambdaFunction(myFunction)],
});