AWS SNS Messaging layer for Tulip Apps

Sometimes you might want to send email messages to users who aren’t registered in your instance. Actually, there are a lot of things you can do with SNS topics.

Using some simple services from AWS you can build a simple messaging layer.

Let’s create a Unit test App to manage the SNS topics.

To do so, lets create a quick lambda that can create topics.

import json
import boto3
import logging
import os

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
runtime_region = os.environ['AWS_REGION']

sns = boto3.client('sns')

def lambda_handler(event, context):
    
    print(event)
    topic = event["topic"]
    try:
        topic = sns.create_topic(Name=topic)
        logger.info("Created topic %s with ARN %s.", topic, topic['TopicArn'])

    except:
        logger.exception("Couldn't create topic %s.", topic)
    else:
        return topic

Attach a policy to allow the lambda to create topics. I wanted to limit the account to altering topics that start with TULIP-

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "sns:DeleteTopic",
                "sns:CreateTopic",
                "sns:SetTopicAttributes"
            ],
            "Resource": "arn:aws:sns:*:AWSACCOUNT:TULIP-*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "sns:ListTopics",
            "Resource": "*"
        }
    ]
}

I like to trigger lambda’s from Aurora Postgres, so create an IAM policy to allow it.

Now make a postgres function to call the lambda.

CREATE OR REPLACE FUNCTION globalstructure.create_sns_topic(topic text)
 RETURNS text
 LANGUAGE plpgsql
AS $function$
            declare

            create_json TEXT;
            response TEXT;
            err_context text;
            _topicarn text;
            
			begin
            RAISE INFO 'Started';	  
            
            select
                into
                create_json row_to_json(t)
            from
                (
                select
                topic
                ) t;
                
            SELECT into response payload FROM aws_lambda.invoke(aws_commons.create_lambda_function_arn('tulip-create-sns-topic', 'us-east-1'),
            create_json::json,'RequestResponse'
            );

            RAISE INFO 'response:%',response;
           
            select into _topicarn response::json->'TopicArn';
            select into _topicarn replace(_topicarn,'"','');
            
           	RAISE INFO 'response:%  ',_topicarn;
           
            return _topicarn;

            EXCEPTION 
                WHEN others THEN    
                    GET STACKED DIAGNOSTICS err_context = PG_EXCEPTION_CONTEXT;
                    RAISE INFO 'Error Name:%',SQLERRM;
                    RAISE INFO 'Error State:%', SQLSTATE;
                    RAISE INFO 'Error Context:%', err_context;
                    return null;
            END;
            $function$
;

Then finally, call the postgres function from a tulip connector

Wash, rinse and repeat for other functions to

  1. List SNS topics (useful to show what possible topics are available)
  2. Subscribe to an SNS Topic (it sends an email that the user clicks to verify the subscription)
  3. Publish to an SNS Topic

2 Likes