Continuous Deployment Pipeline with Bitbucket-Pipelines to AWS EC2 using AWS Code Deploy

Set up continuous deploy of a Node.js Application

Aagam Vadecha
Level Up Coding
Published in
6 min readMay 29, 2019

--

If you’re here I assume you know what Continuous deployment is and why you need it. In this post, we will see how to deploy a simple Node.js Application on an AWS EC2 Instance and to automate its delivery every time a git push is executed to your production repository. The code will be deployed and hosted on your server without you having to do a single thing.

The application we will be using for this demo example is a simple “Hello World” Node.js application but yes the getting started concepts will be covered and then can be scaled according to your needs.

This is how the app.js file for our Node server

The directory structure looks like:

Initial Directory Structure

Alright, Let’s get started!

Overview:

Bitbucket repositories have pipeline support and we can use them to ease our deployments, you can read more about them here. They provide integrations for various platforms such as Amazon Web Services, Google Cloud Platform, Microsoft Azure, and many more.

We will be setting up an IAM user with programmatic access which will be used by bitbucket-pipelines to push a copy of our application to an S3 bucket and then trigger a deployment on AWS Codedeploy which will, in turn, deploy our application as per our appspec.yml configuration on our EC2 instance on our behalf.

This may seem to be a lot, but hang on we will get through all of it! So let’s set up an IAM User first— I assume you’re familiar with the basic Amazon Web Services.

Step 1: Create an IAM Group, User, Role

Create an IAM Group with the permissions

  • AmazonS3FullAccess
  • AWSCodeDeployFullAccess
Create A Group

Create a User and add it to this group with Programmatic Access,
Save the credentials(Access Key, Secret Access Key), we will need it later.

Add A User To Group

Also, create a Role in IAM and select EC2 Service as our EC2 instance will be using that role later to interact with CodeDeploy and add policies of AmazonS3FullAccessand AWSCodeDeployRole

Create A Role

After creating the role, edit the Trust Relationship to be as follows.
Change the region to the region you are working on, mine is N.Virginia that is us-east-1

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"ec2.amazonaws.com",
"codedeploy.us-east-1.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}

Step 2: Create an S3 Bucket and an EC2 Instance

Create an S3 bucket and name it anything you like and keep the bucket settings default for things to be simple currently, I’m naming it directcodedeploy-codedeploy-deployment .

Next, create an EC2 Instance The OS can be as per your requirement, We’ll be using an Ubuntu 16.04. We need to Add the IAM Role-AWSCodeDeployRole we already created, Now in order for AWS Code Deploy to recognize our instance it will look for tags, therefore we need to tag it so we’ll tag it say
Name = CodeDeployDirect, open up proper ports you need for your application in security groups like our application will need port 3000 open.

Add IAM Role
Add Tag

Launch the instance and then install the CodeDeploy Agent on your server, depending on your OS the installation process might vary a proper guide can be found here, Follow the instructions according to your OS and make sure the Code Deploy agent is up and running!

Code Deploy Agent On Server

Step 3: Create a CodeDeploy Application

Go to AWS CodeDeploy Console and click on Create Application

Then Create a deployment Group with the following settings
Name : DG1 (You can choose any)
Service Role : AWSCodeDeployRole
Deployment Type : In Place
Deployment Settings : CodeDeployDefault.OneAtATime
Disable Load Balancing
And Under Environment configuration :

You should see 1 Matching Instance, then press Create Deployment Group

So far we’ve set up an IAM user to be used by the Bitbucket Pipeline, an S3 bucket to store our application zip file, an EC2 Instance on which our application is to be deployed and also installed code deploy agent in order to deploy our application according to the appspec.yml file. You can see some basic examples of how to configure the appspec.yml here , also you can read more about how to configure bitbucket-pipelines.yml here.

For our application the appspec.yml is as follows:

And the three simple bash scripts used above are as follows:

Add the following files to your repository and then add repository variables in Bitbucket, also enable pipelining when prompted.

All that is remaining now is to set up and push the bitbucket-pipelines.yml to our repository so that everything works.

The pipe we see in here is another script which is maintained by Atlassian, you just have to paste the pipe, supply a few key pieces of information, and the rest is done for you.

You can learn more about pipes and check out other pipes here.
The final directory structure looks like this

Final Directory Structure

Now it’s time to commit and push to remote.

After pushing changes to Bitbucket go to the pipeline section of your repository you will be able to see a pipeline triggered with #1 something like

Pipeline In Progress

And if you did follow along properly, you’ll see a successful pipeline run and your application deployed on the server!

Pipeline Successful
Deployed Application

Now try to change the message in your local repository and then push it to remote and in minutes visit your URL to see how it is going to reduce your burden for future deployments!

Good Job!

Thanks for reading! If you liked what you read, then leave a 👏 and follow.

--

--