Setup Amazon SNS locally

Problem

You need to develop with using Amazon SNS, but you don´t have enough Budget. Or you want to impress your Boss by saving money.

Solution

Enter Localstack.

They provide mocks of Amazon Services like the Simple Notification Service (SNS).

Requirement

Installed Localstack

Installed awscli (pip install awscli)

Installed awslocal (https://github.com/localstack/awscli-local) (Optional, Recommended)

To use SNS with LocalStack you can start it via your command line or via docker-compose.

I will show you both options.

CLI (Commandline)

To start SNS via LocalStack, execute the following command (based on your OS):

Linux

SERVICES=sns localstack start --docker

Mac OS

SERVICES=sns TMPDIR=/private$TMPDIR localstack start --docker

Mac OS requires the additional pointer to the TMPDIR.

Docker-Compose

version: '2.1'

services:
  localstack:
    container_name: "${LOCALSTACK_DOCKER_NAME-localstack_main}"
    image: localstack/localstack
    network_mode: bridge
    ports:
      - "4566:4566"
    environment:
      - SERVICES=sns
      - DEBUG=${DEBUG- }
      - DOCKER_HOST=unix:///var/run/docker.sock
      - HOST_TMP_FOLDER=${TMPDIR}
    volumes:
      - "${TMPDIR:-/tmp/localstack}:/tmp/localstack"
      - "/var/run/docker.sock:/var/run/docker.sock"

This docker-compose.yaml from the LocalStack GitHub Repository

Run docker-compose up and you will be good to go.

Both

Either way you will have a LocalStack running locally that supports Amazon SNS.

If it´s the first time (or your cleaned up Docker) it might take a while to get the containers downloaded and running. Then you can get a coffee ;).

On following starts it should start almost instantly.

If you installed awslocal, you can verify that sns is up and running be executing awslocal sns list-topics. Without awslocal you need to execute aws --endpoint-url=http://localhost:4566 sns list-topics.

This is basically how to set it up.

Usage

To use Amazon SNS you need:

  • a topic
  • a subscription
  • a message send

Topic

A topic is like a channel in slack or irc. It´s where message will go. It is used for the routing, similar to a url (especially REST URLs).

That can be alphanumeric and needs to be unique (on your account/your installation).

To create a topic test1, you execute awslocal sns create-topic --name test1. (look a bit up if you don´t use awslocal).

To list all available topics run

 awslocal sns list-topics

Subscription

To receive messages you need to declare that you want to receive them and the target where you want to receive them. Think giving a woman your phone number.

To list all existing subscription topics:

awslocal sns list-subscriptions

Creating a subscription is a little bit more work. Usually you would do it in source code. But if you want to manually create a http subscription you run this:

awslocal sns subscribe --topic-arn arn:aws:sns:us-east-1:000000000000:test1  --protocol http --notification-endpoint http://localhost:3000/incoming

Replace arn:aws:sns:us-east-1:000000000000:test1 with the TopicArn that you received when you created the topic or when you list the available topics.

Note: Subscribing via the aws(local) tool will confirm the subscription.
Subscribe via source code requires an extra call to confirm.

Note: On Mac OS you need to use docker.for.mac.localhost instead of localhost when you are inside docker and need to access a process that runs in another container or directly on the host

Message

Last but not least you actually need to send a message which triggers the call.

You can do this by running this command (sending json data):

 awslocal sns publish --topic-arn arn:aws:sns:us-east-1:000000000000:test1  --message-structure json --message '{"default":{"greeting": "Hello World"}}'

Replace the arn arn:aws:sns:us-east-1:000000000000:test1 with the arn your topic uses.

The json formatted as string ‘{“default”:{“greeting”: “Hello World”}}’ is what we want to send. To send json the top level default is required. Under it your can send your data.

Note: If you want to send a JSON {“orderId”: 123456, “restaurantId”: “abc”} your call looks like this:

 awslocal sns publish --topic-arn arn:aws:sns:us-east-1:000000000000:test1  --message-structure json --message '{"default": {"orderId": 123456, "restaurantId": "abc"} }'

Removing a subscription

While you are experimenting to understand how everything works you probably want to remove a subscription.

To do that you run:

 awslocal sns unsubscribe --subscription-arn arn:aws:sns:us-east-1:000000000000:test1:3508cf40-5ab9-4317-bded-ff6a8d42e0b6

Replace arn:aws:sns:us-east-1:000000000000:test1:3508cf40-5ab9-4317-bded-ff6a8d42e0b6 with the arn of your subscription

Remove a topic

Last but not least you might want to remove a topic. To do that call:

awslocal sns delete-topic --topic-arn arn:aws:sns:us-east-1:000000000000:test1

Replace arn:aws:sns:us-east-1:000000000000:test1 with the arn of your topic.

And that´s it.

Now you know how to set up local Amazon SNS and how to use it on the command line.

Stay tuned for the article how to access it with NodeJS.

Let me know when it helped you.

Best,

Frank

Sources:

https://github.com/localstack/awscli-local

https://docs.aws.amazon.com/cli/latest/userguide/cli-services-sns.html

https://docs.aws.amazon.com/sns/latest/api/Welcome.html

https://dev.to/singhs020/getting-started-with-aws-sns-44b0

Leave a Reply