Created
April 6, 2018 09:13
-
-
Save momota10/25aa53315a3a54ad422168373526a92f to your computer and use it in GitHub Desktop.
sns topicに飛んで来たCloudWatchのalarmをslackに通知するためのlambda function
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
### 前提 | |
- slack webhookはstore parameterに保管している | |
- アラートの重要度ごとにhookを作る | |
- SEVERITYとCOLORをlambdaの環境変数に設定する | |
*/ | |
const url = require('url'); | |
const https = require('https'); | |
const AWS = require('aws-sdk'); | |
const severity = process.env.SEVERITY; | |
const color = process.env.COLOR; | |
let hookUrl; | |
exports.handler = (event, context, callback) => { | |
const ssm = new AWS.SSM(); | |
var params = { | |
Name: "/slack-" + severity, | |
WithDecryption: true | |
}; | |
ssm.getParameter(params, function(err, data) { | |
if (err) { | |
console.log("fail getParameter.", err, err.stack); | |
callback(null); | |
} else { | |
hookUrl = data.Parameter['Value']; | |
processEvent(event, callback); | |
} | |
}); | |
}; | |
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 env = AWSEnv(message.AWSAccountId); | |
const alarmName = message.AlarmName; | |
const newState = message.NewStateValue; | |
const reason = message.NewStateReason; | |
const time = message.StateChangeTime; | |
const slackMessage = { | |
'username': 'Alert Notifier', | |
'attachments': [{ | |
'pretext': alarmName + "* state is now `" + newState + "` ", | |
'color': color, | |
'title': 'See CloudWatch Logs', | |
'title_link': 'https://******.console.aws.amazon.com/cloudwatch/home', | |
'fields': [ | |
{ | |
'title': 'Environment', | |
'value': env, | |
'short': true | |
}, | |
{ | |
'title': 'Reason', | |
'value': reason, | |
'short': true, | |
}, | |
{ | |
'title': 'Alarm Name', | |
'value': alarmName, | |
'short': true | |
}, | |
{ | |
'title': 'Time', | |
'value': time, | |
'short': true, | |
} | |
]}] | |
}; | |
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}`); | |
} | |
}); | |
} | |
function AWSEnv(AWSAccountId) { | |
if (AWSAccountId == "*******") { | |
return "development"; | |
} else { | |
return "production"; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment