Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Lambdas for Slack Notifications
const fetch = require('./fetch')
const RED = '#cd3131'
const YELLOW = '#e5e512'
const GREEN = '#05bc79'
const BLUE = '#2472c8'
exports.handler = async function(event, context) {
// Debugging
// console.log('event', JSON.stringify(event, null, 2))
// console.log('context', JSON.stringify(context, null, 2))
const record = event.Records[0]
const text = record.Sns.Subject
const color = RED
const footer = 'https://console.aws.amazon.com/cloudwatch/home'
const body = { attachments: [{ text, color, footer }] }
await fetch(process.env.SLACK_WEBHOOK_URL, {
method: 'post',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' },
})
context.succeed()
}
/*
Want to know when ECS events happen in Slack? Try this.
(1) Create a new Slack app with an incoming webhook, save the webhook URL
(2) Create an SNS topic called something like ECSEvents
(3) Create a CloudWatch Rule that publishes all ECS events to the topic
(4) Create a Node.js Lambda that is triggered by the SNS topic
(5) Add a WEBHOOK_URL environment variable to the Lambda with the webhook URL
(6) Paste this code into index.js
(7) Paste the contents of https://unpkg.com/node-fetch/lib/index.js into fetch.js
(8) Deploy and enjoy
*/
const fetch = require('./fetch')
const RED = '#cd3131'
const YELLOW = '#e5e512'
const GREEN = '#05bc79'
const BLUE = '#2472c8'
exports.handler = async(event) => {
for (const record of event.Records) {
const msg = JSON.parse(record.Sns.Message)
// console.log(JSON.stringify(msg)) // For debugging
const d = msg.detail
let title = msg['detail-type']
let color, text, body, footer
if (title === "ECS Deployment State Change") {
const env = msg.resources ? msg.resources[0].match(/:service\/(.+)/)[1] : msg.resources[1]
text = `[${env}] ECS ${d.eventName}`
color = /COMPLETED/.test(d.eventName) ? GREEN : YELLOW
} else if (title === "ECS Task State Change") {
color = /DELETED|STOPPED/.test(d.lastStatus) ? RED :
/RUNNING/.test(d.lastStatus) ? GREEN :
YELLOW
// Stuff to ignore to make this less noisy
if (color === YELLOW) return
if (/Scaling activity/.test(d.stoppedReason)) return
const env = d.clusterArn.replace(/^.*\//, '') + '/' + d.group.replace(/^.*:/, '')
const status = d.lastStatus + (d.desiredStatus !== d.lastStatus ? ` (desired: ${d.desiredStatus})` : '')
const taskDef = d.taskDefinitionArn.replace(/^.*\//, '')
const taskId = d.taskArn.replace(/^.*\//, '')
text = `[${env}] ECS Task ${d.lastStatus} ${taskDef}`
footer = `Task ID ${taskId}`
if (d.stoppedReason) text += ' - ' + d.stoppedReason
} else {
return
}
body = { attachments: [{ text, color, footer }] }
// console.log(JSON.stringify(body)) // Debugging
await fetch(process.env.SLACK_WEBHOOK_URL, {
method: 'post',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' },
})
}
};
const zlib = require('zlib')
const fetch = require('./fetch') // https://unpkg.com/node-fetch@2.6.1/lib/index.js
const { promisify } = require('util')
const gunzip = promisify(zlib.gunzip)
exports.handler = async function(input, context) {
const data = JSON.parse((await gunzip(Buffer.from(input.awslogs.data, 'base64'))).toString('utf8'))
const body = { attachments: data.logEvents.map(e => ({ text: e.message, footer: data.logGroup })) }
// console.log(JSON.stringify(body)) // Debugging
await fetch(process.env.SLACK_WEBHOOK_URL, {
method: 'post',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' },
})
context.succeed()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment