The AWS Command Line is awesome. The commands are descriptive, well organized and oftentimes easier to use than any of the dashboard consoles.
If you're looking or a simple NodeJS tool to help you to script and automate commands, try JakeJS.
JakeJS is a task management tool similar to Grunt or Gulp but that is inspired by Rake --that was derived from Make. Jake is fantastic for anyone coming from the Ruby on Rails community.
Jake Features
My favorite JakeJS features include:
- Prerequisites allow you to run checks before running a task.
- Namespaces help you organize your code into groups.
- Test tasks simplify testing.
- Daisy chaining allows you to run a task within other tasks.
Gettting Started
Install JakeJS
npm install jake --save-dev
Create a Jakefile.
touch Jakefile.js
Populate the Jakefile
with tasks. Example
Organizing mutiple files
You can organize your different scripts by creating file.jake
files and placing them inside of a /jakelib
folder. See example.
Examples
All of my examples below will first require you to create an AWS cli profile.
List your IAM users
var util = require('util');
//You might want to consider .env
var config = { profile: 'process.env.DOT_ENV_PROFILE' }
desc('List of Users.');
task('listUsers', { async: true }, function() {
var cmds = [ util.format('aws iam list-users --profile %s', config.profile) ];
jake.exec(cmds, { printStdout: true });
});
Zip a collection of Lambda files
This example shows you to how zip up a bunch of lambda functions.
var util = require('util');
namespace('app', function () {
desc('Archive app for upload.');
task('archive', { async: true }, function(config) {
//Itemize the files you're excluding then concatenate them
var excludes = [
//Hidden files (i.e. .gitignore, .env)
'-x .\*',
//NPM package file
'-x "package.json"',
//NPM Jakefile
'-x "Jakefile.js"',
//ReadMe notes
'-x \*.md',
//HTTP Request Simulator
'-x \*.paw',
//AWS Policy Files
'-x "aws_policies\*"',
//Jakefile tasks
'-x "jakelib\*"'
].join(" ")
var cmds = [
//Remove all node modules including -devDependencies
"rm -r node_modules",
//Only install the production-ready modules
"npm install --only=production",
//Recursively Zip everything with exception to anything within excludes
util.format('zip -r %s * %s', config.app, excludes)
];
//Set "printStdout" to "true" if you want to see the stack trace
jake.exec(cmds, { printStdout: false }, function(){
complete();
})
});
Common S3 Commands
I first create a file called /jakelib/aws.jake
. This file will be used as a pre-requisite check that I have an AWS Client profile created.
var util = require('util');
var AWS = require("aws-sdk");
var fs = require('fs');
namespace('aws', function () {
//TODO: Keep this AWS profile up-to-date.
var AWS_CREDENTIALS = {
profile: "sgm"
}
desc('Prerequisite to most jake tasks. This loads credentials in NodeJS.');
//http://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/loading-node-credentials-shared.html
task('loadCredentials', { async: true }, { breakOnError: true }, function() {
if(!AWS_CREDENTIALS.profile) fail("No awscli profile found within .env. Learn more: https://goo.gl/U2HiAs");
AWS.config.credentials = new AWS.SharedIniFileCredentials({ profile: AWS_CREDENTIALS.profile });
//console.log(AWS.config.credentials);
complete();
});
});
My second file is titled /jakelib/s3.jake
. This file will always check aws.jake
.
var util = require('util');
namespace('s3', function () {
var config = { profile: "aws_credentials_profile" }
desc('Create an S3 bucket.');
task('create', ['aws:loadCredentials'], { async: true }, function(bucket_name) {
var cmds = [ util.format('aws s3 mb %s --profile %s', bucket_name, config.profile) ];
jake.exec(cmds, { printStdout: true });
});
desc('Upload a file to an S3 bucket.');
task('upload', ['aws:loadCredentials'], { async: true }, function(bucket_name, file) {
var cmds = [ util.format('aws s3 cp /local/file/or/folder s3://%s --profile %s', bucket_name, config.profile) ];
jake.exec(cmds, { printStdout: true });
});
desc('List objects within a bucket.');
task('list', ['aws:loadCredentials'], { async: true }, function(bucket_name) {
var cmds = [ util.format('aws s3 ls s3://%s --profile %s', bucket_name, config.profile) ];
jake.exec(cmds, { printStdout: true });
});
});
Now all you need to do is run jake namespace:task[params]
.
jake s3:create[name_of_s3_bucket,awscli_profile_name]