Skip to content

Commit

Permalink
Initial release. (#1)
Browse files Browse the repository at this point in the history
Signed-off-by: Brandon Bodnar <bbodnar@asymmetrik.com>
  • Loading branch information
bodnarbm committed Dec 8, 2016
1 parent e8c5660 commit b861a85
Show file tree
Hide file tree
Showing 36 changed files with 2,925 additions and 2 deletions.
47 changes: 47 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Logs
logs
*.log
npm-debug.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules
jspm_packages

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity
92 changes: 90 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,90 @@
# yadda
Yet Another Docker Deployment Application
yadda
=====
(Yet Another Docker Deployment Application)

`yadda` is a command line tool for managing deploying a collection of
microservices to AWS EC2 Container Service using a declarative syntax. Create a
Manifest file (and associated environment files) declaring your services and
jobs (one-time or periodic task), and `yadda` will handle building the required
docker images, pushing them to your AWS Elastic Container Registry, creating
the associated services and task definitions in ECS, and running periodic tasks
on a schedule.

**Warning: Use of yadda will result in creating resources in AWS for which you
bear the cost.**

Getting Started
================

Install
--------

`yadda` is installable via npm under the `asymmetrik` namespace.

$ npm install -g @asymmetrik/yadda

Deployment Center
-----------------

To operate, `yadda` first must install a deployment center that handles the
deployment history of your application (enabling the `rollback` feature) and
is responsible for running the jobs defined in your Manifest files.

To create the deployment center, run the following after installing `yadda`

$ yadda create-deployment-center --region <AWS_REGION> <DEPLOYMENT_CENTER_NAME>

replacing `<AWS_REGION>` with the region you want the deployment center
installed in and `<DEPLOYMENT_CENTER_NAME>` with the name you want to give this
deployment center.

A single deployment center can be used to manage deployments across multiple
AWS Regions (including managing deployments on ECS clusters outside of the
region where the Deployment Center is installed).

Additionally, a single deployment center can handle managing multiple different
applications.

Manifest Files
--------------

`yadda` needs certain information to manage the deployments. This information is
stored in a Manifest file for a given App and specific environment files for
each deployment environment.

`yadda` expects these files to be within the root directory of your App,
inside a folder named `deployment`. An example folder structure is provided
below.

MyApp
|- deployment
|- Manifest.js
|- env
|- production.js
|- staging.js
|- dev.js

To create a skeleton for the required files, run

$ yadda init

which will create the deployment folder and skeleton files in the current
working directory.

You can find an full example under the `example` directory in this
repo. The example files will show the required information for configuring your
application.

The schema for the Manifest files can be found under `/config/manifest.js`.

Deploying your application
--------------------------

After creating your Deployment Center and Manifest, you can deploy the
application via

$ yadda deploy <environment>

replacing `<environment>` with the name of the environment you want to deploy to
(for example, `yadda deploy staging` to deploy to the environment defined in
`deployment/env/staging.js`).
29 changes: 29 additions & 0 deletions cli/commands/build-push.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use strict';

var Q = require('q');
var _ = require('lodash');

var config = require('../../config');
var logger = config.logger;

var cliHelpers = require('../helpers');
var deploymentTasks = require('../../lib/deployment-tasks');

module.exports = function(program) {
program.command('build-push')
.arguments('<environment>')
.description('build and push based on the Dockerfile in the provided path')
.option('-f, --file <manifest file>', 'Deployment manifest file to use for this deployment')
.option('--tag <tag>', 'Image tag')
.action(function(environment) {
var runtimeOptions = this.opts();
runtimeOptions.environment = environment;
Q.when(runtimeOptions)
.then(cliHelpers.setup(cliHelpers.promptForMissingOptions))
.then(cliHelpers.lint)
.then(deploymentTasks.buildPush)
.catch(function (err) {
logger.error(err.message);
});
});
};
29 changes: 29 additions & 0 deletions cli/commands/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use strict';

var Q = require('q');
var _ = require('lodash');

var config = require('../../config');
var logger = config.logger;

var cliHelpers = require('../helpers');
var deploymentTasks = require('../../lib/deployment-tasks');

module.exports = function(program) {
program.command('build')
.arguments('<environment>')
.description('build based on the Dockerfile in the provided path')
.option('-f, --file <manifest file>', 'Deployment manifest file to use for this deployment')
.option('--tag <tag>', 'Image tag')
.action(function(environment) {
var runtimeOptions = this.opts();
runtimeOptions.environment = environment;
Q.when(runtimeOptions)
.then(cliHelpers.setup(cliHelpers.promptForMissingOptions))
.then(cliHelpers.lint)
.then(deploymentTasks.build)
.catch(function (err) {
logger.error(err.message);
});
});
};
43 changes: 43 additions & 0 deletions cli/commands/create-deployment-center.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use strict';

var Q = require('q');
var _ = require('lodash');

var config = require('../../config');
var logger = config.logger;

var cliHelpers = require('../helpers');
var deploymentTasks = require('../../lib/deployment-tasks');

var deploymentCenter = require('../../deployment-center');

module.exports = function(program) {
program.command('create-deployment-center')
.arguments('<name>')
.description('creates a deployment center with the given name')
.option('--region <aws-region>', 'AWS Region to create the deployment center resources in')
.action(function(name) {

var region = this.region;

if(!region) {
logger.error('A region for the deployment center must be specified');
this.help();
}

deploymentCenter.createDeploymentCenter(region, name)
.then(function(result) {
logger.info('Deployment Center Created');
logger.info('Please use the following information for your deployment manifests');
logger.info({
DeploymentCenter: {
name: name,
region: region
}
});
})
.catch(function(err) {
logger.error(err);
});
});
};
34 changes: 34 additions & 0 deletions cli/commands/deploy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use strict';

var Q = require('q');
var _ = require('lodash');

var config = require('../../config');
var logger = config.logger;

var cliHelpers = require('../helpers');
var deploymentTasks = require('../../lib/deployment-tasks');

function list(value) {
return value.split(',');
}

module.exports = function(program) {
program.command('deploy')
.arguments('<environment>')
.description('Deploy to ECS. Builds new docker image, pushes the image to ECR, creates a new Task Definition and updates the Service to use the new task definition')
.option('-f, --file <manifest file>', 'Deployment manifest file to use for this deployment')
.option('--tag <tag>', 'Image tag')
.option('--update-only <services/jobs>', 'Only updates the provided command seperated list of services and/or jobs.', list)
.action(function(environment) {
var runtimeOptions = this.opts();
runtimeOptions.environment = environment;
Q.when(runtimeOptions)
.then(cliHelpers.setup(cliHelpers.promptForMissingOptions))
.then(cliHelpers.lint)
.then(deploymentTasks.deploy)
.catch(function (err) {
logger.error(err.message);
});
});
};
28 changes: 28 additions & 0 deletions cli/commands/init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict';

var Q = require('q');
var _ = require('lodash');

var fs = require('fs');
var path = require('path');
var ncp = require('ncp');

var config = require('../../config');
var logger = config.logger;

var cliHelpers = require('../helpers');

module.exports = function(program) {
program.command('init')
.description('creates a skeleton deployment manifest and environments in the current directory')
.action(function() {
var exampleDeploymentDirectory = path.resolve(__dirname + '/../../example/deployment');
ncp(exampleDeploymentDirectory, process.cwd() + '/deployment', function(err) {
if (err) {
logger.error(err);
} else {
logger.info('Deployment Files created. Please modify the files for your project before deploying');
}
});
});
};
25 changes: 25 additions & 0 deletions cli/commands/lint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use strict';

var Q = require('q');
var _ = require('lodash');

var config = require('../../config');
var logger = config.logger;

var cliHelpers = require('../helpers');

module.exports = function(program) {
program.command('lint')
.arguments('<environment>')
.description('lint the combined manifest and environment file for required settings')
.action(function(environment) {
var runtimeOptions = this.opts();
runtimeOptions.environment = environment;
Q.when(runtimeOptions)
.then(cliHelpers.setup())
.then(cliHelpers.lint)
.catch(function(err) {
logger.error(err.message);
});
});
};
33 changes: 33 additions & 0 deletions cli/commands/list-jobs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use strict';

var Q = require('q');
var _ = require('lodash');

var config = require('../../config');
var logger = config.logger;

var cliHelpers = require('../helpers');
var deploymentTasks = require('../../lib/deployment-tasks');

module.exports = function(program) {
program.command('list-jobs')
.arguments('<environment>')
.description('List all jobs defined in the Manifest for this environment')
.action(function(environment) {
var runtimeOptions = this.opts();
runtimeOptions.environment = environment;
Q.when(runtimeOptions)
.then(cliHelpers.setup())
.then(cliHelpers.lint)
.then(deploymentTasks.listJobs)
.then(function(jobs) {
logger.info('All jobs:');
_.each(jobs, function(job) {
logger.info('\t-', job);
});
})
.catch(function (err) {
logger.error(err.message);
});
});
};
Loading

0 comments on commit b861a85

Please sign in to comment.