AWS CloudFormation에서 Amazon SQS 대기열과 Amazon SNS 주제 간에 구독을 생성하려면 어떻게 해야 합니까?
최종 업데이트 날짜: 2021년 5월 6일
AWS CloudFormation에서 Amazon SQS(Amazon Simple Queue Service) 대기열과 Amazon SNS(Amazon Simple Notification Service) 주제 간에 구독을 생성하고 싶습니다.
해결 방법
사용 사례에 따라 다음 해결 방법 중 하나를 선택합니다.
- SNS 주제와 SQS 대기열이 동일한 스택에 있습니다. 이 문제를 해결하려면 CloudFormation 템플릿을 사용하여 SQS 대기열로 메시지를 보내는 주제를 생성합니다.
- SNS 주제가 한 스택에 있고 해당 SNS 주제를 구독하는 SQS 대기열이 동일한 AWS 리전의 다른 스택에 있습니다. 이 문제를 해결하려면 교차 스택 참조를 생성합니다.
참고: 교차 스택 참조를 생성할 때에는 한 스택에 있는 SQS 대기열의 Amazon 리소스 이름(ARN)을 내보냅니다. 그런 다음 다른 스택에 있는 SNS 주제의 구독 엔드포인트 속성에서 SQS 대기열 ARN을 가져옵니다. - SNS 주제와 SQS 대기열이 서로 다른 리전에 있습니다. 이 문제를 해결하려면 AWS::SNS::Subscription 리소스를 사용하여 교차 리전 구독 설정 섹션의 단계를 따릅니다.
- SNS 주제와 SQS 대기열이 서로 다른 AWS 계정에 있습니다. 이 문제를 해결하려면 AWS::SNS::Subscription 리소스를 사용하여 교차 계정 구독 설정 섹션의 단계를 따릅니다.
AWS::SNS::Subscription 리소스를 사용하여 교차 리전 구독 설정
1. 한 AWS 리전의 스택에 대한 CloudFormation 템플릿에서 해당 리전의 SNS 주제를 선언합니다. 그런 다음 출력 리소스를 생성하여 SNS 주제 ARN에 주석을 답니다.
다음의 JSON 및 YAML 예제 템플릿을 참조하세요.
JSON:
{
"Resources": {
"SnsTopic": {
"Type": "AWS::SNS::Topic"
}
},
"Outputs": {
"SnsTopicArn": {
"Value": {
"Ref": "SnsTopic"
}
}
}
}
YAML:
Resources:
SnsTopic:
Type: AWS::SNS::Topic
Outputs:
SnsTopicArn:
Value: !Ref SnsTopic
2. 다른 리전의 다른 스택에 대한 CloudFormation 템플릿에서 AWS::SNS::Subscription 리소스와 SQS 대기열을 정의합니다.
참고: Parameters에서 awsSNSTopicArnExample은 SNS 주제 ARN으로 대체하세요. us-east-1은 1단계의 스택 리전으로 대체하세요.
다음의 JSON 및 YAML 예제 템플릿을 참조하세요.
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
이제 교차 리전 구독이 설정되었습니다.
AWS::SNS::Subscription 리소스를 사용하여 교차 계정 구독 설정
1. 하나의 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 계정의 스택에 대한 CloudFormation 템플릿에서 AWS::SNS::Subscription 리소스를 정의합니다. 또한 SQS 대기열 및 AWS::SQS::QueuePolicy 정책을 정의합니다.
참고: Parameters에서 awsSNSTopicArn은 SNS 주제 ARN으로 대체하세요. us-east-1은 1단계의 스택 리전으로 대체하세요.
다음의 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