1

I have created a CF script that creates an EC2 instance that contains a web service. It also creates an SNS Topic and a Subscription that uses this web service as it's http endpoint.

The script successfully creates the stack; the Topic and the Subscription exist. However, the Subscription remains in the PendingConfirmation state.

What must I do to get my script to confirm this Subscription upon creation?

  • A better design would be for your application to subscribe when it starts. – kdgregory Feb 08 '18 at 14:12
  • 1
    It turns out the CloudFormation script for the creation of the Subscription was OK, it was the endpoint server that hadn't completely initialized by the time the Subscription attempt was made. This caused the Subscription to end up, and remain in an "Pending confirmation" state. This was due to the database not being ready in time, causing the web service call to time out. A simple DependsOn solved the timing conflict and hence was the solution to this issue. Thanks everyone for your answers! – erikdebruin Feb 19 '18 at 09:42

2 Answers2

1

I had a similar issue and my problem ended up being a misconfigured CloudFomation template. An AWS::SQS::QueuePolicy is required to give your SNS topic permission to send messages to the queue.

    "SQSQueuePolicy": {
        "Properties": {
            "PolicyDocument": {
                "Id": "usecase1",
                "Statement": [
                    {
                        "Action": "SQS:SendMessage",
                        "Condition": {
                            "ArnEquals": {
                                "aws:SourceArn": {
                                    "Ref": "SnsTopic"
                                }
                            }
                        },
                        "Effect": "Allow",
                        "Principal": {
                            "AWS": "*"
                        },
                        "Resource": {
                            "Fn::GetAtt": [
                                "SqsQueue",
                                "Arn"
                            ]
                        },
                        "Sid": "1"
                    }
                ],
                "Version": "2012-10-17"
            },
            "Queues": [
                {
                    "Ref": "SqsQueue"
                }
            ]
        },
        "Type": "AWS::SQS::QueuePolicy"
    }
Allie Fitter
  • 1,689
  • 14
  • 18
0

You need to Subscribe to endpoint for this to work.

Read the value for SubscribeURL and visit that URL. To confirm the subscription and start receiving notifications at the endpoint, you must visit the SubscribeURLURL (for example, by sending an HTTP GET request to the URL)

When you visit the URL, you will get back a response that looks like the following XML document. The document returns the subscription ARN for the endpoint within the ConfirmSubscriptionResult element.

<ConfirmSubscriptionResponse xmlns="http://sns.amazonaws.com/doc/2010-03-31/">
  <ConfirmSubscriptionResult>
    <SubscriptionArn>arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55</SubscriptionArn>
  </ConfirmSubscriptionResult>
  <ResponseMetadata>
    <RequestId>075ecce8-8dac-11e1-bf80-f781d96e9307</RequestId>
  </ResponseMetadata>
  </ConfirmSubscriptionResponse>

As an alternative to visiting the SubscribeURL, you can confirm the subscription using the ConfirmSubscription action with the Token set to its corresponding value in the SubscriptionConfirmation message. If you want to allow only the topic owner and subscription owner to be able to unsubscribe the endpoint, you call the ConfirmSubscription action with an AWS signature.

You can Refer to this AWS Documentation

Hope this Helps!

Community
  • 1
  • 1
Kush Vyas
  • 5,813
  • 2
  • 26
  • 36
  • Thank you for that detailed answer. Do you perhaps know how to achieve these actions using CloudFormation? – erikdebruin Feb 08 '18 at 13:45
  • You can use a CloudFormation custom resource for this, I'd imagine. It is a customisable Lambda function you can write, and you could pass it the SubscribeURL and then perform the ConfirmSubscription action using Boto within your lambda. – Joe Alamo Oct 03 '18 at 10:24