You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS CDK跨栈Lambda与API Gateway权限配置报错求助

解决CDK跨栈授权时的Token构造ID错误

这个问题我之前踩过坑,根源是CDK自动生成IAM权限的构造ID时,引入了动态Token(跨栈引用的值属于Token类型),而CDK要求构造ID必须是静态字符串,不能包含Token,所以才会抛出Cannot use tokens in construct ID的错误。下面给你两种可行的解决方案:

方案一:在API Gateway栈中添加调用权限(推荐)

既然API Gateway需要调用Lambda,直接在API所在的栈里授权更合理,也能避开跨栈Token的问题。通常LambdaIntegration会自动创建调用权限,但如果跨栈导入Lambda时自动授权失效,手动添加即可:

import * as cdk from 'aws-cdk-lib';
import * as api from 'aws-cdk-lib/aws-apigateway';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as iam from 'aws-cdk-lib/aws-iam';

export class CustomerApiStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // 跨栈导入Service A的Lambda
    const queryTrackFunction = lambda.Function.import(this, 'TrackQueryServiceQueryTrackFunction', {
      functionArn: cdk.Fn.importValue('TrackQueryServiceStack:QueryTrackFunctionArn')
    });

    const customerApi = new api.RestApi(this, 'CustomerAPI');
    const tracks = customerApi.root.addResource('tracks');
    
    // 创建Lambda集成
    const lambdaIntegration = new api.LambdaIntegration(queryTrackFunction);
    tracks.addMethod('GET', lambdaIntegration);

    // 手动添加API Gateway调用Lambda的权限
    queryTrackFunction.grantInvoke(new iam.ServicePrincipal('apigateway.amazonaws.com'));
  }
}

这个方案的优势是不需要修改Service A的栈,权限逻辑和API放在一起,更符合单一职责。

方案二:在Service A栈中手动指定权限的构造ID

如果你一定要在Service A栈中提前授权给API Gateway,可以手动创建IAM Permission并指定静态构造ID,避免CDK自动生成带Token的ID:

import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as iam from 'aws-cdk-lib/aws-iam';

export class TrackQueryServiceStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // 定义你的Lambda函数
    const queryTracksFunction = new lambda.Function(this, 'QueryTrackFunction', {
      runtime: lambda.Runtime.NODEJS_18_X,
      handler: 'index.handler',
      code: lambda.Code.fromAsset('path/to/your/code'),
      // 其他配置...
    });

    // 手动创建IAM权限,指定静态构造ID
    new iam.Permission(this, 'ApiGatewayInvokePermission', {
      action: 'lambda:InvokeFunction',
      principal: new iam.ServicePrincipal('apigateway.amazonaws.com'),
      function: queryTracksFunction,
      // 可选:限制仅特定API Gateway可以调用,更安全(需要从API栈导出ApiId并导入)
      // sourceArn: cdk.Arn.format({
      //   service: 'execute-api',
      //   resource: cdk.Fn.importValue('CustomerApiStack:ApiId'),
      //   resourceName: '*/*/*',
      // }, this)
    });

    // 导出Lambda ARN给其他栈使用
    new cdk.CfnOutput(this, 'QueryTrackFunctionArn', {
      value: queryTracksFunction.functionArn,
      exportName: 'TrackQueryServiceStack:QueryTrackFunctionArn'
    });
  }
}

这里关键是手动创建iam.Permission并指定了静态的构造ID(ApiGatewayInvokePermission),取代了grantInvoke自动生成的带Token的ID,从根源上解决了错误。

内容的提问来源于stack exchange,提问作者S73417H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:35:32