如何在 CloudFormation 中的 Amazon SQS 队列和 Amazon SNS 主题之间创建订阅?
我想在 AWS CloudFormation 中的 Amazon Simple Queue Service (Amazon SQS) 队列和 Amazon Simple Notification Service (Amazon SNS) 主题之间创建订阅。
解决方法
如果主题和队列在同一个堆栈中,则使用 CloudFormation 模板创建一个主题,向 SQS 队列发送消息。
如果主题在一个堆栈中而队列在另一个堆栈中,则创建跨堆栈引用。两个堆栈必须位于同一 AWS 区域。创建跨堆栈引用时,将 SQS 队列的 ARN 导出到一个堆栈中。然后,将 ARN 导入另一个堆栈中 SNS 主题的订阅端点属性中。
如果您的 SNS 主题和 SQS 队列位于不同的区域或 AWS 账户,则使用 AWS::SNS::Subscription 设置跨账户或跨区域订阅。
设置跨账户订阅
配置账户 A
在源堆栈的 CloudFormation 模板中,配置以下设置:
- 在参数下的描述中,输入目标账户 ID。
- 对于资源,声明 AWS::SNS::Topic 和 AWS::SNS::TopicPolicy。
- 创建 Outputs 部分以返回 SNS TopicArn。
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
配置账户 B
在目标堆栈的 CloudFormation 模板的资源中,声明 AWS::SNS::Subscription 资源、AWS::SQS::Queue 和 AWS::SQS::QueuePolicy。
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
注意:在前面的模板示例中的参数下,将 awsSNSTopicArn 替换为您的 SNS 主题 ARN。另外,将 us-east-1 替换为源账户(账户 A)中堆栈的区域。
设置跨区域订阅
配置区域 A
在一个区域的堆栈的 CloudFormation 模板中,配置以下设置:
- 对于资源,声明 AWS::SNS::Topic。
- 创建 Outputs 部分以返回 SnsTopicArn。
JSON 模板示例:
{ "Resources": { "SnsTopic": { "Type": "AWS::SNS::Topic" } }, "Outputs": { "SnsTopicArn": { "Value": { "Ref": "SnsTopic" } } } }
YAML 模板示例:
Resources: SnsTopic: Type: AWS::SNS::Topic Outputs: SnsTopicArn: Value: !Ref SnsTopic
配置区域 B
在其他区域堆栈的 CloudFormation 模板中,对于资源,声明 AWS::SNS::Subscription 资源和 AWS::SQS::Queue。
JSON 模板示例:
{ "Parameters": { "SNSTopicARN": { "Type": "String", "Default": "awsSNSTopicArnExample" }, "TopicRegion": { "Type": "String", "Default": "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 Default: awsSNSTopicArnExample TopicRegion: Type: String Default: 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
注意:在前面的模板示例中的参数下,将 awsSNSTopicArnExample 替换为您的 SNS 主题 ARN。另外,将 us-east-1 替换为区域 A 中堆栈的区域。

相关内容
- AWS 官方已更新 2 年前
- AWS 官方已更新 10 个月前
- AWS 官方已更新 3 年前