如何在我的 Amazon SQS 队列和 AWS CloudFormation 中的 Amazon SNS 主题之间创建订阅?

上次更新时间:2019 年 10 月 2 日

如何在我的 Amazon Simple Queue Service (Amazon SQS) 队列和 AWS CloudFormation 中的 Amazon Simple Notification Service (Amazon SNS) 主题之间创建订阅?

解决方法

请根据您的使用案例从下列解决方案中选择一种:

  • 如果 SNS 主题和 SQS 队列位于同一堆栈中, 请利用 AWS CloudFormation 模板创建向 Amazon SQS 队列发送消息的主题
  • 如果 SNS 主题和将会订阅该 SNS 主题的 SQS 队列位于同一 AWS 区域的不同堆栈中,请创建跨堆栈引用
    注意:当您创建跨堆栈参考时,将 SQS 队列的 Amazon 资源名称 (ARN) 导出到一个堆栈中。然后,将 SNS 主题的订阅终端节点属性中的 SQS 队列 ARN 导入另一个堆栈中。
  • 如果 SNS 主题和 SQS 队列位于不同的 AWS 区域,请按照使用 AWS::SNS::Subscription 资源来设置跨区域订阅部分描述的步骤进行操作。
  • 如果 SNS 主题和 SQS 队列位于不同的 AWS 账户,请按照使用 AWS::SNS::Subscription 资源来设置跨账户订阅部分描述的步骤进行操作。

使用 AWS::SNS::Subscription 资源来设置跨区域订阅

1.    在位于一个 AWS 区域的堆栈的 AWS CloudFormation 模板中声明该区域的 SNS 主题,然后创建一个输出资源来注释 SNS 主题 ARN。

请参阅以下 JSON 和 YAML 示例模板。

JSON:

{
 "Resources": {
  "SnsTopic": {
   "Type": "AWS::SNS::Topic"
  }
 },
 "Outputs": {
  "SnsTopicArn": {
   "Value": "SnsTopic"
  }
 }
}

YAML:

Resources:
  SnsTopic:
    Type: AWS::SNS::Topic
Outputs:
  SnsTopicArn:
    Value: !Ref SnsTopic

2.    在位于另一个 AWS 区域的另一个堆栈的 AWS CloudFormation 模板中,定义 AWS::SNS::Subscription 资源和 SQS 队列。

注意:awsSNSTopicArnExample 替换为您的 SNS 主题 ARN,并将 us-east-1 替换为您的 AWS 区域。

请参阅以下 JSON 和 YAML 示例模板。

JSON:

{
 "Parameters": {
  "SNSTopicARN": {
   "Type": "String",
   "Description": "awsSNSTopicArnExample"
  },
  "TopicRegion": {
   "Type": "String",
   "Description": "us-east-1"
  }
 },
 "Resources": {
  "Queue": {
   "Type": "AWS::SQS::Queue"
  },
  "SnsSubscription": {
   "Type": "AWS::SNS::Subscription",
   "Properties": {
    "Protocol": "sqs",
    "Endpoint": {
     "Fn::GetAtt": [
      "Queue",
      "Arn"
     ]
    },
    "Region": {
     "Ref": "TopicRegion"
    },
    "TopicArn": {
     "Ref": "SNSTopicARN"
    }
   }
  }
 }
}

YAML:

Parameters:
  SNSTopicARN:
    Type: String
    Description: awsSNSTopicArnExample 
  TopicRegion:
    Type: String
    Description: us-east-1

Resources:
  Queue:
    Type: AWS::SQS::Queue

  SnsSubscription:
    Type: AWS::SNS::Subscription
    Properties:
      Protocol: sqs
      Endpoint: !GetAtt Queue.Arn
      Region: !Ref TopicRegion
      TopicArn: !Ref SNSTopicARN

您的跨区域订阅现已设置。

使用 AWS::SNS::Subscription 资源设置跨账户订阅

1.    在位于一个 AWS 源账户的堆栈的 AWS CloudFormation 模板中,声明 SNS 主题和 AWS::SNS::TopicPolicy。然后,创建一个输出资源来注释 SNS 主题 ARN,并提供您的目标 AWS 账户作为参数。

请参阅以下 JSON 和 YAML 示例模板。

JSON:

{
  "Parameters": {
    "CrossAccountNumber": {
      "AllowedPattern": "[0-9]+",
      "Description": "The 12 digit AWS account number to grant access to.",
      "MaxLength": "12",
      "MinLength": "12",
      "Type": "String",
      "Default": 123456789101
    }
  },
  "Resources": {
    "SnsTopic": {
      "Type": "AWS::SNS::Topic"
    },
    "SnsTopicPolicy": {
      "Type": "AWS::SNS::TopicPolicy",
      "DependsOn": "SnsTopic",
      "Properties": {
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "SnsTopicPolicy",
              "Effect": "Allow",
              "Principal": {
                "AWS": {
                  "Fn::Sub": "arn:aws:iam::${CrossAccountNumber}:root"
                }
              },
              "Action": [
                "sns:Subscribe"
              ],
              "Resource": {
                "Ref": "SnsTopic"
              }
            }
          ]
        },
        "Topics": [
          {
            "Ref": "SnsTopic"
          }
        ]
      }
    }
  },
  "Outputs": {
    "SnsTopicArn": {
      "Value": {
        "Ref": "SnsTopic"
      }
    }
  }
}

YAML:

Parameters:
 CrossAccountNumber:
  AllowedPattern: '[0-9]+'
  Description: The 12 digit AWS account number to grant access to.
  MaxLength: '12'
  MinLength: '12'
  Type: String
  Default: 123456789101
Resources:
 SnsTopic:
  Type: AWS::SNS::Topic
 SnsTopicPolicy:
  Type: AWS::SNS::TopicPolicy
  DependsOn: SnsTopic
  Properties:
   PolicyDocument:
    Version: '2012-10-17'
    Statement:
    - Sid: SnsTopicPolicy
     Effect: Allow
     Principal:
      AWS: !Sub arn:aws:iam::${CrossAccountNumber}:root
     Action:
     - sns:Subscribe
     Resource: !Ref SnsTopic
   Topics:
    - !Ref SnsTopic
Outputs:
 SnsTopicArn:
  Value: !Ref SnsTopic

2.    在位于您想要扩展订阅所在的 AWS 账户的堆栈的 AWS CloudFormation 模板中,定义 AWS::SNS::Subscription 资源、SQS 队列和 AWS::SQS::QueuePolicy 策略。

注意:awsSNSTopicArn 替换为您的 SNS 主题 ARN,并将 us-east-1 替换为您的 AWS 区域。

请参阅以下 JSON 和 YAML 示例模板。

JSON:

{
 "Parameters": {
  "SNSTopicARN": {
   "Type": "String",
   "Default": "awsSNSTopicArn"
  },
  "TopicRegion": {
   "Type": "String",
   "Default": "us-east-1"
  }
 },
 "Resources": {
  "Queue": {
   "Type": "AWS::SQS::Queue"
  },
  "SqsQueuePolicy": {
   "Type": "AWS::SQS::QueuePolicy",
   "Properties": {
    "PolicyDocument": {
     "Version": "2012-10-17",
     "Id": "MyQueuePolicy",
     "Statement": [
      {
       "Sid": "Allow-SNS-SendMessage",
       "Effect": "Allow",
       "Principal": "*",
       "Action": [
        "sqs:SendMessage"
       ],
       "Resource": {
        "Fn::GetAtt": [
         "Queue",
         "Arn"
        ]
       },
       "Condition": {
        "ArnEquals": {
         "aws:SourceArn": {
          "Ref": "SNSTopicARN"
         }
        }
       }
      }
     ]
    },
    "Queues" : [
     {
      "Ref" : "Queue"
     }
    ]
   }
  },
  "SnsSubscription": {
   "Type": "AWS::SNS::Subscription",
   "Properties": {
    "Protocol": "sqs",
    "Endpoint": {
     "Fn::GetAtt": [
      "Queue",
      "Arn"
     ]
    },
    "Region": {
     "Ref": "TopicRegion"
    },
    "TopicArn": {
     "Ref": "SNSTopicARN"
    }
   }
  }
 }
}

YAML:

Parameters:
 SNSTopicARN:
  Type: String
  Default: awsSNSTopicArn
 TopicRegion:
  Type: String
  Default: us-east-1
Resources:
 Queue:
  Type: AWS::SQS::Queue
 SqsQueuePolicy:
  Type: AWS::SQS::QueuePolicy
  Properties:
   PolicyDocument:
    Version: '2012-10-17'
    Id: MyQueuePolicy
    Statement:
    - Sid: Allow-SNS-SendMessage
     Effect: Allow
     Principal: "*"
     Action:
     - sqs:SendMessage
     Resource: !GetAtt Queue.Arn
     Condition:
      ArnEquals:
       aws:SourceArn: !Ref SNSTopicARN
   Queues:
    - !Ref Queue
 SnsSubscription:
  Type: AWS::SNS::Subscription
  Properties:
   Protocol: sqs
   Endpoint: !GetAtt Queue.Arn
   Region: !Ref TopicRegion
   TopicArn: !Ref SNSTopicARN

这篇文章对您有帮助吗?

我们可以改进什么?


需要更多帮助吗?