Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
This is a sample of AWS Lambda function that notifies CodeBuild Notification (only state changes) to Slack via Amazon SNS.
import json
import traceback
from datetime import datetime, timezone, timedelta
from urllib.request import Request, urlopen
SLACK_WEBHOOK_URL = '<your-slack-incomming-webhook-url>'
SLACK_CHANNEL = '<your-slack-channel>'
TEST_EVENT_FILE = './sample__CodeBuild.json'
def lambda_handler(event, context):
try:
main(event, context)
except Exception as e:
print(traceback.format_exc())
def main(event, context=None):
event_message = str(event['Records'][0]['Sns']['Message'])
event_message_json = json.loads(event_message)
optimezed_info = optimize_notification_info(event_message_json)
post_to_slack_with_attachment(optimezed_info)
def load_test_event():
with open(TEST_EVENT_FILE) as f:
test_event = json.load(f)
return {
'Records': [
{
'Sns': {
'Message': json.dumps(test_event)
}
}
]
}
def optimize_notification_info(event):
ts = int(datetime.fromisoformat(
event['time'].replace('Z', '')).strftime('%s'))
color = '#cfd8dc'
if event['detail']['build-status'] == 'SUCCEEDED':
color = '#76ff03'
elif event['detail']['build-status'] == 'STOPPED':
color = '#ffeb3b'
elif event['detail']['build-status'] == 'FAILED':
color = '#d50000'
attachments = [
{
'title': event['detailType'],
'color': color,
'ts': ts,
'fields': [
{
'title': 'project-name',
'value': '`{}`'.format(event['detail']['project-name'])
},
{
'title': 'build-status',
'value': '`{}`'.format(event['detail']['build-status'])
},
{
'title': 'build-id',
'value': '`{}`'.format(event['detail']['build-id'])
}
]
}
]
# not succeeded phases
if event['detail']['build-status'] != 'IN_PROGRESS':
not_succeeded_phases_info = get_not_succeeded_phase_info(
event['detail']['additional-information']['phases'])
if not_succeeded_phases_info != '':
attachments[0]['fields'].append(
{
'title': 'NOT-SUCCEEDED-phases',
'value': '```\n{}\n```'.format(not_succeeded_phases_info)
}
)
# CloudWatch Logs link
if 'deep-link' in event['detail']['additional-information']['logs'] and 'group-name' in event['detail']['additional-information']['logs']:
attachments[0]['fields'].append(
{
'title': 'logs',
'value': '<{deep_link}|{group_name}:{stream_name}>'.format(
deep_link=event['detail']['additional-information']['logs']['deep-link'],
group_name=event['detail']['additional-information']['logs']['group-name'],
stream_name=event['detail']['additional-information']['logs']['stream-name']
)
}
)
return attachments
def get_not_succeeded_phase_info(phases):
info = ''
for phase in phases:
if 'phase-status' in phase and phase['phase-status'] != 'SUCCEEDED':
if info != '':
info += '\n'
info += '- {type}\n\tstatus: {status}\n\tcontext: "{context}"'.format(
type=phase['phase-type'],
status=phase['phase-status'],
context=', '.join(phase['phase-context'])
)
return info
def post_to_slack_with_attachment(attachment):
post_data = {
'username': 'CodeBuild Notification',
'attachments': attachment,
'channel': SLACK_CHANNEL
}
headers = {'Content-Type': 'application/json'}
data = json.dumps(post_data).encode('utf-8')
request = Request(SLACK_WEBHOOK_URL, data=data, headers=headers)
urlopen(request)
if __name__ == '__main__':
event = load_test_event()
main(event)
{
"account": "999999999999",
"detailType": "SampleProject Build State Change",
"region": "ap-northeast-1",
"source": "aws.codebuild",
"time": "2019-11-11T05:05:05Z",
"notificationRuleArn": "arn:aws:codestar-notifications:ap-northeast-1:999999999999:notificationrule/b5bd8303-f06f-466e-a0a1-XXXXXXXXXXXX",
"detail": {
"build-status": "SUCCEEDED",
"project-name": "SampleProjectBuild",
"build-id": "arn:aws:codebuild:ap-northeast-1:999999999999:build/SampleProjectBuild:408c5476-c8c0-4aa9-a81b-XXXXXXXXXXXX",
"additional-information": {
"cache": {
"type": "NO_CACHE"
},
"timeout-in-minutes": 60,
"build-complete": true,
"initiator": "INITIATOR",
"build-start-time": "Nov 11, 2019 5:03:42 AM",
"source": {
"location": "location-link",
"type": "GITHUB"
},
"artifact": {
"location": ""
},
"environment": {
"image": "aws/codebuild/amazonlinux2-x86_64-standard:1.0",
"privileged-mode": false,
"image-pull-credentials-type": "CODEBUILD",
"compute-type": "BUILD_GENERAL1_SMALL",
"type": "LINUX_CONTAINER",
"environment-variables": []
},
"logs": {
"group-name": "/aws/codebuild/SampleProjectBuild",
"stream-name": "408c5476-c8c0-4aa9-a81b-XXXXXXXXXXXX",
"deep-link": "https://console.aws.amazon.com/cloudwatch/home?region=ap-northeast-1#logEvent:group=/aws/codebuild/SampleProjectBuild;stream=408c5476-c8c0-4aa9-a81b-XXXXXXXXXXXX"
},
"phases": [
{
"phase-context": [],
"start-time": "Nov 11, 2019 5:03:42 AM",
"end-time": "Nov 11, 2019 5:03:42 AM",
"duration-in-seconds": 0,
"phase-type": "SUBMITTED",
"phase-status": "SUCCEEDED"
},
{
"phase-context": [],
"start-time": "Nov 11, 2019 5:03:42 AM",
"end-time": "Nov 11, 2019 5:03:44 AM",
"duration-in-seconds": 1,
"phase-type": "QUEUED",
"phase-status": "SUCCEEDED"
},
{
"phase-context": [
": "
],
"start-time": "Nov 11, 2019 5:03:44 AM",
"end-time": "Nov 11, 2019 5:03:59 AM",
"duration-in-seconds": 15,
"phase-type": "PROVISIONING",
"phase-status": "SUCCEEDED"
},
{
"phase-context": [
": "
],
"start-time": "Nov 11, 2019 5:03:59 AM",
"end-time": "Nov 11, 2019 5:04:02 AM",
"duration-in-seconds": 2,
"phase-type": "DOWNLOAD_SOURCE",
"phase-status": "SUCCEEDED"
},
{
"phase-context": [
": "
],
"start-time": "Nov 11, 2019 5:04:02 AM",
"end-time": "Nov 11, 2019 5:04:35 AM",
"duration-in-seconds": 33,
"phase-type": "INSTALL",
"phase-status": "SUCCEEDED"
},
{
"phase-context": [
": "
],
"start-time": "Nov 11, 2019 5:04:35 AM",
"end-time": "Nov 11, 2019 5:04:35 AM",
"duration-in-seconds": 0,
"phase-type": "PRE_BUILD",
"phase-status": "SUCCEEDED"
},
{
"phase-context": [
": "
],
"start-time": "Nov 11, 2019 5:04:35 AM",
"end-time": "Nov 11, 2019 5:04:53 AM",
"duration-in-seconds": 17,
"phase-type": "BUILD",
"phase-status": "SUCCEEDED"
},
{
"phase-context": [
": "
],
"start-time": "Nov 11, 2019 5:04:53 AM",
"end-time": "Nov 11, 2019 5:05:01 AM",
"duration-in-seconds": 8,
"phase-type": "POST_BUILD",
"phase-status": "SUCCEEDED"
},
{
"phase-context": [
": "
],
"start-time": "Nov 11, 2019 5:05:01 AM",
"end-time": "Nov 11, 2019 5:05:01 AM",
"duration-in-seconds": 0,
"phase-type": "UPLOAD_ARTIFACTS",
"phase-status": "SUCCEEDED"
},
{
"phase-context": [
": "
],
"start-time": "Nov 11, 2019 5:05:01 AM",
"end-time": "Nov 11, 2019 5:05:03 AM",
"duration-in-seconds": 2,
"phase-type": "FINALIZING",
"phase-status": "SUCCEEDED"
},
{
"start-time": "Nov 11, 2019 5:05:03 AM",
"phase-type": "COMPLETED"
}
],
"queued-timeout-in-minutes": 480
},
"current-phase": "COMPLETED",
"current-phase-context": "[: ]",
"version": "1"
},
"resources": [
"arn:aws:codebuild:ap-northeast-1:999999999999:build/SampleProjectBuild:408c5476-c8c0-4aa9-a81b-XXXXXXXXXXXX"
],
"additionalAttributes": {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.