Amazon cloudformation 无法通过LocalStack中的Cloudformation创建对SNS主题的SQS订阅
我正在使用localstack创建一个模板,该模板执行以下操作:Amazon cloudformation 无法通过LocalStack中的Cloudformation创建对SNS主题的SQS订阅,amazon-cloudformation,amazon-sns,localstack,Amazon Cloudformation,Amazon Sns,Localstack,我正在使用localstack创建一个模板,该模板执行以下操作: TopicArn: arn:aws:sns:eu-west-2:123456789012:MySnsTopic Endpoint: arn:aws:sqs:elasticmq:000000000000:MySqsQueue 创建一个SNS主题 创建一个SQS队列 创建将SQS队列订阅到SNS主题的订阅。 我的docker compose文件如下所示: version: '3' services: localstack:
TopicArn: arn:aws:sns:eu-west-2:123456789012:MySnsTopic
Endpoint: arn:aws:sqs:elasticmq:000000000000:MySqsQueue
创建一个SNS主题
创建一个SQS队列
创建将SQS队列订阅到SNS主题的订阅。
我的docker compose文件如下所示:
version: '3'
services:
localstack:
image: localstack/localstack
container_name: localstack
environment:
- SERVICES=sns,sqs,cloudformation
- DEBUG=1
- PORT_WEB_UI=${PORT_WEB_UI- }
- HOSTNAME=localstack
- AWS_DEFAULT_REGION=eu-west-2
- AWS_ACCESS_KEY_ID=XX
- AWS_SECRET_ACCESS_KEY=XX
ports:
- "4575:4575"
- "4576:4576"
- "4581:4581"
- "8080:8080"
volumes:
- ./config/formation.yml:/usr/stuff/formation.yml
- ./config/init.sh:/docker-entrypoint-initaws.d/init.sh
#!/bin/bash
aws cloudformation create-stack --stack-name fincorestack --template-body file:///usr/stuff/formation.yml --endpoint-url=http://localstack:4581
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Test'
Resources:
MySnsTopic:
Type: AWS::SNS::Topic
Properties:
TopicName: MySnsTopic
MySnsTopicSubscription:
Type: AWS::SNS::Subscription
Properties:
Protocol: sqs
TopicArn: !Ref MySnsTopic
Endpoint: !GetAtt
- MySqsQueue
- QueueArn
MySqsQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: MySqsQueue
我的init.sh文件如下所示:
version: '3'
services:
localstack:
image: localstack/localstack
container_name: localstack
environment:
- SERVICES=sns,sqs,cloudformation
- DEBUG=1
- PORT_WEB_UI=${PORT_WEB_UI- }
- HOSTNAME=localstack
- AWS_DEFAULT_REGION=eu-west-2
- AWS_ACCESS_KEY_ID=XX
- AWS_SECRET_ACCESS_KEY=XX
ports:
- "4575:4575"
- "4576:4576"
- "4581:4581"
- "8080:8080"
volumes:
- ./config/formation.yml:/usr/stuff/formation.yml
- ./config/init.sh:/docker-entrypoint-initaws.d/init.sh
#!/bin/bash
aws cloudformation create-stack --stack-name fincorestack --template-body file:///usr/stuff/formation.yml --endpoint-url=http://localstack:4581
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Test'
Resources:
MySnsTopic:
Type: AWS::SNS::Topic
Properties:
TopicName: MySnsTopic
MySnsTopicSubscription:
Type: AWS::SNS::Subscription
Properties:
Protocol: sqs
TopicArn: !Ref MySnsTopic
Endpoint: !GetAtt
- MySqsQueue
- QueueArn
MySqsQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: MySqsQueue
最后,我的Cloudformation文件如下所示:
version: '3'
services:
localstack:
image: localstack/localstack
container_name: localstack
environment:
- SERVICES=sns,sqs,cloudformation
- DEBUG=1
- PORT_WEB_UI=${PORT_WEB_UI- }
- HOSTNAME=localstack
- AWS_DEFAULT_REGION=eu-west-2
- AWS_ACCESS_KEY_ID=XX
- AWS_SECRET_ACCESS_KEY=XX
ports:
- "4575:4575"
- "4576:4576"
- "4581:4581"
- "8080:8080"
volumes:
- ./config/formation.yml:/usr/stuff/formation.yml
- ./config/init.sh:/docker-entrypoint-initaws.d/init.sh
#!/bin/bash
aws cloudformation create-stack --stack-name fincorestack --template-body file:///usr/stuff/formation.yml --endpoint-url=http://localstack:4581
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Test'
Resources:
MySnsTopic:
Type: AWS::SNS::Topic
Properties:
TopicName: MySnsTopic
MySnsTopicSubscription:
Type: AWS::SNS::Subscription
Properties:
Protocol: sqs
TopicArn: !Ref MySnsTopic
Endpoint: !GetAtt
- MySqsQueue
- QueueArn
MySqsQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: MySqsQueue
这会产生一个非常模糊的500内部服务器错误。由于这是localstack,而且我知道ARN是静态的,所以我尝试用以下内容替换订阅TopcArn和Endpoint的yml文件的内容:
TopicArn: arn:aws:sns:eu-west-2:123456789012:MySnsTopic
Endpoint: arn:aws:sqs:elasticmq:000000000000:MySqsQueue
这一次我没有收到错误,但是没有创建订阅。从localstack的调试输出中,我可以看到:
并且未创建订阅。localstack的Cloudformation实现不支持此功能,还是我做错了什么 我认为QueueArn不是AWS::SQS::Queue的一个属性,它应该是Arn。我认为QueueArn不是AWS::SQS::Queue的一个属性,它应该是Arn。找到了一个解决方法,以便在其他人需要时发布。我觉得localstack不支持将订阅创建为资源,所以我在定义SNS主题资源时创建了订阅。将yml文件更改为以下格式可以实现此目的:
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Test'
Resources:
MySqsQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: MySqsQueue
MySqsQueue:
Type: AWS::SNS::Topic
Properties:
TopicName: MySqsQueue
Subscription:
- Protocol: sqs
Endpoint:
"Fn::GetAtt": ["MySqsQueue", "Arn"]
RawMessageDelivery: 'true'
编辑:
不幸的是,以这种方式创建订阅不允许设置属性。在我的情况下,我需要RawMessageDelivery=true,这是不受支持的,请参阅。很烦人…找到了一个解决办法,以便在其他人需要时发布。我觉得localstack不支持将订阅创建为资源,所以我在定义SNS主题资源时创建了订阅。将yml文件更改为以下格式可以实现此目的:
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Test'
Resources:
MySqsQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: MySqsQueue
MySqsQueue:
Type: AWS::SNS::Topic
Properties:
TopicName: MySqsQueue
Subscription:
- Protocol: sqs
Endpoint:
"Fn::GetAtt": ["MySqsQueue", "Arn"]
RawMessageDelivery: 'true'
编辑:
不幸的是,以这种方式创建订阅不允许设置属性。在我的情况下,我需要RawMessageDelivery=true,这是不受支持的,请参阅。相当烦人…这一问题现已得到解决:
尽管TopcArn和Endpoint仍然需要硬编码。这一问题现已得到解决:
尽管TopcArn和Endpoint仍然需要硬编码。在客户端使用docker和localstack 启动localstack 创建主题:
AWS_ACCESS_KEY_ID=x AWS_SECRET_ACCESS_KEY=x aws --endpoint-url=http://dc-localstack:4566 --region us-east-1 sns create-topic --name jensTopic`
答复:
{
"SubscriptionArn": "arn:aws:sns:us-east-1:000000000000:jensTopic:9bf7628e-ee36-49c1-8216-ed5cf5aea1ed"
}
创建队列:
AWS_ACCESS_KEY_ID=x AWS_SECRET_ACCESS_KEY=x aws --endpoint=http://dc-localstack:4566 --region us-east-1 sqs create-queue --queue-name jensQueue
获取队列arn属性:
AWS_ACCESS_KEY_ID=x AWS_SECRET_ACCESS_KEY=x aws --endpoint-url=http://dc-localstack:4566 --region us-east-1 sqs get-queue-attributes --queue-url http://localhost:4566/queue/jensQueue --attribute-names QueueArn
答复:
{
"Attributes": {
"QueueArn": "arn:aws:sqs:us-east-1:000000000000:jensQueue"
}
}
{
"Subscriptions": [
{
"SubscriptionArn": "arn:aws:sns:us-east-1:000000000000:jensTopic:9bf7628e-ee36-49c1-8216-ed5cf5aea1ed",
"Owner": "",
"Protocol": "sqs",
"Endpoint": "arn:aws:sqs:us-east-1:000000000000:jensQueue",
"TopicArn": "arn:aws:sns:us-east-1:000000000000:jensTopic"
}
]
}
订阅主题队列:
AWS_ACCESS_KEY_ID=x AWS_SECRET_ACCESS_KEY=x aws --endpoint-url=http://dc-localstack:4566 --region us-east-1 sns subscribe --topic-arn "arn:aws:sns:us-east-1:000000000000:jensTopic" --protocol sqs --notification-endpoint "arn:aws:sqs:us-east-1:000000000000:jensQueue"
健全性检查:
AWS_ACCESS_KEY_ID=x AWS_SECRET_ACCESS_KEY=x aws --endpoint-url=http://dc-localstack:4566 --region us-east-1 sns list-subscriptions
答复:
{
"Attributes": {
"QueueArn": "arn:aws:sqs:us-east-1:000000000000:jensQueue"
}
}
{
"Subscriptions": [
{
"SubscriptionArn": "arn:aws:sns:us-east-1:000000000000:jensTopic:9bf7628e-ee36-49c1-8216-ed5cf5aea1ed",
"Owner": "",
"Protocol": "sqs",
"Endpoint": "arn:aws:sqs:us-east-1:000000000000:jensQueue",
"TopicArn": "arn:aws:sns:us-east-1:000000000000:jensTopic"
}
]
}
在cli中将docker与localstack一起使用 启动localstack 创建主题:
AWS_ACCESS_KEY_ID=x AWS_SECRET_ACCESS_KEY=x aws --endpoint-url=http://dc-localstack:4566 --region us-east-1 sns create-topic --name jensTopic`
答复:
{
"SubscriptionArn": "arn:aws:sns:us-east-1:000000000000:jensTopic:9bf7628e-ee36-49c1-8216-ed5cf5aea1ed"
}
创建队列:
AWS_ACCESS_KEY_ID=x AWS_SECRET_ACCESS_KEY=x aws --endpoint=http://dc-localstack:4566 --region us-east-1 sqs create-queue --queue-name jensQueue
获取队列arn属性:
AWS_ACCESS_KEY_ID=x AWS_SECRET_ACCESS_KEY=x aws --endpoint-url=http://dc-localstack:4566 --region us-east-1 sqs get-queue-attributes --queue-url http://localhost:4566/queue/jensQueue --attribute-names QueueArn
答复:
{
"Attributes": {
"QueueArn": "arn:aws:sqs:us-east-1:000000000000:jensQueue"
}
}
{
"Subscriptions": [
{
"SubscriptionArn": "arn:aws:sns:us-east-1:000000000000:jensTopic:9bf7628e-ee36-49c1-8216-ed5cf5aea1ed",
"Owner": "",
"Protocol": "sqs",
"Endpoint": "arn:aws:sqs:us-east-1:000000000000:jensQueue",
"TopicArn": "arn:aws:sns:us-east-1:000000000000:jensTopic"
}
]
}
订阅主题队列:
AWS_ACCESS_KEY_ID=x AWS_SECRET_ACCESS_KEY=x aws --endpoint-url=http://dc-localstack:4566 --region us-east-1 sns subscribe --topic-arn "arn:aws:sns:us-east-1:000000000000:jensTopic" --protocol sqs --notification-endpoint "arn:aws:sqs:us-east-1:000000000000:jensQueue"
健全性检查:
AWS_ACCESS_KEY_ID=x AWS_SECRET_ACCESS_KEY=x aws --endpoint-url=http://dc-localstack:4566 --region us-east-1 sns list-subscriptions
答复:
{
"Attributes": {
"QueueArn": "arn:aws:sqs:us-east-1:000000000000:jensQueue"
}
}
{
"Subscriptions": [
{
"SubscriptionArn": "arn:aws:sns:us-east-1:000000000000:jensTopic:9bf7628e-ee36-49c1-8216-ed5cf5aea1ed",
"Owner": "",
"Protocol": "sqs",
"Endpoint": "arn:aws:sqs:us-east-1:000000000000:jensQueue",
"TopicArn": "arn:aws:sns:us-east-1:000000000000:jensTopic"
}
]
}
我认为你是正确的,所以+1,尽管我仍然有现在已经解决的问题,请参见答案。我认为你是正确的,所以+1,尽管我仍然有现在已经解决的问题,请参见答案。