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

如何在不触发类型转换异常的情况下重写AWS CDK资源Logical ID

问题

之前一直用某篇文章里的方法重写AWS CDK资源的Logical ID,该方法正常运行数月,代码如下:

class MyConstruct(scope: Construct, id: String) extends Construct(scope, id) {
    val barFunc =
      lambda
        .Function
        .Builder
        .create(this, "bar")
        .handler("blah.blah")
        .code(lambda.Code.fromInline("blah"))
        .runtime(lambda.Runtime.PYTHON_3_10)
        .build

    barFunc
      .getNode
      .getDefaultChild
      .asInstanceOf[CfnFunction]
      .overrideLogicalId("mylogicalid")

}

class MyStack(scope: Construct, id: String, stackProps: StackProps) extends Stack(scope, id, stackProps) {
   val barConstruct = new MyConstruct(this, "bar")
}

近期未修改代码,但执行synth时突然失败,报错:

java.lang.ClassCastException: class software.constructs.Construct cannot be cast to class software.amazon.awscdk.services.lambda.CfnFunction

推测是CDK破坏性更新导致,已尝试回退cdk和aws-cdk-lib版本但无效,当前依赖版本:

lazy val awsCdkLib = "software.amazon.awscdk" % "aws-cdk-lib" % "2.89.0"
  lazy val awsConstructs = "software.constructs" % "constructs" % "10.2.69"

需要找到修改已实例化Function的Logical ID且不触发异常的方法。

解决方案

之前通过getDefaultChild强转的方式失效,是因为CDK部分高层construct的默认子节点结构发生了变化,现在可以通过以下两种可靠方法修改Lambda Function的Logical ID:

方法1:直接获取底层Cfn资源(推荐)

Lambda的Function construct提供了getCfnFunction()方法,可直接获取对应的CfnFunction实例,无需强转:

class MyConstruct(scope: Construct, id: String) extends Construct(scope, id) {
    val barFunc =
      lambda
        .Function
        .Builder
        .create(this, "bar")
        .handler("blah.blah")
        .code(lambda.Code.fromInline("blah"))
        .runtime(lambda.Runtime.PYTHON_3_10)
        .build

    // 直接调用官方方法获取底层CFN资源
    barFunc.getCfnFunction.overrideLogicalId("mylogicalid")
}

class MyStack(scope: Construct, id: String, stackProps: StackProps) extends Stack(scope, id, stackProps) {
   val barConstruct = new MyConstruct(this, "bar")
}

方法2:遍历子节点筛选CfnFunction

如果getCfnFunction()方法不可用,可遍历Function的子节点,筛选出CfnFunction类型的实例:

class MyConstruct(scope: Construct, id: String) extends Construct(scope, id) {
    val barFunc =
      lambda
        .Function
        .Builder
        .create(this, "bar")
        .handler("blah.blah")
        .code(lambda.Code.fromInline("blah"))
        .runtime(lambda.Runtime.PYTHON_3_10)
        .build

    // 遍历子节点找到目标CfnFunction
    val cfnFunc = barFunc.getNode.getChildren
      .find(_.isInstanceOf[CfnFunction])
      .getOrElse(throw new RuntimeException("Failed to locate CfnFunction instance"))
      .asInstanceOf[CfnFunction]
    
    cfnFunc.overrideLogicalId("mylogicalid")
}

class MyStack(scope: Construct, id: String, stackProps: StackProps) extends Stack(scope, id, stackProps) {
   val barConstruct = new MyConstruct(this, "bar")
}

关键说明

  • 方法1是最稳妥的方案,因为这是CDK官方提供的访问底层CFN资源的接口,不会因内部结构调整而失效。
  • 避免依赖getDefaultChild这类内部实现细节,CDK的节点结构可能随版本更新发生变化,导致强转异常。

内容的提问来源于stack exchange,提问作者Ramón J Romero y Vigil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 15:42:50