Skip to content

Instantly share code, notes, and snippets.

@carlochess
Created June 18, 2021 23:07
Show Gist options
  • Save carlochess/5524277d4565f636f33b71f8b44618d4 to your computer and use it in GitHub Desktop.
Save carlochess/5524277d4565f636f33b71f8b44618d4 to your computer and use it in GitHub Desktop.
AWS Listen for codepipeline events and triggers a lambda (slack notifier)
AWSTemplateFormatVersion: "2010-09-09"
Description: Pipeline
Parameters:
SsmSlackWebHookParam:
Type: String
Description: Slack web hook path from ssm parameter store
Default: "/DEVOPS/SLACKWEBHOOK"
Resources:
PipelineEventsRule:
Type: 'AWS::Events::Rule'
Properties:
Description: Test Events Rule
Name: pipelineevents
EventPattern:
source:
- "aws.codepipeline"
detail-type:
- "CodePipeline Pipeline Execution State Change"
State: ENABLED
Targets:
- Arn: !GetAtt "LambdaSlack.Arn"
Id: "TargetLambdaSlack"
PermissionForEventsToInvokeLambda:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref "LambdaSlack"
Action: "lambda:InvokeFunction"
Principal: "events.amazonaws.com"
SourceArn: !GetAtt "PipelineEventsRule.Arn"
LambdaSlack:
Type: 'AWS::Lambda::Function'
Properties:
Code:
ZipFile: |
const util = require("util");
const https = require('https');
const url = require('url');
var AWS = require('aws-sdk');
AWS.config.update({region: 'us-east-1'});
var ssm = new AWS.SSM();
let apiRequest = async (state, pipeline, execution_id, region) => {
const data = JSON.stringify({
text: `The pipeline <https://console.aws.amazon.com/codesuite/codepipeline/pipelines/${pipeline}/view?region=${region}|${pipeline}> has *${state}*. <https://console.aws.amazon.com/codesuite/codepipeline/pipelines/${pipeline}/executions/${execution_id}/timeline?region=${region}|Execution ID: ${execution_id}>`
})
var ssm_options = {
Name: process.env.SSM_SLACKWEBHOOK_PARAM,
WithDecryption: true
};
var url_param = await ssm.getParameter(ssm_options).promise();
const slack_url = url.parse(url_param["Parameter"]["Value"]);
const options = {
hostname: slack_url.hostname,
port: 443,
path: slack_url.pathname,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length
}
}
const req = https.request(options, (res) => {
console.log(`statusCode: ${res.statusCode}`)
res.on('data', (d) => {
process.stdout.write(d)
})
})
req.on('error', (error) => {
console.error(error)
})
req.write(data)
req.end()
}
apiRequest = util.promisify(apiRequest);
module.exports.handler = async (event, context, callback) => {
try {
console.log('event:', JSON.stringify(event));
const { state, pipeline } = event.detail;
const execution_id = event.detail['execution-id']
const region = event.region
const response = await apiRequest(state, pipeline, execution_id, region)
console.log("response:", JSON.stringify(response));
}catch(err){
console.log("error:", err)
}
}
Description: Send slack notifications
Handler: 'index.handler'
MemorySize: 128
Role: !GetAtt 'LambdaExecutionRole.Arn'
Runtime: 'nodejs12.x'
Timeout: 30
Environment:
Variables:
SSM_SLACKWEBHOOK_PARAM: !Ref 'SsmSlackWebHookParam'
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: LambdaSlackRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- 'lambda.amazonaws.com'
Action:
- 'sts:AssumeRole'
Path: /
Policies:
- PolicyName: LambdaLogs
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- !Join ["", ["arn:aws:logs:", Ref: "AWS::Region", ":", Ref: "AWS::AccountId", ":log-group:/aws/lambda/*"]]
- Effect: Allow
Action:
- ssm:GetParameter
Resource:
- !Join [ "", ["arn:aws:ssm:*:*:parameter", Ref: 'SsmSlackWebHookParam']]
- Effect: Allow
Action:
- kms:Decrypt
Resource:
- arn:aws:kms:*:*:key/aws/ssm
- Effect: Allow
Action:
- ssm:DescribeParameters
Resource:
- "*"
#!/bin/bash
set -xe
NAME_PROJECT=codepipeline-events
SSM_SLACKWEBHOOK_PARAM=/DEVOPS/SLACKWEBHOOK
# Check that /DEVOPS/SLACKWEBHOOK ssm parameter exists before deploying the cf stack
SLACKWEBHOOK=$(aws ssm get-parameter --region us-east-1 --name ${SSM_SLACKWEBHOOK_PARAM} --with-decryption --query Parameter.Value --output text)
aws cloudformation deploy \
--stack-name $NAME_PROJECT \
--template-file ./${NAME_PROJECT}.yaml \
--parameter-overrides \
SsmSlackWebHookParam=${SSM_SLACKWEBHOOK_PARAM} \
--capabilities CAPABILITY_IAM \
--capabilities CAPABILITY_NAMED_IAM
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment