从外部账户使用 SNS 调用 Lambda

Invoke Lambda using SNS from Outside Account

我一直在关注 Amazon 的以下博客 post(场景 3:从另一个帐户中的 Amazon S3 存储桶通知触发 Lambda 函数)关于授权 Lambda 函数用于各种用途。我想设置一个 Lambda 函数来接受来自外部帐户的 SNS 消息(在具有 lambda 函数的帐户外部)。

https://aws.amazon.com/blogs/compute/easy-authorization-of-aws-lambda-functions/

我希望添加远程调用函数的权限如下:

$ aws lambda add-permission \
     --function-name MyFunction \
     --region us-west-2 \
     --statement-id Id-123 \
     --action "lambda:InvokeFunction" \
     --principal sns.amazonaws.com \
     --source-arn arn:aws:sns:::<topic name> \
     --source-account <account number> \
     --profile adminuser

然后我尝试转到我的 SNS 主题并将 Lambda 设置为端点,并在第一个帐户中为 lambda 函数键入远程 ARN。这不太有效,因为端点需要帐户中函数的 arn...

B计划: 尝试通过 CLI 创建订阅以规避控制台中的限制...

 aws sns --profile adminuser \
     --region us-west-2 subscribe 
     --topic-arn arn:aws:sns:us-west-2:<account #>:<topic name> 
     --protocol lambda 
     --notification-endpoint arn:aws:lambda:us-west-2:<account id>:function:<lambda function name>

回复:
A client error (AuthorizationError) occurred when calling the Subscribe operation: The account <account id> is not the owner of the lambda function arn:aws:lambda:us-west-2:<account id>:function:<function name>

有没有人能够从另一个帐户中的 "remote" SNS 调用 Lambda 函数?我有点困惑我可能哪里出错了...根据博客中的注释 post,我完全希望远程 SNS 能够工作:
Note: Amazon SNS (Simple Notification Service) events sent to Lambda works the same way, with “sns.amazonaws.com” replacing “s3.amazonaws.com” as the principal.

如果提供者帐户授权拥有 lambda 的消费者帐户订阅 SNS 主题,则可以。这可以在 topics page.

下的 "Edit topic policy" 中完成

以下是允许 lambda 从外部帐户侦听 SNS 主题的步骤摘要:

  1. 消费者帐户创建 lambda,
  2. 消费者帐户通过指定提供者的 SNS 主题 ARN 将事件源添加到 AWS 控制台中的 lambda(不要担心此处的错误消息),
  3. 提供者账户将 SNS 订阅权限添加到在第三方 AWS 账户中创建的消费者 IAM 账户(通过上述 "edit topic policy" 完成),
  4. 消费者使用第 2 步中的 IAM 账户通过 AWS CLI 添加对提供商账户的订阅。

之前对我有用的第 4 步示例命令:

aws sns subscribe --topic-arn <provider_sns_arn> --protocol lambda --notification-endpoint <consumer_lambda_arn> --profile consumer-IAM-account

在 AWS Lambda 开发人员指南中有一个 tutorial,其中 AWS CLI 命令用于设置从属于另一个账户的 SNS 调用 Lambda 函数。

该过程与接受的答案中的过程非常相似。订阅无需确认。在 aws sns subscribe 命令之后就可以进行测试了。

我运行遇到了同样的问题。该错误是因为您正在从拥有 SNS 主题的帐户调用 SNS 订阅函数。虽然这看起来合乎逻辑并且是您通常的做法,但 AWS 希望您在跨账户访问时采取相反的方式 - 您必须从拥有 Lambda 函数的账户调用 SNS 订阅函数。

今天有类似需求。总结起来有3个步骤。假设 111111111 是具有 SNS 主题的生产者帐户,2222222222 是具有 lambda 的消费者,

  1. 允许 Lambda 函数订阅主题

    aws sns --profile SNS_Owner_Profile add-permission \  
          --topic-arn "arn:aws:sns:us-east-1:111111111:your-sns-top" \  
          --label "AllowCrossAccountSns" \  
          --aws-account-id "2222222222" \  
          --action-name "Receive" "Subscribe"  
    
  2. 允许主题调用 Lambda 函数,

    aws lambda --profile Lambda_Owner_Profile add-permission \                                                                                                                     
          --function-name "your-lambda-function" \  
          --statement-id "allowCrossAccountSNS" \  
          --principal "sns.amazonaws.com" \  
          --action "lambda:InvokeFunction" \  
          --source-arn "arn:aws:sns:us-east-1:111111111:your-sns-top"  
    
  3. 订阅主题的 lambda 函数。

    aws sns --profile Lambda_Owner_Profile subscribe \                                                                                                                          
          --topic-arn "arn:aws:sns:us-east-1:111111111:your-sns-top" \  
          --protocol "lambda" \  
          --notification-endpoint "arn:aws:lambda:us-east-1:2222222222:function:your-lambda-function"