AWS SNS and Slack Integration

Slack is an awesome tool. Rich set of integrations with AWS and popular APIs make IFTT use cases a breeze. I had recently integrated our JIRA installation to slack for production release notifications to create a timeline of releases plus prodops tasks.

Looking at AWS Lambda today i thought of integrating our production alerts into our Slack prodops channel. Amazon SNS has an HTTP payload that is not compatible with the Slack Webhooks so i needed a transformer in between.

Here is the node.js and AWS Lambda hello world. Select AWS Lamba function as a subscription in the SNS Topic and you are good to go.

Look Ma, no servers.

console.log('Loading function');
var https = require('https');
var async = require('async');

exports.handler = function(event, context) {
	event.Records.forEach(function(record) {
		var notification = record.Sns
		var postData = "payload=" + JSON.stringify({ 
				"text" : notification.TopicArn + ":" + notification.Subject +":" + notification.Timestamp + notification.Message
			});

		var options = {
			host: 'hooks.slack.com',
			path: 'SLACK API PATH',
			port: '443',
			method: 'POST',
			headers: {
				'Content-Type': 'application/x-www-form-urlencoded',
				'Content-Length': postData.length
			}
		};
		async.waterfall([
			function(next) {
				var req = https.get(options, function(res) {
					next(res);
				}).on('error', function(e) {
					console.log("Got error: ", e);
					next(e);
				});
				req.write(postData);
				req.end();
			},
			function completed(d) {
				console.log(d);
				context.succeed(event.MessageId);
			}
		]);
	});
};

AWS IAM : Too complicated for your own good

AWS IAM Framework is very flexible and extensible. But it defeats the purpose when you cannot figure out what permissions are required for an operations role like deployment using Beanstalk.

AWS introduced managed policies to ease the pain. “AWSElasticBeanstalkFullAccess” seems like you are giving beanstalk access to an ops guy but behind the scene you give all access and make him/her a power user.

{
    "Statement": [
        {
            "Action": [
                "elasticbeanstalk:*",
                "ec2:*",
                "elasticloadbalancing:*",
                "autoscaling:*",
                "cloudwatch:*",
                "s3:*",
                "sns:*",
                "cloudformation:*",
                "rds:*",
                "sqs:*",
                "iam:PassRole"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ],
    "Version": "2012-10-17"
}