主题 ARN 和目标 ARN AWS SNS 有什么区别?
What is the difference between Topic ARN and Target ARN AWS SNS?
我尝试在 Lambda 中使用 boto3 向 SNS 主题发布消息,如下所示:
def publish_msg(msg, bar):
response = SNS.publish(
TopicArn='blah_blah_arn',
Message=msg,
MessageAttributes={
'foo': {
'DataType': 'String',
'StringValue': bar
}
}
)
它不起作用,因为它一直给我一个像这样的身份验证错误:
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 根本没有回答这个问题。
非常感谢!
事实证明,这里的问题并不像看上去的那样。
在这种情况下,TopicArn
和 TargetArn
实际上是可以互换的。 (为什么有两种可能的方式来传递主题 ARN?SNS 最初只支持主题作为目标,但现在支持其他种类的东西,所以这很可能是 API 向后兼容的情况,AWS 通常非常擅长。)
tl;dr:有时,当 Lambda 执行角色使用的 IAM 策略被修改时,Lambda 函数的行为就像发生了策略更改一样。
它似乎只有在从一个更改为另一个后才起作用的原因与(在某种程度上)更新 Lambda 函数代码时发生的情况有关。
Lambda 服务管理 运行 您的代码的容器,每个容器 运行 一次不超过一个函数并发调用。后续调用可能会重用相同的容器...但前提是与函数关联的代码相同且未更改。
更新函数代码,然后再次 运行 函数(第一次使用新代码),你会运行进入一个新的容器以前没用过。
新容器必须使用 AssumeRole
action in AWS Security Token Service, which provides a temporary AWS-Access-Key-ID and Secret Key, as well as a Session Token. Lambda stores these in environment variables 作为 AWS_ACCESS_KEY_ID
、AWS_SECRET_ACCESS_KEY
和 AWS_SESSION_TOKEN
获取 Lambda 执行角色的临时凭证,其中 AWS-SDK在您的函数中(在本例中用于调用其他服务,如 SNS)选择它们并使用它们来签署请求。
OP 运行 的内容是此设置中的一个怪癖。 IAM 或 STS 中的某些内容会导致 AWS 系统中的缓存数据或陈旧数据——允许 Lambda 执行角色针对相关主题执行 SNS:Publish
操作所必需的策略(或最新版本的策略)对于需要查看它的组件尚不可见,以便允许该操作。
尚不清楚此缓存发生的确切位置。 Lambda 当然会缓存临时凭证,但 EC2 元数据服务也是如此,任何行为良好的客户端也是如此,因为在临时凭证仍然有效时继续向 STS 发出请求是没有意义的。我不相信凭据本身的缓存是原因(尽管它有所贡献)。
STS 凭据是一个黑盒子,尤其是 "Session Token." 它是否包含加密数据?或者它只是一个很大的 运行dom 值,字面上只不过是一个没有内在含义的象征性 "token"?这并不重要,但关键是它没有明确记录。
IAM 是一个庞大的分布式系统,因此它自然会偶尔 "eventual consistency" issues that can arise。
但是,不知何故,创建一个新的 Lambda 容器——它必须对 STS 进行新的调用——似乎有一个缓存破坏的副作用,使得当前的执行角色的 IAM 策略在某些情况下变得可用在新部署中不起作用的地方。
在您尝试给定的操作后,似乎偶尔会弹出,它失败了,您意识到您需要编辑 IAM 策略,您打算足以允许该操作。所以你编辑了政策,但随后的尝试仍然失败,但政策似乎有效,所以你无法弄清楚为什么它不起作用,然后你在空中挥舞着你的手,给约翰罗滕斯坦发消息说你是不知所措...然后,在失望地放弃了一晚之后,第二天早上 return 进一步排除故障,发现它突然起作用了。
大概这与旧的执行角色临时凭据被替换有关,要么是由于容器因不活动而被 p运行ed 和替换,或者仅仅是因为临时凭据的寿命有限...但尚不清楚刷新 STS 令牌是否真的是解决方案的必要部分,或者它是否只是修复了 IAM 中的一个副作用作为副作用。
重新部署 Lambda 函数以测试代码更改可能会产生与此处相同的效果,无论哪种方式。
我尝试在 Lambda 中使用 boto3 向 SNS 主题发布消息,如下所示:
def publish_msg(msg, bar):
response = SNS.publish(
TopicArn='blah_blah_arn',
Message=msg,
MessageAttributes={
'foo': {
'DataType': 'String',
'StringValue': bar
}
}
)
它不起作用,因为它一直给我一个像这样的身份验证错误:
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 根本没有回答这个问题。
非常感谢!
事实证明,这里的问题并不像看上去的那样。
在这种情况下,TopicArn
和 TargetArn
实际上是可以互换的。 (为什么有两种可能的方式来传递主题 ARN?SNS 最初只支持主题作为目标,但现在支持其他种类的东西,所以这很可能是 API 向后兼容的情况,AWS 通常非常擅长。)
tl;dr:有时,当 Lambda 执行角色使用的 IAM 策略被修改时,Lambda 函数的行为就像发生了策略更改一样。
它似乎只有在从一个更改为另一个后才起作用的原因与(在某种程度上)更新 Lambda 函数代码时发生的情况有关。
Lambda 服务管理 运行 您的代码的容器,每个容器 运行 一次不超过一个函数并发调用。后续调用可能会重用相同的容器...但前提是与函数关联的代码相同且未更改。
更新函数代码,然后再次 运行 函数(第一次使用新代码),你会运行进入一个新的容器以前没用过。
新容器必须使用 AssumeRole
action in AWS Security Token Service, which provides a temporary AWS-Access-Key-ID and Secret Key, as well as a Session Token. Lambda stores these in environment variables 作为 AWS_ACCESS_KEY_ID
、AWS_SECRET_ACCESS_KEY
和 AWS_SESSION_TOKEN
获取 Lambda 执行角色的临时凭证,其中 AWS-SDK在您的函数中(在本例中用于调用其他服务,如 SNS)选择它们并使用它们来签署请求。
OP 运行 的内容是此设置中的一个怪癖。 IAM 或 STS 中的某些内容会导致 AWS 系统中的缓存数据或陈旧数据——允许 Lambda 执行角色针对相关主题执行 SNS:Publish
操作所必需的策略(或最新版本的策略)对于需要查看它的组件尚不可见,以便允许该操作。
尚不清楚此缓存发生的确切位置。 Lambda 当然会缓存临时凭证,但 EC2 元数据服务也是如此,任何行为良好的客户端也是如此,因为在临时凭证仍然有效时继续向 STS 发出请求是没有意义的。我不相信凭据本身的缓存是原因(尽管它有所贡献)。
STS 凭据是一个黑盒子,尤其是 "Session Token." 它是否包含加密数据?或者它只是一个很大的 运行dom 值,字面上只不过是一个没有内在含义的象征性 "token"?这并不重要,但关键是它没有明确记录。
IAM 是一个庞大的分布式系统,因此它自然会偶尔 "eventual consistency" issues that can arise。
但是,不知何故,创建一个新的 Lambda 容器——它必须对 STS 进行新的调用——似乎有一个缓存破坏的副作用,使得当前的执行角色的 IAM 策略在某些情况下变得可用在新部署中不起作用的地方。
在您尝试给定的操作后,似乎偶尔会弹出,它失败了,您意识到您需要编辑 IAM 策略,您打算足以允许该操作。所以你编辑了政策,但随后的尝试仍然失败,但政策似乎有效,所以你无法弄清楚为什么它不起作用,然后你在空中挥舞着你的手,给约翰罗滕斯坦发消息说你是不知所措...然后,在失望地放弃了一晚之后,第二天早上 return 进一步排除故障,发现它突然起作用了。
大概这与旧的执行角色临时凭据被替换有关,要么是由于容器因不活动而被 p运行ed 和替换,或者仅仅是因为临时凭据的寿命有限...但尚不清楚刷新 STS 令牌是否真的是解决方案的必要部分,或者它是否只是修复了 IAM 中的一个副作用作为副作用。
重新部署 Lambda 函数以测试代码更改可能会产生与此处相同的效果,无论哪种方式。