使用Amplify CLI+CDK为Lambda添加SqsEventSource遇错求助
问题排查:Amplify自定义CDK栈部署时的解析错误
问题描述
此前手动添加LambdaFunctionSQSMapping并成功运行,尝试通过amplify add custom结合CDK程序化实现相同功能时,执行amplify push --debug -y出现以下错误:
🛑 There was an error building the custom resources
Resolution error: Resolution error: Resolution error: Resolution error: ID components may not include unresolved tokens: ${Token[TOKEN.1200]}.
Object creation stack:
at Execute again with CDK_DEBUG=true to capture stack traces.
Object creation stack:
at Execute again with CDK_DEBUG=true to capture stack traces..
问题原因
错误核心是CDK构造的ID必须是静态字符串,不能包含未解析的CloudFormation Token。代码中使用cdk.Fn.importValue()返回的动态Token作为fromRoleArn和fromFunctionAttributes的构造ID参数,违反了CDK的规则。此外,iam.Role.fromRoleArn的参数顺序也存在错误。
解决方案
关键修改点
- 将构造ID替换为静态字符串(不能用动态导出值)
- 修正
iam.Role.fromRoleArn的参数顺序 - 导入Lambda函数时无需手动指定角色(函数自身已关联执行角色)
修改后的完整代码
import * as AmplifyHelpers from '@aws-amplify/cli-extensibility-helper'; import * as cdk from 'aws-cdk-lib'; import * as iam from 'aws-cdk-lib/aws-iam'; import * as lambda from 'aws-cdk-lib/aws-lambda'; import { SqsEventSource } from 'aws-cdk-lib/aws-lambda-event-sources'; import * as sqs from 'aws-cdk-lib/aws-sqs'; import { Construct } from 'constructs'; import { AmplifyDependentResourcesAttributes } from '../../types/amplify-dependent-resources-ref'; export class cdkStack extends cdk.Stack { constructor( scope: Construct, id: string, props?: cdk.StackProps, amplifyResourceProps?: AmplifyHelpers.AmplifyResourceProps ) { super(scope, id, props); /* Do not remove - Amplify CLI automatically injects the current deployment environment in this input parameter */ new cdk.CfnParameter(this, 'env', { type: "String", description: "Current Amplify CLI env name" }); /* AWS CDK code goes here - learn more: https://docs.aws.amazon.com/cdk/latest/guide/home.html */ const amplifyProjectInfo = AmplifyHelpers.getProjectInfo(); const sqsQueueResourceNamePrefix = `sqs-correos-${amplifyProjectInfo.projectName}`; const queue = new sqs.Queue(this, 'sqs-queue', { queueName: `${sqsQueueResourceNamePrefix}-${cdk.Fn.ref('env')}.fifo`, fifo: true, contentBasedDeduplication: true }); new cdk.CfnOutput(this, 'QueueUrl', { value: queue.queueUrl, description: "SQS Queue URL" }); new cdk.CfnOutput(this, 'QueueArn', { value: queue.queueArn, description: "SQS Queue ARN" }); new cdk.CfnOutput(this, 'QueueName', { value: queue.queueName, description: "SQS Queue Name" }); const roleResourceNamePrefix = `CustomRole-${amplifyProjectInfo.projectName}`; const role = new iam.Role(this, 'CustomRole', { assumedBy: new iam.AccountRootPrincipal(), roleName: `${roleResourceNamePrefix}-${cdk.Fn.ref('env')}` }); role.addToPolicy( new iam.PolicyStatement({ actions: ['sqs:SendMessage', 'sqs:ReceiveMessage', 'sqs:DeleteMessage', 'sqs:GetQueueUrl'], resources: [queue.queueArn] }) ); // Access other Amplify Resources const dependencies: AmplifyDependentResourcesAttributes = AmplifyHelpers.addResourceDependency( this, amplifyResourceProps.category, amplifyResourceProps.resourceName, [{ category: 'function', resourceName: 'procesarCorreo' }] ); // 修正:用静态字符串作为构造ID,参数顺序正确 const lambdaRole = iam.Role.fromRoleArn( this, 'ProcesarCorreoLambdaRole', cdk.Fn.importValue(dependencies.function.procesarCorreo.LambdaExecutionRoleArn) ); const policy1 = new iam.PolicyStatement({ actions: [ 'sqs:ReceiveMessage', 'sqs:DeleteMessage', 'sqs:GetQueueAttributes', 'sqs:GetQueueUrl', 'sqs:ChangeMessageVisibility' ], resources: [queue.queueArn], effect: iam.Effect.ALLOW }); lambdaRole.attachInlinePolicy( new iam.Policy(this, 'receive-events', { statements: [policy1] }) ); // Attach EventSource const sqseve = new SqsEventSource(queue); // 修正:用静态字符串作为构造ID,无需指定role const lambdaProcesarCorreo = lambda.Function.fromFunctionAttributes( this, 'ProcesarCorreoLambdaFunction', { functionArn: cdk.Fn.importValue(dependencies.function.procesarCorreo.Arn) } ); lambdaProcesarCorreo.addEventSource(sqseve); } }
验证步骤
- 保存修改后的
cdk-stack.ts - 重新执行
amplify push --debug -y - 检查部署日志,确认错误消失,资源创建成功
内容的提问来源于stack exchange,提问作者GusZL
相关产品推荐
相关产品推荐

