CICD — Deploy to AWS CodeDeploy with Bitbucket Pipeline

Devashish Gupta
codelogicx
Published in
7 min readMay 25, 2023

Hello guys, today we’re going to see how we can setup Bitbucket Pipeline with EC2 on AWS using CodeDeploy. This will reduce the work of manually deploying the code on server and reduce the time-to-market of your application. This practice is known as CI-CD which means Continuous Integration & Continuous Deployment/Delivery.

Deploy to AWS with CodeDeploy with Bitbucket Pipeline

For the rough working principle, you can refer to the following Infra Architecture diagram.

As you can see, the Bitbucket is containing the repo which will be responsible to deploy the code on the EC2 instance & the flow is something like, Bitbucket pipeline will be executed when doing changes in the source code, after that the build and deploy steps will be executed as per the bitbucket-pipelines.yml file which will do the build of code, upload the code to S3 bucket and then from S3 bucket the code will be deployed on EC2 using CodeDeploy AWS service and the CodeDeploy agent running on EC2.

For this tutorial we’re going to use following services,

  • Bitbucket Pipeline
  • AWS IAM
  • AWS CodeDeploy & CodeDeploy agent
  • AWS EC2 (with NodeJS)
  • AWS S3

This mainly cover 6 steps:

  1. Create an EC2 with AmazonEC2CodeDeploy role,
  2. Install CodeDeployAgent and NodeJS on ec2 instance,
  3. Create CodeDeploy Application & Deployment group,
  4. Create S3 bucket,
  5. Create an IAM user with AWSCodeDeployFullAccess and AmazonS3 access,
  6. Configuring Bitbucket Repo Variables & Bitbucket Pipeline.

So, let’s get started with these steps,

Create an EC2 with Amazon EC2 Code Deploy Role:

For this, first you need to login into your AWS console and go to EC2 section, from there you can click on Launch instance and proceed with it.

Launch Instance

After clicking on Launch instance, choose the configuration you want to use as per your needs,

Instance configuration

Remember to choose the IAM instance profile AmazonEC2CodeDeploy default role in Advance details section

IAM instance profile section

After that click on Launch instance and your instance is ready to be used.

Instance created

Now let’s SSH into server and we can move to the next step.

Install Code Deploy Agent and NodeJS on EC2 Instance:

For installing the CodeDeployAgent we can refer to this guide = https://docs.aws.amazon.com/codedeploy/latest/userguide/codedeploy-agent-operations-install-linux.html

and for installing NodeJS we can refer to this guide = https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-up-node-on-ec2-instance.html

After installing both the application, you need to make sure both are running as well,

code-deploy agent status

Note: Don’t worry about the warning.

As you can see, both the CodeDeployAgent and NodeJS are installed and running. Here we installed CodeDeployAgent so that EC2 can fetch the deployment task from CodeDeploy server in order to do the deployment which will be assigned by Bitbucket. Next, we installed NodeJS because we’re going to Install and Run NodeJS application on the server. Remember to note the NodeJS version because this will be used in the code. So, we’re fine to go for the next step.

Create CodeDeploy Application & Deployment Group:

For this we need to go to CodeDeploy Applications tab, and click on Create application.

CodeDeploy console

Write any name and choose EC2/On-premises in Compute platform and then click on Create application,

Create CodeDeploy application

After that it is created, we need to create Deployment Group, for this click on Create deployment group button under the Application which we just created,

CodeDeploy Application Created

After clicking on that button, you’ll get a new page there you’ll need to add information like Deployment group name, Service role and others,

Create deployment group

As you can see, I’ve used CodeDeployGroup as name and choose AmazonCodeDeploy default role to be used with the deployment group.

After that choose In-place in Deployment type,

Deployment type

And then under Environment configuration

Environment configuration

Choose Amazon EC2 instances as type and use Name as key and write the name of the EC2 which you deployed in 1st step as Value.

Scroll down further and configure rest options as shown in below screenshot,

CodeDeploy agent configuration

Since we’ve already installed CodeDeployAgent, we can choose Never in Agent configuration section. After that choose AllAtOnce in Deployment settings section which will make sure the code will be deployed on all the EC2 instances which verifies the Key-Value pair. After that just click on Create deployment group and you’re good to go.

Deployment Group Created

Now we can move to the next part which is creating a S3 bucket.

Create S3 Bucket:

For this, all you need is to create a S3 bucket in the same region as where you deployed EC2 and CodeDeploy Application and Deployment groups.

S3 bucket

So, this part is also done. Now move to the next step.

Create an IAM user with AWSCodeDeployFullAccess and AmazonS3 access:

For this, move over to IAM console and create a new user with the following permissions,

CodeDeploy IAM User

Since this user Secret Access Key Pair will be used with Bitbucket to register the job to CodeDeploy and upload/download build from S3 to EC2, we need CodeDeploy and S3 access policies. You can tweak these policies as per your requirements which is recommended but I’m here using the FullAccess just for demo purpose.

Now comes the final step where we’re going to integrate all these services into the code so the pipeline works flawlessly.

Configuring Bitbucket Repo Variables & Bitbucket Pipeline:

For this, first you need to have the base code which will be used to setup the pipeline,

Source code: https://github.com/dcgmechanics/CICD-aws-code-deploy
(Clone this repo on your local machine and upload on your Bitbucket profile repo)

In this source code, we need to modify the following details on Bitbucket,

  • AWS_SECRET_ACCESS_KEY: Secret key for a user with the required permissions.
  • AWS_ACCESS_KEY_ID: Access key for a user with the required permissions.
  • AWS_DEFAULT_REGION: Region where the target AWS CodeDeploy application is.
  • APPLICATION_NAME: Name of AWS CodeDeploy application.
  • DEPLOYMENT_GROUP: Name of the AWS CodeDeploy deployment group.
  • S3_BUCKET: Name of the S3 Bucket.

I believe we already have all these details from the last steps. So, we need to make the changes in bitbucket-pipelines.yml file repository variables.

Bitbucket pipeline variables

After that we need to make sure that the NodeJS version is same on the repo as the one which is installed on the EC2 server, For this move to app/sceipts/start.sh and check for this line,

node js version modification

If the version is not same, please make the changes and commit the code.

Now we need to enable the Pipeline feature in the Repository settings>Pipelines>Settings

Enable pipelines

After enabling the Pipeline, move to the repo root directory and click on Pipelines from the left panel, Click on Run Pipeline, choose branch and pipeline and click on Run.

Run pipeline

If you followed everything fine till now, you’ll see something similar to below as mine

Pipeline successful

As you can see, All the stages ran fine and the code is deployed on EC2 which you can access from the anywhere with http://IP:8080/ address

Code Deployed

Since This is just for demo, there’s nothing much from App side but if you want to use your own app for deployment via CICD, you need to move the codebase into app/ directory and modify the scripts which will be used to start and stop as per your application needs which are located at app/scripts/start.sh

start.sh

& app/scripts/stop.sh

stop.sh

The file app/appspec.yml contains the information about where the code will be deployed and what kind of actions will be executed while deploying on the EC2,

appspec.yml

Here os keyword refers to the OS architecture on which the CodeDeployAgent is running. I hope you succeeded in setup the Bitbucket pipeline and it executed fine without any issues.

If there is any feedback is appreciated, it will be great for me to improve and work further on this pipeline.

Thanks!
Remember, #SharingIsCaring ;)

--

--