AWS CDK疑问:为何代理资源无法替代实际资源用于Trigger?
问题原因与解决方案
问题根源
通过_lambda.Function.from_function_arn()获取的是Lambda的只读代理对象(_FunctionBaseProxy),它仅包含ARN等基础标识信息,并非完整的Function类实例。而triggers.Trigger的handler参数要求传入可操作的Function实例——因为Trigger需要给Lambda添加触发器权限、配置事件源等修改操作,只读代理对象无法支持这些操作,因此触发类型错误。
AWS文档中说代理资源可像动态资源传递,指的是只读场景(比如传递ARN作为其他资源的依赖参数),但涉及资源修改的场景不适用。
解决方案
方案1:使用同栈内创建的Lambda实例(优先推荐)
如果你的Lambda是在当前CDK栈中动态创建的,直接使用创建时的Function实例即可,无需通过from_function_arn获取:
# 假设这是你在当前栈中创建的Lambda nr_ingest_lambda = _lambda.Function( self, "new-relic-log-ingest-lambda", runtime=_lambda.Runtime.PYTHON_3_11, handler="index.handler", code=_lambda.Code.from_asset("lambda") ) # 直接传入实例创建Trigger nr_ingest_trigger = triggers.Trigger( self, "nr-log-ingest-trigger", handler=nr_ingest_lambda, )
方案2:通过from_function_attributes获取外部Lambda的完整引用
如果Lambda是外部栈或手动创建的,使用from_function_attributes替代from_function_arn,传入必要的属性(至少包含function_arn,若需要Trigger配置权限则需传入role):
from aws_cdk import aws_iam as iam nr_ingest_lambda = _lambda.Function.from_function_attributes( self, "new-relic-log-ingest-lambda", function_arn="arn:aws:lambda:region:account-id:function:function-name", # 若Trigger需要给Lambda添加权限,需传入Lambda的执行角色ARN role=iam.Role.from_role_arn(self, "LambdaExecutionRole", role_arn="arn:aws:iam::account-id:role/lambda-role") ) nr_ingest_trigger = triggers.Trigger( self, "nr-log-ingest-trigger", handler=nr_ingest_lambda, )
方案3:手动创建触发器(绕过Trigger构造函数限制)
如果上述方案无法满足需求,可以直接用CloudWatch Events规则手动创建触发器,无需依赖triggers.Trigger:
from aws_cdk import aws_events as events from aws_cdk import aws_events_targets as targets # 获取外部Lambda代理 nr_ingest_lambda = _lambda.Function.from_function_arn( self, "new-relic-log-ingest-lambda", function_arn="arn:aws:lambda:region:account-id:function:function-name" ) # 创建定时规则(示例:每天凌晨执行) trigger_rule = events.Rule( self, "NrLogIngestTriggerRule", schedule=events.Schedule.cron(minute="0", hour="0") ) # 将Lambda设为规则目标 trigger_rule.add_target(targets.LambdaFunction(nr_ingest_lambda))
方案4:强制类型转换(不推荐,有运行时风险)
若你确认不需要Trigger对Lambda进行修改操作,可通过类型转换绕过类型检查,但可能引发运行时错误:
from typing import cast nr_ingest_lambda_proxy = _lambda.Function.from_function_arn( self, "new-relic-log-ingest-lambda", function_arn="arn:aws:lambda:region:account-id:function:function-name" ) # 强制转换为Function类型 nr_ingest_lambda = cast(_lambda.Function, nr_ingest_lambda_proxy) nr_ingest_trigger = triggers.Trigger( self, "nr-log-ingest-trigger", handler=nr_ingest_lambda, )
内容的提问来源于stack exchange,提问作者SteveJ
相关产品推荐
相关产品推荐

