Using SNS Service Integration from API Gateway
Introduction
This is a tutorial on setting up AWS API GW to talk to SNS. The code below is in Powershell. You should verify your setup from the console as you follow along.
References
Create SNS Topic
Nothing fancy. Just regular topic. Keep the ARN handy
Create IAM Role
Create a new IAM Role with following properties. Keep this ARN handy.
- Permission Policy
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "sns:Publish" ], "Resource": "arn:aws:sns:us-east-1:999999999999:delete_me_hyon" } ] } - Trust Policy
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "apigateway.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }API GW
Create REST API
You can also verify via console here:

Create a Resource
Create a resource under root called my_ingest
$INGEST_RESOURCE_ID = aws apigateway create-resource `
--rest-api-id $API_ID `
--parent-id $ROOT_RESOURCE_ID `
--path-part my_ingest `
--output text `
--query 'id' `
--region $REGION

Create a method
Create a method
aws apigateway put-method `
--rest-api-id $API_ID `
--resource-id $INGEST_RESOURCE_ID `
--http-method POST `
--authorization-type NONE `
--region $REGION

Put integration
$requesttemplates = '{\"application/json\":' + '\"Action=Publish&TopicArn=$util.urlEncode(''' + $SNS_TOPIC_ARN + ''')&Message=$util.urlEncode($input.body)\"}'
aws apigateway put-integration `
--rest-api-id $API_ID `
--resource-id $INGEST_RESOURCE_ID `
--http-method POST `
--type AWS `
--integration-http-method POST `
--uri "arn:aws:apigateway:${REGION}:sns:path//" `
--credentials $ROLE_ARN `
--request-parameters '{\"integration.request.header.Content-Type\" : \"''application/x-www-form-urlencoded''\"}' `
--request-templates $requesttemplates `
--passthrough-behavior NEVER
Expected Output:
{
"type": "AWS",
"httpMethod": "POST",
"uri": "arn:aws:apigateway:us-east-1:sns:path//",
"credentials": "arn:aws:iam::999999999999:role/delete_me_hyon",
"requestParameters": {
"integration.request.header.Content-Type": "'application/x-www-form-urlencoded'"
},
"requestTemplates": {
"application/json": "Action=Publish&TopicArn=$util.urlEncode('arn:aws:sns:us-east-1:999999999999:delete_me_hyon')&Message=$util.urlEncode($input.body)"
},
"passthroughBehavior": "NEVER",
"timeoutInMillis": 29000,
"cacheNamespace": "cvevrl",
"cacheKeyParameters": []
}

Put integration Response
aws apigateway put-integration-response `
--rest-api-id $API_ID `
--resource-id $INGEST_RESOURCE_ID `
--http-method POST `
--status-code 200 `
--response-templates '{\"application/json\": \"{''body'': ''Message received.''}\"}'
Expected Output:
{
"statusCode": "200",
"selectionPattern": "\"\"",
"responseTemplates": {
"application/json": "{'body': 'Message received.'}"
}
}

Put Method Response
aws apigateway put-method-response `
--rest-api-id $API_ID `
--resource-id $INGEST_RESOURCE_ID `
--http-method POST `
--status-code 200 `
--response-models '{\"application/json\": \"Empty\" }'
Expected Output:
{
"statusCode": "200",
"responseModels": {
"application/json": "Empty"
}
}

Deploy it
aws apigateway create-deployment --rest-api-id $API_ID --stage-name prod
Expected Output:
{
"id": "55n8z8",
"createdDate": "2022-02-06T15:29:21-06:00"
}

Test it
- Click here to test

- Expected Output
