Topic ARN和Target ARN AWS SNS有什么区别?

时间:2019-10-10 00:39:56

标签: boto3 amazon-sns

我试图像这样在Lambda中使用boto3将消息发布到SNS主题:

def publish_msg(msg, bar):
    response = SNS.publish(
        TopicArn='blah_blah_arn',
        Message=msg,
        MessageAttributes={
            'foo': {
                'DataType': 'String',
                'StringValue': bar
            }
        }
    )

无效,因为它不断给我一个auth错误,如下所示:

Error publishing message because lambda_fn_role doesn't have the permissions to invoke SNS:Publish on resource blah_blah_arn

但是我确定我对该功能的策略是正确的,所以我将TopicARN更改为TargetARN并成功了!

所以我的问题是:主题和目标ARN有什么区别?以及何时应使用另一个?

AWS docs for boto3根本没有回答这个问题。

非常感谢!

1 个答案:

答案 0 :(得分:2)

事实证明,这里的问题并不像看起来那样。

在这种情况下,

TopicArnTargetArn实际上是可以互换的。 (为什么有两种可能的方法来传递主题ARN?SNS最初仅支持将主题作为目标,但现在支持其他类型的东西,因此这很可能是API向后兼容的一种情况,AWS通常非常擅长此功能。)

tl; dr:有时,当修改Lambda执行角色使用的IAM策略时,Lambda函数的行为就好像发生了策略更改一样。

它似乎只有从一个更改为另一个后才起作用的原因(在某种程度上)与更新Lambda函数的代码时发生的情况有关。

Lambda服务管理运行代码的容器,每个容器一次运行的函数并发调用不超过一个。后续调用可以重用相同的容器...但是仅当与该函数关联的代码相同且不变时。

更新功能代码,然后再次运行该功能(首次使用新代码),可以确保您位于以前未使用过的新容器中。

新容器必须使用AWS Security Token Service中的AssumeRole操作获取Lambda执行角色的临时凭证,该操作提供一个临时AWS-Access-Key-ID和密钥以及一个会话令牌。 Lambda stores these in environment variables分别为AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_SESSION_TOKEN,其中函数中的AWS-SDK(在此示例中用于调用其他服务,例如SNS)捡起来并用它们来签名请求。

OP遇到的一个奇怪之处是此设置。 IAM或STS中的某些内容会导致AWS系统内部缓存或过时的数据-一种策略(或策略的最新版本),该参数对于允许Lambda执行角色针对所涉及的主题执行SNS:Publish操作是必需的对于需要查看该组件的组件而言,尚不可见,以便允许执行该操作。

目前尚不清楚此缓存的确切位置。 Lambda当然会缓存临时凭证,但是EC2元数据服务也会缓存,行为良好的客户端也会缓存,因为当临时凭证仍然有效时,连续向STS发出请求是没有意义的。我不相信凭据的缓存本身就是原因(尽管它是造成这种情况的原因)。

STS凭据是一个黑匣子,尤其是“会话令牌”。它是否包含加密数据?还是仅仅是一个较大的随机值,而实际上只是一个没有内在含义的符号“令牌”?其实并不重要,但重点是没有明确记录。

IAM是一个庞大的分布式系统,因此它有时自然具有“最终一致性” issues that can arise

但是,无论如何,创建一个新的Lambda容器-必须必须对STS进行新调用-似乎具有缓存无效化的副作用,这使得在某些情况下,当前用于执行角色的IAM策略变得可用在新的部署中不起作用。

尝试执行给定的操作后,有时似乎会弹出该窗口,但它失败了,并且您意识到需要编辑足以使该操作生效的IAM策略。因此,您编辑了该策略,但是随后的尝试仍然失败,但是该策略似乎仍然有效,因此您无法弄清它为何不起作用,于是不知所措,向约翰·罗滕斯坦发送了一条信息,告知您在机智的尽头...然后,在失望的夜晚放弃后,您第二天早上返回进一步进行故障排除,发现它突然开始工作。

大概这与替换旧执行角色有关,因为是由于不活动而对容器进行了修剪和替换,或者仅仅是因为临时凭据的寿命有限,所以替换了临时凭据……但是尚不清楚是否刷新STS令牌实际上是解决方案的必要部分,或者它是否只是解决了附加IAM中的对数冲突问题。

无论采用哪种方式,重新部署Lambda函数以测试代码更改都可能具有与此处相同的效果。