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

如何使用Lambda ARN订阅SNS主题 解决CDK Token未解析报错

问题根因

报错本质是CDK执行时序和你的代码调用时机不匹配,同时混用基础设施定义和SDK调用违反了CDK的基本运行逻辑:

  • CDK代码运行分两个阶段:第一阶段是本地合成阶段,执行你写的Python构造代码,生成CloudFormation模板,这个阶段所有未创建的资源属性(比如function_arn)都是CDK生成的${Token[TOKEN.xxx]}占位符,要等CloudFormation实际部署资源时才会替换成真实值;第二阶段是云端部署阶段,CloudFormation按照模板顺序创建资源,此时才能拿到资源的真实ARN、ID等属性。
  • 你把boto3的SNS创建、订阅逻辑直接写在CDK构造代码里,这些调用会在本地合成阶段就直接用你本地的AWS凭证发起请求,此时Lambda还没开始创建,拿到的只有无法被AWS API识别的Token占位符,自然会报Endpoint ARN非法的错误。
  • 额外问题:这种写法创建的SNS主题不在CDK栈的管理范围内,后续执行栈删除、更新操作时,这个SNS主题不会被同步处理,会产生云资源残留。
推荐解决方案:全量使用CDK原生资源构造,移除boto3调用

CDK本身已经封装了SNS主题、SNS订阅Lambda的相关资源,完全不需要自行编写boto3调用,CDK会自动处理资源依赖、ARN传参、权限配置的问题,部署时会自动等待资源创建完成再注入正确的属性值。
修改后的代码逻辑如下:

# 引入CDK自带的SNS、SNS订阅相关依赖,无需使用boto3
from aws_cdk import aws_sns as sns
from aws_cdk import aws_sns_subscriptions as subscriptions
from aws_cdk import Tags

# 原有Lambda定义,注意同scope下构造ID不能重复,这里将角色ID调整为不与Lambda重名
dynamodb_lambda = lambda_.Function(
                        self,
                        "foobar",
                        runtime = lambda_.Runtime.PYTHON_3_7,
                        handler = "lambda_handlers.dynamodb_lambda_handler",
                        code    = lambda_.Code.from_asset(path),
                        role    = iam_.Role(
                                    self,
                                    "DynamoDBLambdaRole",
                                    assumed_by = iam_.ServicePrincipal('lambda.amazonaws.com'),
                                    managed_policies = [
                                        iam_.ManagedPolicy.from_aws_managed_policy_name('DynamoDBFullAccess')
                                    ]
                        )
                    )

# 用CDK原生构造创建SNS主题,替代boto3的create_topic调用
sns_topic = sns.Topic(
    self,
    "AppSnsTopic",
    topic_name = c.SNS_TOPIC_NAME
)
# 给SNS主题添加指定标签
Tags.of(sns_topic).add("CohortStudent", "anon")

# 给SNS主题添加Lambda订阅,CDK会自动完成ARN传参、触发权限配置
sns_topic.add_subscription(subscriptions.LambdaSubscription(dynamodb_lambda))

该写法的优势:

  • 不需要手动处理ARN传参,CDK会自动在CloudFormation模板中配置正确的资源引用,部署时自动解析为真实ARN值
  • 自动给Lambda添加SNS触发所需的资源策略,不需要手动调用权限添加接口
  • 自动处理资源创建顺序:CDK会识别到SNS订阅依赖Lambda和SNS主题资源,会等两个资源都创建完成后再创建订阅关系,不会出现时序错误
  • 所有资源都纳入CDK栈管理,后续更新、删除栈时会同步处理对应资源,不会产生残留
特殊场景方案:必须使用boto3时通过自定义资源在部署阶段执行

如果有特殊业务逻辑无法通过CDK原生构造实现,必须使用boto3编写自定义逻辑,不能将boto3调用直接写在构造代码中,需要将boto3逻辑封装为CDK自定义资源,让这段逻辑在CloudFormation部署阶段、Lambda创建完成之后再执行:

  • 自定义资源会在部署时由CloudFormation触发临时Lambda执行你的boto3代码
  • 可以将CDK创建的Lambda ARN作为参数传给自定义资源,此时传入的Token会在部署阶段被解析为真实的ARN值,可正常被boto3接口识别
  • 自定义资源需要正确处理创建、更新、删除三类事件回调,避免资源残留

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 03:18:16