A place to share technical learnings, etc.
aws | jekyll | github | apigateway | serverless | ad | powershell | windows | webdev | nodejs | terraform | consul | nomad | jenkins | traefik | azuread | azure | nextjs |
NOTE: This assumes that you already have a functional and tested CodeDeploy process built out, and a branch that you want to push with CodeDeploy (i.e. AddCodeDeploy in this example).
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "codedeploy:GetDeploymentConfig",
"Resource": "arn:aws:codedeploy:us-west-2:YOUR_ACCOUNT_ID:deploymentconfig:*"
},
{
"Effect": "Allow",
"Action": "codedeploy:RegisterApplicationRevision",
"Resource": "arn:aws:codedeploy:us-west-2:YOUR_ACCOUNT_ID:*"
},
{
"Effect": "Allow",
"Action": "codedeploy:GetApplicationRevision",
"Resource": "arn:aws:codedeploy:us-west-2:YOUR_ACCOUNT_ID:*"
},
{
"Effect": "Allow",
"Action": "codedeploy:CreateDeployment",
"Resource": "arn:aws:codedeploy:us-west-2:YOUR_ACCOUNT_ID:*"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:us-west-2:YOUR_ACCOUNT_ID:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:us-west-2:YOUR_ACCOUNT_ID:log-group:/aws/lambda/*"
]
},
{
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": [
"*"
]
}
]
}
The code. This will take a message from a Github webhook, and if it’s a commit from the branch “AddCodeDeploy”, it’ll kick off a build in AWS CodeDeploy.
exports.handler = (event, context, callback) => {
var AWS = require('aws-sdk');
var crypto = require('crypto');
//grab the Secret environment variable
var secret = process.env.Secret;
//hash the event.body - we'll use this to validate the message we got is really from Github
var hash = crypto.createHmac('sha1', secret).update(JSON.stringify(event.body));
//get the digest of the message from Github
var digest = 'sha1=' + hash.digest('hex');
//check to see that the digest and the header we got from Github match - indicating it's a legit message from Github
if (digest === event.headers["X-Hub-Signature"]) {
console.log("Legit message from Github.");
var codedeploy = new AWS.CodeDeploy({apiVersion: '2014-10-06'});
if (event.body.ref === 'refs/heads/AddCodeDeploy') {
console.log('Received a push on the AddCodeDeploy branch. Pushing a CodeDeploy deployment...');
var params = {
applicationName: 'MyCodeDeployApp',
autoRollbackConfiguration: {
enabled: false
},
deploymentGroupName: 'TEST',
revision: {
gitHubLocation: {
commitId: event.body.head_commit.id,
repository: 'myOrganization/MyApp'
},
revisionType: 'GitHub',
},
fileExistsBehavior: 'OVERWRITE'
}
codedeploy.createDeployment(params, function(err, data) {
if (err) {
console.log(err, err.stack); // an error occurred
} else {
console.log(data); // successful response
}
});
}
} else {
console.log("Dropping message - Potentially bogus message from Github");
}
//respond to the web request
callback();
};
By default, API Gateway does not pass headers to Lambda functions. We’ll want the headers passed in because we need that to validate the message we receive actually came from GitHub.
{
"method": "$context.httpMethod",
"body" : $input.json('$'),
"headers": {
#foreach($param in $input.params().header.keySet())
"$param": "$util.escapeJavaScript($input.params().header.get($param))"
#if($foreach.hasNext),#end
#end
}
}
At this point, our AWS code should be set up to receive webhook requests from Github. Let’s set up the Github Side of things.
At this point, you should be able to push a new commit to your AddCodeDeploy branch.
If everything worked correctly, you should see a new build triggered immediately in CodeDeploy! :D
tags: github - aws - apigateway - serverless