Continuous Deployment Pipeline with Bitbucket-Pipelines to AWS EC2 using AWS Code Deploy
Set up continuous deploy of a Node.js Application
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:
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 User and add it to this group with Programmatic Access,
Save the credentials(Access Key, Secret Access Key), we will need it later.
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 AmazonS3FullAccess
and AWSCodeDeployRole
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.
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!
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
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
And if you did follow along properly, you’ll see a successful pipeline run and your application deployed on the server!
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.