Package and Publish a Node site to AWS ElasticBeanstalk with Gulp

Say you are building a Node application which you want to host in AWS Elastic Beanstalk, but how do you automate this process?  I mean sure, you could just open up the AWS console and manually upload your files, but lets be honest that is a royal pain in the ass.  What we really want to do is setup some sort of automate to make everything easier.  In this post we are going to walk though how to use Gulp to a publish your code to AWS S3 and then consume the package in Elastic Beanstalk (EB).

In this post we are going to learn how to use Gulp to create, upload and deploy a Node application.  The flow will be as below

NodeToAWSEB

Before you get started I am going to make a few assumptions.

  1. You already know basic Gulp.js usage, if not details on this here
  2. You already have a React application, if not details on this here
  3. You already have an AWS account setup, if not details on this here
    • You will also need to make sure you have your CLI configured w/ credentials.  See here for details
  4. You already have a build npm task in your package.json file, if not look here
  5. You already have the EB CLI installed, if not look here

To get started, the first thing we are going to need to install a few NPM packages

npm install --save-dev aws-sdk gulp-run gulp-zip run-sequence

After you have the npm packages installed we will need to start working on your gulpfile.js changes.

Add the reference to the package we added

const run = require('gulp-run');
const zip = require('gulp-zip');
const AWS = require('aws-sdk');
const runSequence = require('run-sequence');

After we reference our packages we need to create an instance of the S3 object, this will be used to push the files into our S3 bucket.

const s3 = new AWS.S3({apiVersion: '2006-03-01'});

Now that we have all the prerequisite stuff out of the way, time to get down to business.

We are going to need to create 5 different tasks in our gulp file.

  1. deploy -> This will be used to kick off the entire process
  2. zip-build -> We want to zip our entire solution into a single file for pushing to S3 -> EB
  3. copy-to-bucket -> Will copy our zip file to S3 for store-and-forward to EB
  4. publish-version-to-eb -> Will create the actual version in EB for usage
  5. publish-environment-to-eb -> Will publish the provisioned version we created in the prior step
gulp.task('deploy', deployTest);

gulp.task('copy-to-bucket', copyToS3Bucket);
gulp.task('publish-version-to-eb', publishVersionToEB);
gulp.task('publish-environment-to-eb', publishEnvironmentToEB);
gulp.task('zip-build', zipBuild)

function copyToS3Bucket() {
    const options = s3Options.active;
    const packageNameAndLocation = "./deploy/deploymentPackageName.zip";
    const s3BucketPath = "s3://your-s3-bucket-name";
    
    return run("aws s3 cp " + packageNameAndLocation + " " + s3BucketPath ).exec();
}

function deploy(done) {
    runSequence('zip-build',
                'copy-to-bucket',
                'publish-version-to-eb',
                'publish-environment-to-eb',
                done);
}

function publishVersionToEB(){
    const createAppCommand = "aws elasticbeanstalk create-application-version --application-name application-name-from-eb --version-label deployment-version-label --source-bundle S3Bucket=your-bucket-name,S3Key=full-name-of-deploy-zip.zip";
    return run(createAppCommand).exec();
}

function publishEnvironmentToEB(){
    const updateEnvironmentCommand = "aws elasticbeanstalk update-environment --environment-name your-environemnt-name-in-eb --version-label your-version-name-just-created";
    return run(updateEnvironmentCommand).exec();
}

function zipBuild(){
    const options = s3Options.active;

    // when zipping the files we want to grab all files and sub folders
    // we want to omit our deploy and test files (no need for those in EB)
    return gulp.src(["./**/*.*",             
            "!./node_modules/**/*.*",
            "!./deploy/**/*.*",
            "!./test/**/*.*"
        ])
        .pipe(zip(options.deployPackageName))
        .pipe(gulp.dest("deploy"));

}

After you have implemented the changes above you can run gulp on the command line and watch the magic unfold.

gulp deploy

If you would like to see a full working copy of my gulpfile.js checkout this gist.

One thought on “Package and Publish a Node site to AWS ElasticBeanstalk with Gulp

  1. Pingback: Interesting links of the week (02/12 – 02/18, 2018) – same stuff, different day

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s