如何在AWS Lambda中获取CDK创建的Step Functions状态机ARN?
解决AWS CDK中Lambda获取动态生成的Step Functions状态机ARN的问题
你遇到的${Token[TOKEN.xxx]}是CDK在合成阶段的占位符,此时真实ARN还未生成,手动写入.env文件的方法行不通,推荐以下两种靠谱的解决方案:
1. 通过Lambda环境变量直接传递(最常用)
CDK支持直接将状态机ARN作为环境变量注入Lambda,部署阶段会自动替换为真实的ARN值,无需手动处理。
CDK栈代码示例:
import * as cdk from 'aws-cdk-lib'; import * as sfn from 'aws-cdk-lib/aws-stepfunctions'; import * as lambda from 'aws-cdk-lib/aws-lambda-nodejs'; export class MyStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); // 创建Step Functions状态机 const myStateMachine = new sfn.StateMachine(this, 'MyStateMachine', { // 替换为你的状态机定义 definition: sfn.Chain.start(new sfn.Pass(this, 'StartPass')) }); // 创建Lambda函数,注入状态机ARN到环境变量 const myLambda = new lambda.NodejsFunction(this, 'MyLambda', { entry: './lambda/index.ts', environment: { // 直接引用状态机的ARN属性 STATE_MACHINE_ARN: myStateMachine.stateMachineArn } }); // 给Lambda添加调用StartExecution的权限 myStateMachine.grantStartExecution(myLambda); } }
Lambda代码示例(index.ts):
import { SFNClient, StartExecutionCommand } from "@aws-sdk/client-sfn"; const sfnClient = new SFNClient({}); export const handler = async () => { // 从环境变量读取真实ARN const stateMachineArn = process.env.STATE_MACHINE_ARN; if (!stateMachineArn) { throw new Error('STATE_MACHINE_ARN环境变量未设置'); } const command = new StartExecutionCommand({ stateMachineArn, // 按需添加输入等其他参数 input: JSON.stringify({ key: 'value' }) }); await sfnClient.send(command); return { statusCode: 200, body: '状态机执行已启动' }; };
2. 存入SSM参数存储(跨栈/多场景共享时用)
如果需要在多个Lambda或跨栈场景中共享状态机ARN,可以将ARN存入AWS Systems Manager参数存储,再让Lambda读取该参数。
CDK栈代码示例:
import * as ssm from 'aws-cdk-lib/aws-ssm'; import * as iam from 'aws-cdk-lib/aws-iam'; // ... 前面的状态机创建代码不变 // 将状态机ARN存入SSM参数 new ssm.StringParameter(this, 'StateMachineArnParam', { parameterName: '/my-app/step-functions/state-machine-arn', stringValue: myStateMachine.stateMachineArn }); // 给Lambda添加读取SSM参数的权限 myLambda.addToRolePolicy(new iam.PolicyStatement({ actions: ['ssm:GetParameter'], resources: [ssm.StringParameter.fromStringParameterName(this, 'ParamArn', '/my-app/step-functions/state-machine-arn').parameterArn] }));
Lambda代码示例:
import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm"; import { SFNClient, StartExecutionCommand } from "@aws-sdk/client-sfn"; const ssmClient = new SSMClient({}); const sfnClient = new SFNClient({}); export const handler = async () => { // 从SSM读取ARN const paramCommand = new GetParameterCommand({ Name: '/my-app/step-functions/state-machine-arn' }); const paramResult = await ssmClient.send(paramCommand); const stateMachineArn = paramResult.Parameter?.Value; if (!stateMachineArn) { throw new Error('未从SSM获取到状态机ARN'); } // 启动状态机执行 const executionCommand = new StartExecutionCommand({ stateMachineArn, input: JSON.stringify({ key: 'value' }) }); await sfnClient.send(executionCommand); return { statusCode: 200, body: '状态机执行已启动' }; };
注意:不要用本地文件写入的方式传递ARN,CDK在合成阶段无法获取真实资源标识符,只会生成占位Token,只有部署阶段才会替换为真实值。
内容的提问来源于stack exchange,提问作者hello planet
相关产品推荐
相关产品推荐

