【问题标题】:Cannot create SQS subscription to an SNS topic through Cloudformation in LocalStack无法通过 LocalStack 中的 Cloudformation 创建对 SNS 主题的 SQS 订阅
【发布时间】:2019-08-03 01:43:34
【问题描述】:

使用localstack 我正在尝试创建一个执行以下操作的模板:

  1. 创建一个 SNS 主题
  2. 创建 SQS 队列
  3. 创建一个订阅,将 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

我的init.sh 文件如下所示:

#!/bin/bash
aws cloudformation create-stack --stack-name fincorestack --template-body file:///usr/stuff/formation.yml --endpoint-url=http://localstack:4581

最后我的 Cloudformation 文件如下所示:

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 Internal Server Error。由于这是localstack,而且我知道arns 是相当静态的,因此我尝试将订阅TopcArnEndpointyml 文件的内容替换为以下内容:

TopicArn: arn:aws:sns:eu-west-2:123456789012:MySnsTopic
Endpoint: arn:aws:sqs:elasticmq:000000000000:MySqsQueue

这一次我没有收到错误消息,但没有创建订阅。从localstack 的调试输出中我可以看到:

并且未创建订阅。 localstackCloudformation 实现不支持此功能还是我做错了什么?

【问题讨论】:

    标签: amazon-cloudformation amazon-sns localstack


    【解决方案1】:

    在 cli 中使用 docker 和 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"
        }
    }
    

    订阅队列到主题:

    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
    

    回复:

    {
        "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"
            }
        ]
    }
    

    【讨论】:

      【解决方案2】:

      此问题现已修复:https://github.com/localstack/localstack/issues/1191

      虽然TopcArnEndpoint 仍然需要硬编码。

      【讨论】:

        【解决方案3】:

        找到了解决方法,因此发布以防其他人需要。我感觉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(请参阅here)。好烦啊……

        【讨论】:

          【解决方案4】:

          我认为QueueArn 不是AWS::SQS::Queue 的属性,应该只是Arn

          【讨论】:

          • 我认为你是对的,所以 +1 虽然我仍然有问题现在已经解决(见答案)。
          猜你喜欢
          • 1970-01-01
          • 2021-02-20
          • 2021-11-25
          • 2021-11-14
          • 2019-04-11
          • 2021-03-25
          • 2019-07-02
          • 2020-11-28
          • 1970-01-01
          相关资源
          最近更新 更多