Continuous Deployment using AWS CodeDeploy For Node.js App

Saqib Ullah Siddiqui
5 min readJul 29, 2022

In this blog, we are going to set up and configure continuous deployment on the Bitbucket repository using the AWS service.

AWS platform provides a unique service with the name of CodeDeploy on their platform stack, which helps the organization to quickly establish CD (Continuous Deployment) pipelines between repositories and different AWS services. AWS CodeDeploy allows integration with multiple repository providers like Github, Bitbucket, and others.

Not only Node.js application !

To make it’s for easy for the target audience specific application deployment steps may vary from language to language. Let’s suppose we are deploying a python base app rather than node.js, we only need to change the required setting for python packages rest of the AWS CodeDeploy settings and configurations will remain the same.

Requirements?

Bitbuckets Account
AWS Account

1. Importing Repository

To start first you need to import a sample repository into your Bitbucket repository. Click here to import the repo, in the URL section paste this like “https://github.com/technetbytes/Programs/tree/main/Node.js/Bitbucket-CodeDeploy-App” and click the Import repository button.

Repository structure

Note: — Both appspec.yml & bitbucket-pipelines.yml files should be in the top folder, otherwise CodeDeploy job will not execute.

2. Setup AWS User & Role

For successful deployment of the repo, you need some permission and settings. Let’s create a User Group with the name “Codedeploy” and set permission “AmazonS3FullAccess” and “AWSCodeDeployFullAccess”.

User Group Name Codedeploy with Permission of AmazonS3FullAccess & AWSCodeDeployFullAccess

Now create a new User with programmatic access under the User Groups. Secondly, we need a new Role with the name “ec2_codedeploy” with two permissions “AmazonS3FullAccess” and “AWSCodeDeployRole”.

IAM Role ec2_codedeploy with AmazonS3FullAccess and AWSCodeDeployRole

One last thing that we need to edit is the trust policy of the role, in our case we are using the “ap-southeast-1” region. You must update the role policy otherwise the whole solution won’t work out.

Update the trust policy according to your region

3. Setup AWS S3

To save CodeDeploy Revisions we need storage, so you need to create a bucket in S3 storage. Recommended convention of S3 storage bucket name is <application_name>-codedeploy-deployment.

cdtest-codedeploy-deployment S3 storage bucket

3. Setup AWS EC2 Instance

To deploy the node.js application we need a Ubuntu 20.04 server. Use the AWS console option and set up a micro Ubuntu 20.04 server and set its IAM Role to “ec2_codedeploy” which we created earlier. EC2 instance configuration does not end here, to configure the AWS CodeDeploy agent on the instance we need to connect to the Ubuntu server using SSH and run the following script commands.

Set Tag “Name=codedeployNodeapp” to the EC2 instance, it would be helpful in EC2 instance matching.

After running the preceding script EC2 is ready to communicate with the CodeDeploy service.

4. Create CodeDeploy Application

  1. Now is the time to set up the CodeDeploy application using AWS Console and search “CodeDeploy” in the search bar. After opening the landing page click on the “Create application” button top right. Give the name “testcodedeploy” and select “EC2/On-premises” in Compute platform dropdown.
  2. In the step we are going to create a deployment group, for this you need to select the previously created application “testcodedeploy” and click on Create deployment group button, give the proper name i.e “testdeploymentgrp”, next select service role from the dropdown “ec2_codedeploy”, next deployment type select “In-place”, next Environment configuration select Amazon EC2 Instances and set Tag “Name=codedeployNodeapp” its matched 1 unique instance of EC2.

3. Remove the Load balancer check and finally click on create deployment group button.

5. AppSpec Lifecycle Event Hooks

For application deployment, YAML-based AppSpec files are used which are based on hooks. The JSON format is also supported for definition. Using these hooks’ lifecycle you can control the configuration and deployment of the app. All hook events allow execution of bash script.

  1. BeforeInstall
  2. AfterInstall
  3. ApplicationStart

Before Install Script, in this script, we are installing pm2 globally using the
-g flag

https://gist.github.com/technetbytes/

After Install Script, my folder under ubuntu user with the name my-app1

https://gist.github.com/technetbytes/

Application Start Script,

6. Configure Bitbucket Pipeline

Before going to write down the pipeline YAML file, we need to set some repository variables in the repository setting.

  1. AWS_DEFAULT_REGION = “ap-southeast-1
  2. AWS_ACCESS_KEY_ID = “**** Use your KEY ID ****
  3. AWS_SECRET_ACCESS_KEY = “**** Use your ACCESS ID ****
  4. APPLICATION_NAME = “testcodedeploy
  5. DEPLOYMENT_GROUP = “testdeploymentgrp
  6. S3_BUCKET = “cdtest-codedeploy-deployment

APPLICATION_NAME & DEPLOYMENT_GROUP are coming from CodeDeploy

Following the pipeline YAML file use “atlassian/aws-code-deploy:1.1.1” version, another version might give you some errors. To get the latest integration pipeline.

Now it’s time to push the YAML file and see the magic. Click the Pipelines link where you will see the one running pipeline and click on it.

At the same time, you can also verify the AppSpec hook from the Deployment group deployment history section in the AWS console.

The core objective of this blog is to give step-by-step guidance on the configuration EC2 CodeDeploy agent installation, AppSpec hooks scripts, and core CD YAML pipeline. If anyone follows these guidelines they can quickly establish Continues Deployment option for any type of application.

Users can also view the logs detail of CodeDeploy on the Server by opening the log file “codedeploy-agent-deployments.log”. SSH the server and follow type this command in the terminal.

/opt/codedeploy-agent/deployment-root/deployment-logs/codedeploy-agent-deployments.log

Thanks!

--

--