Skip to content

Commit

Permalink
Add example project
Browse files Browse the repository at this point in the history
Add example project showcasing the plugin usage
  • Loading branch information
davidgf committed Feb 28, 2018
1 parent 5d96aed commit 621afee
Show file tree
Hide file tree
Showing 7 changed files with 2,767 additions and 0 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
[![npm version](https://badge.fury.io/js/serverless-plugin-canary-deployments.svg)](https://badge.fury.io/js/serverless-plugin-canary-deployments)

# Serverless Plugin Canary Deployments

A Serverless plugin to implement canary deployments of Lambda functions, making use of the [traffic shifting feature](https://docs.aws.amazon.com/lambda/latest/dg/lambda-traffic-shifting-using-aliases.html) in combination with [AWS CodeDeploy](https://docs.aws.amazon.com/lambda/latest/dg/automating-updates-to-serverless-apps.html)
Expand Down Expand Up @@ -44,6 +46,8 @@ functions:
handler: hooks.post
```

You can see a working example in the [example folder](./example/).

## Configuration

* `type`: (required) defines how the traffic will be shifted between Lambda function versions. It must be one of the following:
Expand Down
44 changes: 44 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Serverless Plugin Canary Deployments Example

Let's see the plugin in action :smile: In this service example we'll create several resources:

* A Lambda function with an HTTP event where we'll test the gradual deploy
* A before and an after traffic shifting hooks
* An alarm that sets off if the Lambda function exits with error status

The function's deployment is configured so that it shifts a 10% of the traffic to the new version every minute, as long as the alarm status is OK.

## Usage

First, we need to set up the service and deploy it in our AWS account:

```console
$ npm i
$ sls deploy -s dev
```

When you call your newly created endpoint, you should see the following message:

```console
$ curl https://yourendpoint.com/dev/hello
{"message":"First version"}
```

To check how traffic is shifted gradually, modify `handler.js` and deploy your service again. You'll see that the output varies accross endpoint calls.

```console
$ sls deploy -s dev
$ curl https://yourendpoint.com/dev/hello
{"message":"First version"}
$ curl https://yourendpoint.com/dev/hello
{"message":"Second version"}
```

If we wanted to check how our deployment rolls back to the previous version, we need to set off the alarm. Calling the endpoint with `error` as a query parameter will cause the function with error status.

```console
$ curl https://yourendpoint.com/dev/hello?error=true
{"message": "Internal server error"}
```

As soon as the alarm turns to `ALARM` state, all the traffic will be shifted to the previous version. You can check progress of the deployment in the [CodeDeploy console](https://console.aws.amazon.com/codedeploy/home).
12 changes: 12 additions & 0 deletions example/handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict';

module.exports.hello = (event, context, callback) => {
if ((event.queryStringParameters || {}).error) callback(new Error('Oh no!'));
const response = {
statusCode: 200,
body: JSON.stringify({
message: 'First version',
})
};
return callback(null, response);
};
36 changes: 36 additions & 0 deletions example/hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const aws = require('aws-sdk');
const codedeploy = new aws.CodeDeploy({apiVersion: '2014-10-06'});

module.exports.pre = (event, context, callback) => {
var deploymentId = event.DeploymentId;
var lifecycleEventHookExecutionId = event.LifecycleEventHookExecutionId;

console.log('Check some stuff before shifting traffic...');

var params = {
deploymentId: deploymentId,
lifecycleEventHookExecutionId: lifecycleEventHookExecutionId,
status: 'Succeeded' // status can be 'Succeeded' or 'Failed'
};

return codedeploy.putLifecycleEventHookExecutionStatus(params).promise()
.then(data => callback(null, 'Validation test succeeded'))
.catch(err => callback('Validation test failed'));
};

module.exports.post = (event, context, callback) => {
var deploymentId = event.DeploymentId;
var lifecycleEventHookExecutionId = event.LifecycleEventHookExecutionId;

console.log('Check some stuff after shifting traffic...');

var params = {
deploymentId: deploymentId,
lifecycleEventHookExecutionId: lifecycleEventHookExecutionId,
status: 'Succeeded' // status can be 'Succeeded' or 'Failed'
};

return codedeploy.putLifecycleEventHookExecutionStatus(params).promise()
.then(data => callback(null, 'Validation test succeeded'))
.catch(err => callback('Validation test failed'));
};
Loading

0 comments on commit 621afee

Please sign in to comment.