AWS SAM模板中Lambda调用跨账号SNS FIFO时账号ID混淆问题求助
问题描述
我有一个用于Lambda调用两个跨账号SNS FIFO的SAM模板,配置如下:
Resources: MainFunction: Type: 'AWS::Serverless::Function' Properties: Handler: core.lambda_function.lambda_handler Policies: - SNSPublishMessagePolicy: TopicName: !Select [ 5, !Split [ ":", !Ref SNSTopicARN ] ] - SNSPublishMessagePolicy: TopicName: !Select [ 5, !Split [ ":", !Ref SNSTopicARN2 ] ]
但当SNSTopicARN和SNSTopicARN2属于不同AWS账号时,生成的权限策略出现账号ID混淆,例如第二个SNS对应的资源ARN错误使用了第一个SNS的账号ID:
{ "Statement": [ { "Action": [ "sns:Publish" ], "Resource": "arn:aws:sns:us-east-1:idAccountFromSNS1:SNS2.fifo", "Effect": "Allow" } ] }
请问是否可以在SNSPublishMessagePolicy中直接指定ARN,或有其他方法避免该问题?
解决方案
方法1:直接使用自定义IAM策略替代SNSPublishMessagePolicy
SNSPublishMessagePolicy的设计逻辑是默认采用当前部署栈的账号ID,跨账号场景下必然出现混淆。直接定义完整IAM策略语句,明确指定每个SNS Topic的ARN即可解决:
Resources: MainFunction: Type: 'AWS::Serverless::Function' Properties: Handler: core.lambda_function.lambda_handler Policies: - Statement: - Effect: Allow Action: sns:Publish Resource: !Ref SNSTopicARN - Effect: Allow Action: sns:Publish Resource: !Ref SNSTopicARN2
这种方式绕开了SAM策略模板的账号ID推断逻辑,直接使用传入的完整ARN,不会出现跨账号混淆问题。
方法2:单独创建IAM策略资源绑定权限
如果需要更清晰的权限管理,可单独创建IAM策略再关联到Lambda函数:
Resources: MainFunction: Type: 'AWS::Serverless::Function' Properties: Handler: core.lambda_function.lambda_handler Policies: - !Ref SNSPublishPolicy SNSPublishPolicy: Type: AWS::IAM::Policy Properties: PolicyName: LambdaCrossAccountSNSPublishPolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: sns:Publish Resource: - !Ref SNSTopicARN - !Ref SNSTopicARN2 Roles: - !Ref MainFunctionRole
注意需要引用Lambda自动生成的角色(命名规则为函数名+Role后缀),若使用自定义角色则直接引用其ARN即可。
问题根源
SAM的SNSPublishMessagePolicy模板生成资源ARN时,默认采用当前部署栈所在的账号ID,而非从传入的TopicName反向推断对应账号ID。当传入跨账号TopicName时,仅替换ARN中的TopicName部分,账号ID仍沿用当前栈(或第一个策略的账号ID),最终导致ARN错误。
内容的提问来源于stack exchange,提问作者Lucke
相关产品推荐
相关产品推荐

