Skip to content

Instantly share code, notes, and snippets.

@jacoyutorius
Last active June 21, 2017 00:51
Show Gist options
  • Select an option

  • Save jacoyutorius/ada74bf738efa4849cd2e2080bea5db9 to your computer and use it in GitHub Desktop.

Select an option

Save jacoyutorius/ada74bf738efa4849cd2e2080bea5db9 to your computer and use it in GitHub Desktop.
AWSLambdaSlackNotification
var event = {
"Records": [
{
"EventVersion": "1.0",
"EventSubscriptionArn": "arn:aws:sns:EXAMPLE",
"EventSource": "aws:sns",
"Sns": {
"SignatureVersion": "1",
"Timestamp": "1970-01-01T00:00:00.000Z",
"Signature": "EXAMPLE",
"SigningCertUrl": "EXAMPLE",
"MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e",
// "Message": "Hello from SNS!",
"Message": '{"configurationItemDiff":{"changedProperties":{},"changeType":"CREATE"},"configurationItem":{"relatedEvents":[],"relationships":[],"configuration":{"alarmName":"awsapplicationelb-app-SampleAppELB-4cfa0c9ece494773-High-HTTP-4XX","alarmArn":"arn:aws:cloudwatch:ap-northeast-1:916766174167:alarm:awsapplicationelb-app-SampleAppELB-4cfa0c9ece494773-High-HTTP-4XX","alarmDescription":"Created from EC2 Console","alarmConfigurationUpdatedTimestamp":1498004451605,"actionsEnabled":true,"alarmActions":["arn:aws:sns:ap-northeast-1:916766174167:config-topic"],"insufficientDataActions":[],"metricName":"HTTPCode_Target_4XX_Count","namespace":"AWS/ApplicationELB","statistic":"Average","dimensions":[{"name":"LoadBalancer","value":"app/SampleAppELB/4cfa0c9ece494773"}],"period":60,"evaluationPeriods":1,"threshold":10.0,"comparisonOperator":"GreaterThanOrEqualToThreshold","okactions":[]},"supplementaryConfiguration":{},"tags":{},"configurationItemVersion":"1.2","configurationItemCaptureTime":"2017-06-21T00:32:13.684Z","configurationStateId":1498005133684,"awsAccountId":"916766174167","configurationItemStatus":"ResourceDiscovered","resourceType":"AWS::CloudWatch::Alarm","resourceId":"awsapplicationelb-app-SampleAppELB-4cfa0c9ece494773-High-HTTP-4XX","resourceName":"awsapplicationelb-app-SampleAppELB-4cfa0c9ece494773-High-HTTP-4XX","ARN":"arn:aws:cloudwatch:ap-northeast-1:916766174167:alarm:awsapplicationelb-app-SampleAppELB-4cfa0c9ece494773-High-HTTP-4XX","awsRegion":"ap-northeast-1","availabilityZone":"Not Applicable","configurationStateMd5Hash":"","resourceCreationTime":null},"notificationCreationTime":"2017-06-21T00:32:13.879Z","messageType":"ConfigurationItemChangeNotification","recordVersion":"1.2"}',
"MessageAttributes": {
"Test": {
"Type": "String",
"Value": "TestString"
},
"TestBinary": {
"Type": "Binary",
"Value": "TestBinary"
}
},
"Type": "Notification",
"UnsubscribeUrl": "EXAMPLE",
"TopicArn": "arn:aws:sns:EXAMPLE",
"Subject": "TestInvoke"
}
}
]
};
var context = {};
var callback = function(err, data) {
return;
};
var myLambda = require('./lambda');
myLambda.handler(event, context, callback);
`use strict`
const AWS = require('aws-sdk');
const url = require('url');
const https = require('https');
// The base-64 encoded, encrypted key (CiphertextBlob) stored in the kmsEncryptedHookUrl environment variable
const kmsEncryptedHookUrl = process.env.kmsEncryptedHookUrl;
// The Slack channel to send a message to stored in the slackChannel environment variable
// const slackChannel = process.env.slackChannel;
const slackChannel = "fr_aws";
let hookUrl;
hookUrl="";
function postMessage(message, callback) {
const body = JSON.stringify(message);
const options = url.parse(hookUrl);
options.method = 'POST';
options.headers = {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(body),
};
const postReq = https.request(options, (res) => {
const chunks = [];
res.setEncoding('utf8');
res.on('data', (chunk) => chunks.push(chunk));
res.on('end', () => {
if (callback) {
callback({
body: chunks.join(''),
statusCode: res.statusCode,
statusMessage: res.statusMessage,
});
}
});
return res;
});
postReq.write(body);
postReq.end();
}
function processEvent(event, callback) {
const message = JSON.parse(event.Records[0].Sns.Message);
// const alarmName = message.AlarmName;
// var oldState = message.OldStateValue;
// const newState = message.NewStateValue;
// const reason = message.NewStateReason;
// const slackMessage = {
// channel: slackChannel,
// text: `${alarmName} state is now ${newState}: ${reason}`,
// };
// const message = event.Records[0].Sns.Message;
// const slackMessage = {
// channel: slackChannel,
// text: `${message}`
// };
const messageType = message.messageType;
var text = `messageType: ${messageType}\r\n`;
switch(messageType){
case "ConfigurationItemChangeNotification":
text += `Type:${message.configurationItemDiff.changeType}\r\n resourceName:${message.configurationItem.resourceName}`
break;
default:
break;
}
const slackMessage = {
channel: slackChannel,
text: `${text}`
};
postMessage(slackMessage, (response) => {
if (response.statusCode < 400) {
console.info('Message posted successfully');
callback(null);
} else if (response.statusCode < 500) {
console.error(`Error posting message to Slack API: ${response.statusCode} - ${response.statusMessage}`);
callback(null); // Don't retry because the error is due to a problem with the request
} else {
// Let Lambda retry
callback(`Server error when processing message: ${response.statusCode} - ${response.statusMessage}`);
}
});
}
exports.handler = (event, context, callback) => {
if (hookUrl) {
// Container reuse, simply process the event with the key in memory
processEvent(event, callback);
} else if (kmsEncryptedHookUrl && kmsEncryptedHookUrl !== '<kmsEncryptedHookUrl>') {
const encryptedBuf = new Buffer(kmsEncryptedHookUrl, 'base64');
const cipherText = { CiphertextBlob: encryptedBuf };
const kms = new AWS.KMS();
kms.decrypt(cipherText, (err, data) => {
if (err) {
console.log('Decrypt error:', err);
return callback(err);
}
hookUrl = `https://${data.Plaintext.toString('ascii')}`;
processEvent(event, callback);
});
} else {
callback('Hook URL has not been set.');
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment