Skip to content

Commit

Permalink
Merge pull request #18 from gunnargrosch/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
gunnargrosch authored Oct 25, 2020
2 parents 6489ac3 + 81ab22b commit 1e548cd
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 18 deletions.
42 changes: 38 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

## Description

`failure-lambda` is a small Node module for injecting failure into AWS Lambda (https://aws.amazon.com/lambda). It offers a simple failure injection wrapper for your Lambda handler where you then can choose to inject failure by setting the `failureMode` to `latency`, `exception`, `denylist`, `diskspace` or `statuscode`. You control your failure injection using SSM Parameter Store.
`failure-lambda` is a small Node module for injecting failure into AWS Lambda (https://aws.amazon.com/lambda). It offers a simple failure injection wrapper for your Lambda handler where you then can choose to inject failure by setting the `failureMode` to `latency`, `exception`, `denylist`, `diskspace` or `statuscode`. You control your failure injection using SSM Parameter Store or [AWS AppConfig](https://docs.aws.amazon.com/appconfig/latest/userguide/what-is-appconfig.html).

## How to install
## How to install with parameter in SSM Parameter Store

1. Install `failure-lambda` module using NPM.
```bash
Expand All @@ -28,11 +28,40 @@ exports.handler = failureLambda(async (event, context) => {
aws ssm put-parameter --region eu-west-1 --name failureLambdaConfig --type String --overwrite --value "{\"isEnabled\": false, \"failureMode\": \"latency\", \"rate\": 1, \"minLatency\": 100, \"maxLatency\": 400, \"exceptionMsg\": \"Exception message!\", \"statusCode\": 404, \"diskSpace\": 100, \"denylist\": [\"s3.*.amazonaws.com\", \"dynamodb.*.amazonaws.com\"]}"
```
5. Add an environment variable to your Lambda function with the key FAILURE_INJECTION_PARAM and the value set to the name of your parameter in SSM Parameter Store.
6. Try it out!
6. Add permissions to the parameter for your Lambda function.
7. Try it out!

## How to install with hosted configuration in AWS AppConfig

1. Install `failure-lambda` module using NPM.
```bash
npm install failure-lambda
```
2. Add the module to your Lambda function code.
```js
const failureLambda = require('failure-lambda')
```
3. Wrap your handler.
```js
exports.handler = failureLambda(async (event, context) => {
...
})
```
4. Create Application, Environment, Configuration Profile, and Hosted Configuration in AppConfig console.
5. Deploy a version of the configuration.
6. Add the AWS AppConfig layer for Lambda extensions to your Lambda function. [See details](https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-integration-lambda-extensions.html).
7. Add environment variables to your Lambda function.
```bash
FAILURE_APPCONFIG_APPLICATION: YOUR APPCONFIG APPLICATION
FAILURE_APPCONFIG_ENVIRONMENT: YOUR APPCONFIG ENVIRONMENT
FAILURE_APPCONFIG_CONFIGURATION: YOUR APPCONFIG CONFIGURATION PROFILE
```
8. Add permissions to the AppConfig Application, Environment, and Configuration Profile for your Lambda function.
9. Try it out!

## Usage

Edit the values of your parameter in SSM Parameter Store to use the failure injection module.
Edit the values of your parameter in SSM Parameter Store or hosted configuration in AWS AppConfig to use the failure injection module.

* `isEnabled: true` means that failure is injected into your Lambda function.
* `isEnabled: false` means that the failure injection module is disabled and no failure is injected.
Expand All @@ -58,6 +87,11 @@ Inspired by Yan Cui's articles on latency injection for AWS Lambda (https://hack

## Changelog

### 2020-10-25 v0.4.0

* Added optional support for AWS AppConfig, allowing to validate failure configuration, deploy configuration using gradual or non-gradual deploy strategy, monitor deployed configuration with automatical rollback if CloudWatch Alarms is configured, and caching of configuration.
* Hardcoded default configuration with `isEnabled: false`, to use if issues loading configuration from Parameter Store or AppConfig.

### 2020-10-21 v0.3.1

* Change mitm mode back to connect to fix issue with all connections being blocked.
Expand Down
42 changes: 31 additions & 11 deletions lib/failure.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,46 @@
'use strict'
const aws = require('aws-sdk')
const ssm = new aws.SSM()
const fetch = require('node-fetch')
const childProcess = require('child_process')
const Mitm = require('mitm')

async function getConfig() {
try {
let params = {
Name: process.env.FAILURE_INJECTION_PARAM
async function getConfig () {
const defaults = {
isEnabled: false
}
if (process.env.FAILURE_APPCONFIG_CONFIGURATION) {
try {
const url = 'http://localhost:2772/applications/' + process.env.FAILURE_APPCONFIG_APPLICATION + '/environments/' + process.env.FAILURE_APPCONFIG_ENVIRONMENT + '/configurations/' + process.env.FAILURE_APPCONFIG_CONFIGURATION
const response = await fetch(url)
const json = await response.json()
return json
} catch (err) {
console.error(err)
return defaults
}
} else if (process.env.FAILURE_INJECTION_PARAM) {
try {
let params = {
Name: process.env.FAILURE_INJECTION_PARAM
}
let response = await ssm.getParameter(params).promise()
let json = JSON.parse(response.Parameter.Value)
return json
} catch (err) {
console.error(err)
return defaults
}
let request = await ssm.getParameter(params).promise()
return request.Parameter.Value
} catch (err) {
console.error(err)
throw err
} else {
return defaults
}
}
var injectFailure = function (fn) {
return async function () {
try {
let configResponse = await getConfig()
let config = JSON.parse(configResponse)
// let configResponse = await getConfig()
// let config = JSON.parse(configResponse)
let config = await getConfig()
if (config.isEnabled === true && Math.random() < config.rate) {
if (config.failureMode === 'latency') {
let latencyRange = config.maxLatency - config.minLatency
Expand Down
7 changes: 6 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "failure-lambda",
"version": "0.3.1",
"version": "0.4.0",
"description": "Module for failure injection into AWS Lambda",
"main": "./lib/failure.js",
"scripts": {
Expand Down Expand Up @@ -34,6 +34,7 @@
"eslint-plugin-standard": "^4.0.1"
},
"dependencies": {
"mitm": "^1.7.1"
"mitm": "^1.7.1",
"node-fetch": "^2.6.1"
}
}

0 comments on commit 1e548cd

Please sign in to comment.