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

使用AWS Amplify与CDK创建自定义资源时部署失败求助

问题

尝试使用AWS Amplify结合AWS CDK创建自定义资源,并将现有Lambda函数作为事件处理程序。执行amplify push时资源创建失败,错误信息如下:

CREATE_FAILED custommyCustomResourceXXXX AWS::CloudFormation::Stack Parameters: [AssetParametersXXXX, .....] must have values

相关CDK代码:

import * as cdk from '@aws-cdk/core';
import * as AmplifyHelpers from '@aws-amplify/cli-extensibility-helper';
import * as cr from "@aws-cdk/custom-resources";
import * as logs from "@aws-cdk/aws-logs";
import * as lambda from '@aws-cdk/aws-lambda';

import { AmplifyDependentResourcesAttributes } from "../../types/amplify-dependent-resources-ref"

export class cdkStack extends cdk.Stack {
  constructor(scope: cdk.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',
    });

    const dependencies: AmplifyDependentResourcesAttributes = AmplifyHelpers.addResourceDependency(this,
      amplifyResourceProps.category,
      amplifyResourceProps.resourceName,
      [{
        category: "function",
        resourceName: "myFunction" 
      }] 
    );


    const myFunctionArn = cdk.Fn.ref(dependencies.function.myFunction.Arn);
    const importedLambda = lambda.Function.fromFunctionArn(this, "importedLambda", myFunctionArn);
    
    const provider = new cr.Provider(this, "MyCustomResourceProvider", {
      onEventHandler: importedLambda,
      logRetention: logs.RetentionDays.ONE_DAY,
    })

    new cdk.CustomResource(this, "MyCustomResource", {
      serviceToken: provider.serviceToken
    })
  }
}
问题原因与排查修复

核心原因

cr.Provider默认会生成辅助资源(如日志处理的Lambda层、辅助函数),这些资源依赖Asset参数注入部署值,但在Amplify集成场景下,直接使用外部导入的Lambda作为onEventHandler时,CDK无法正确传递这些参数,导致CloudFormation报错。cr.Provider设计上更适配当前栈内定义的Lambda资源,而非外部导入的资源。

修复方案

方案1:直接使用现有Lambda作为自定义资源的服务令牌

如果现有Lambda已实现自定义资源的处理逻辑(能接收并响应CloudFormation事件格式),可跳过cr.Provider,直接将Lambda ARN作为自定义资源的serviceToken:

import * as cdk from '@aws-cdk/core';
import * as AmplifyHelpers from '@aws-amplify/cli-extensibility-helper';
import * as cr from "@aws-cdk/custom-resources";

import { AmplifyDependentResourcesAttributes } from "../../types/amplify-dependent-resources-ref"

export class cdkStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps, amplifyResourceProps?: AmplifyHelpers.AmplifyResourceProps) {
    super(scope, id, props);
    new cdk.CfnParameter(this, 'env', {
      type: 'String',
      description: 'Current Amplify CLI env name',
    });

    const dependencies: AmplifyDependentResourcesAttributes = AmplifyHelpers.addResourceDependency(this,
      amplifyResourceProps.category,
      amplifyResourceProps.resourceName,
      [{
        category: "function",
        resourceName: "myFunction" 
      }] 
    );

    const myFunctionArn = cdk.Fn.ref(dependencies.function.myFunction.Arn);

    new cdk.CustomResource(this, "MyCustomResource", {
      serviceToken: myFunctionArn,
      // 按需传递自定义资源所需参数
      properties: {
        Env: cdk.Fn.ref('env')
      }
    })
  }
}

方案2:在当前栈内定义Lambda(保留cr.Provider能力)

若需要cr.Provider提供的重试、日志管理等能力,可将现有Lambda的代码迁移到当前CDK栈内定义:

import * as cdk from '@aws-cdk/core';
import * as AmplifyHelpers from '@aws-amplify/cli-extensibility-helper';
import * as cr from "@aws-cdk/custom-resources";
import * as logs from "@aws-cdk/aws-logs";
import * as lambda from '@aws-cdk/aws-lambda';

import { AmplifyDependentResourcesAttributes } from "../../types/amplify-dependent-resources-ref"

export class cdkStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps, amplifyResourceProps?: AmplifyHelpers.AmplifyResourceProps) {
    super(scope, id, props);
    new cdk.CfnParameter(this, 'env', {
      type: 'String',
      description: 'Current Amplify CLI env name',
    });

    // 直接在当前栈内定义Lambda,指向现有代码目录
    const myFunction = new lambda.Function(this, "MyFunction", {
      runtime: lambda.Runtime.NODEJS_18_X,
      handler: "index.handler",
      code: lambda.Code.fromAsset("../functions/myFunction"), // 替换为你的Lambda代码路径
    });

    const provider = new cr.Provider(this, "MyCustomResourceProvider", {
      onEventHandler: myFunction,
      logRetention: logs.RetentionDays.ONE_DAY,
    })

    new cdk.CustomResource(this, "MyCustomResource", {
      serviceToken: provider.serviceToken
    })
  }
}

排查方法

  • 查看Amplify生成的CloudFormation模板:进入.amplify/backend/custom/你的资源名称目录,检查模板中是否存在未赋值的AssetParameters参数。
  • 验证Lambda逻辑:手动触发myFunction,传入模拟的CloudFormation自定义资源事件,确认其能返回符合要求的响应格式。
  • 检查权限配置:确保Amplify部署角色有权限访问该Lambda,且Lambda自身具备执行所需操作的IAM权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 15:45:27