6 min read

jj-ying-4XvAZN8 WHo-unsplash

Using AWS CodePipeline to Automate Deployments to ElasticBeanstalk


A hello world example using GitHub as a source

On our latest post we’ve learnt how to deploy a Node.js app to AWS ElasticBeanstalk using a single command on our console. Today we’ll move one step forward and create an automated deployment pipeline that will automatically detect any code pushes we do to our GitHub repo and will grab that code an generate a new build that will be deployed to our ElasticBeanstalk environment. For this purpose we’ll be using AWS CodePipeline, which is a service that wraps other services from AWS like CodeCommit, CodeBuild and CodeDeploy among others.

CodePipeline is a tool aiming to provide Continuous Integration and Delivery for your project. As stated on the AWS docs:

CodePipeline builds, tests, and deploys your code every time there is a code change, based on the release process models you define. This enables you to rapidly and reliably deliver features and updates.

In this post we will use the same application we deployed to ElasticBeanstalk in our previous post and automate it’s deployment.

Step 1: Source

Enough intro, let’s go to the CodePipeline console in your AWS account and hit the Get Started button. This will trigger the wizard to create a new pipeline. We’ll call our pipeline helloworld-pipeline :

When you hit next, you’ll be presented with the first step on the pipeline, which AWS calls “Source”. In this step we need to tell AWS how are we managing our code. There are a few options available, including Amazon CodeCommit, Amazon S3 and GitHub. We’ll go with the GitHub option, which once selected, will show us a “Connect to GitHub” button. Click that button and connect your GitHub account so that CodeBuild can access your repositories, you should see something like this in a new tab:

Hit the Authorize button and it will redirect you back to the pipeline creation page. Once you authorize AWS to access your Github account, you’ll be able to choose a repository and a branch from where you want to generate new builds. In our case we chose the codepipeline-helloworld repo and selected the master branch:

This means that whenever we merge a PR (or push directly to master), CodePipeline will trigger a new build. This works thanks to GitHub’s webhooks. We’re set for the Source step, time to click that “Next Step” button.

Step 2: Build

Now that AWS knows where our code is, we need to tell it how to create a build. The first thing we need to select here is a Build Provider. There are a few options, we’ll select AWS CodeBuild.

Then we need to select the AWS CodeBuild project we want to use. Since we don’t have one yet, we’ll create a new one and name it helloworld-build

Finally we need to choose the environment under which we want to build our code. You’re free to experiment and use a custom docker image for this. In this tutorial we will select an image managed by AWS CodeBuild with the following characteristics:

We used the same Node version we had on the Elastic Beanstalk instance we created on our previous post. For the build specification we will use the buildspec.yml option, so we need to write some code now. In your project root directory, create the file and put this inside:

version: 0.2

artifacts:
  files:
    - '**/*'

Quite simple, right? Well that’s because we have a pretty simple hello world app that doesn’t have any pre-build, build, post-build phases. All we need to do to deploy our app is pack all the code in a zip file (this is what CodeBuild does). So we tell CodeBuild that the artifacts to be packaged are basically all the files in our source code.** **There might be different scenarios where your buildspec.yml file looks more complex. Imagine your code is written in ES6 and uses Babel to transpile into good ol’ Javascript. in that case you’d need to have a pre-build phase where you install node dependencies on the project in order to get the babel command tool. Then you would have a build phase where you run the ./node_modules/.bin/babel src -d dist . Finally you’d tell CodeBuild to pack all the files inside your dist directory instead of all the files in the root as we’re doing now. This is not our case, but I wanted to show you that there are multiple possibilities and configurations with the buildspec.yml file. I’ll be happy to read questions about other approaches you might have in the comments of this post!

Step 3: Deploy

Now that we have a built artifact, we’ll have to configure how to deploy that artifact to Elastic Beanstalk. And today is our luckiest day, because CodePipeline already supports Elastic Beanstalk as a deployment provider! So we’ll select it as well as select the app and environment names which will be the same we created on our previous post:

And we’re almost there! All we have to do now is create or select an existing IAM role for CodePipeline, so that it gets access to the needed AWS resources in your account. Hit the “Create Role” button and it will open a new tab on the IAM console. Once you finish, it will take you back to the pipeline config with the recently created role name set:

Review and Launch

The final step is to review the pipeline configuration. Once you click the “Create pipeline” button, it will finalize the process and trigger the first pipeline build. If everything goes well, you should see the pipeline steps status with a nice interface:

Once all steps are done, everything should be green and you should have the hello world express app deployed into the same EB environment we created previously.

Now you can push any change to the master branch on your repo, and CodePipeline will automatically get the changes and start a new build process that will end up with your latest app deployed in your EB environment.

This was a very very simple example, but the goal was to show you how easy and powerful AWS CodePipeline is. Would love to see your comments and if you liked the post, share on Twitter!

P.S.: Here is the sample app code with the buildspec.yml: https://github.com/xoor-io/codepipeline-helloworld