使用 CDK 创建依赖于不同项目拥有的其他 AWS 资源(如 Lambda)的 Step Function
Using CDK to Create a Step Function With Dependencies on Other AWS Resources (Like a Lambda) Owned By Different Projects
我们在我们的应用程序中使用 AWS Step Functions。我们使用 CDK 创建一个步骤函数,作为从存储库 A 部署应用程序 A 的一部分。该步骤函数需要包含一个 lambda 函数作为步骤之一。我们遇到的问题是这个 lambda 函数是在不同的存储库(存储库 B)中独立创建和维护的。当这两种资源的创建在两个不同的地方独立发生时,我们不确定将一个 AWS 资源 (AWS Lambda) 与另一个 AWS 资源 (AWS Step Functions) 连接的最佳方式。
我们不想在每个环境中手动创建 lambda 或 step 函数(或两者)。这很耗时,容易出错,我们会遇到很多这样的情况。
我们目前最好的想法是,我们可以也许让应用程序 A 创建步骤函数,但让它创建并引用一个空的 lambda。最初 step 函数当然不会完全发挥作用,但是当我们部署应用程序 B 时,它可以查找那个空的 lambda 函数并向其上传新代码。
并且,这样我们就不会遇到首先部署应用程序 B 导致无法运行代码的问题。我们还可以处理相反的情况:应用程序 B 可以在将代码上传到它之前创建 lambda 函数(如果它尚不存在)。应用程序 A 然后可以在创建步骤函数时查看 lambda 函数是否已经存在,并直接在步骤函数中引用 lambda 函数。
对这种方法的担忧:
- 这是额外的工作,给部署增加了很多复杂性,因此失败的可能性更大
- 我不确定我是否可以轻松地查找这样的 lambda 函数(我猜它必须是通过名称,因为我们在编写代码时不知道 ARN 是什么) .但是如果名称也发生变化,我们就会遇到问题,所以也许有一个预定义的 ID 或者我们可以用来查找它的东西。
- 代码在生产中失败的可能性。如果在部署到 QA 进行测试时,我们先部署应用程序 A,然后再部署应用程序 B,我们实际上只知道该场景有效。那么,如果在投入生产时我们以相反的顺序部署它们,它可能会崩溃。
这种东西有什么好的选择,因为我想不出什么好的。我最好的想法是根本不使用 lambda,而是让步进函数步骤在 SQS 中排队,然后应用程序 B 可以从该队列中毫无问题地读取。感觉这是一个足够常见的场景,尽管必须有一些干净的方法来使用 lambda 来完成它,我不希望我在 AWS 中使用哪种服务类型的决定受到部署可行性的阻碍。
谢谢
您可以轻松地将现有的 Lambda 函数包含在新的 CDK-created Step Function 中。使用 Function.fromFunctionArn
静态方法 get a read-only reference to the Lambda 使用其 ARN。 CDK 使用 ARN 向 Step Functions 的代入角色添加必要的 lambda:InvokeFunction
权限。
import { aws_stepfunctions_tasks as tasks } from 'aws-cdk-lib';
const importedLambdaTask = new tasks.LambdaInvoke(this, 'ImportedLambdaTask', {
lambdaFunction: lambda.Function.fromFunctionArn(
this,
'ImportedFunc',
'arn:aws:lambda:us-east-1:123456789012:function:My-Lambda5C096DFA-RLhGGzBJSnMN'
),
resultPath: '$.importedLambdaTask',
});
如果您不想在 CDK 堆栈中对 Lambda ARN 进行硬编码,请将 ARN 保存到 SSM Parameter Store Parameter。然后按名称导入到栈中,传给fromFunctionArn
:
const lambdaArnParam = ssm.StringParameter.fromStringParameterName(
this,
'ArnFromParamStore',
'lambda-arn-saved-as-ssm-param'
);
编辑:可选择将 Trigger 构造添加到您的 CDK 应用程序 A 以在部署之前确认应用程序 B Lambda 依赖项的存在。触发器是 CDK 的一项新功能,可让您 运行 Lambda 代码 在部署期间 。如果触发器函数找不到外部 Lambda,它应该 return 出错,从而导致应用程序 A 的部署失败。
我们在我们的应用程序中使用 AWS Step Functions。我们使用 CDK 创建一个步骤函数,作为从存储库 A 部署应用程序 A 的一部分。该步骤函数需要包含一个 lambda 函数作为步骤之一。我们遇到的问题是这个 lambda 函数是在不同的存储库(存储库 B)中独立创建和维护的。当这两种资源的创建在两个不同的地方独立发生时,我们不确定将一个 AWS 资源 (AWS Lambda) 与另一个 AWS 资源 (AWS Step Functions) 连接的最佳方式。
我们不想在每个环境中手动创建 lambda 或 step 函数(或两者)。这很耗时,容易出错,我们会遇到很多这样的情况。
我们目前最好的想法是,我们可以也许让应用程序 A 创建步骤函数,但让它创建并引用一个空的 lambda。最初 step 函数当然不会完全发挥作用,但是当我们部署应用程序 B 时,它可以查找那个空的 lambda 函数并向其上传新代码。
并且,这样我们就不会遇到首先部署应用程序 B 导致无法运行代码的问题。我们还可以处理相反的情况:应用程序 B 可以在将代码上传到它之前创建 lambda 函数(如果它尚不存在)。应用程序 A 然后可以在创建步骤函数时查看 lambda 函数是否已经存在,并直接在步骤函数中引用 lambda 函数。
对这种方法的担忧:
- 这是额外的工作,给部署增加了很多复杂性,因此失败的可能性更大
- 我不确定我是否可以轻松地查找这样的 lambda 函数(我猜它必须是通过名称,因为我们在编写代码时不知道 ARN 是什么) .但是如果名称也发生变化,我们就会遇到问题,所以也许有一个预定义的 ID 或者我们可以用来查找它的东西。
- 代码在生产中失败的可能性。如果在部署到 QA 进行测试时,我们先部署应用程序 A,然后再部署应用程序 B,我们实际上只知道该场景有效。那么,如果在投入生产时我们以相反的顺序部署它们,它可能会崩溃。
这种东西有什么好的选择,因为我想不出什么好的。我最好的想法是根本不使用 lambda,而是让步进函数步骤在 SQS 中排队,然后应用程序 B 可以从该队列中毫无问题地读取。感觉这是一个足够常见的场景,尽管必须有一些干净的方法来使用 lambda 来完成它,我不希望我在 AWS 中使用哪种服务类型的决定受到部署可行性的阻碍。
谢谢
您可以轻松地将现有的 Lambda 函数包含在新的 CDK-created Step Function 中。使用 Function.fromFunctionArn
静态方法 get a read-only reference to the Lambda 使用其 ARN。 CDK 使用 ARN 向 Step Functions 的代入角色添加必要的 lambda:InvokeFunction
权限。
import { aws_stepfunctions_tasks as tasks } from 'aws-cdk-lib';
const importedLambdaTask = new tasks.LambdaInvoke(this, 'ImportedLambdaTask', {
lambdaFunction: lambda.Function.fromFunctionArn(
this,
'ImportedFunc',
'arn:aws:lambda:us-east-1:123456789012:function:My-Lambda5C096DFA-RLhGGzBJSnMN'
),
resultPath: '$.importedLambdaTask',
});
如果您不想在 CDK 堆栈中对 Lambda ARN 进行硬编码,请将 ARN 保存到 SSM Parameter Store Parameter。然后按名称导入到栈中,传给fromFunctionArn
:
const lambdaArnParam = ssm.StringParameter.fromStringParameterName(
this,
'ArnFromParamStore',
'lambda-arn-saved-as-ssm-param'
);
编辑:可选择将 Trigger 构造添加到您的 CDK 应用程序 A 以在部署之前确认应用程序 B Lambda 依赖项的存在。触发器是 CDK 的一项新功能,可让您 运行 Lambda 代码 在部署期间 。如果触发器函数找不到外部 Lambda,它应该 return 出错,从而导致应用程序 A 的部署失败。