Deploy your Spring Boot Applications using CodeDeploy and CodePipeline

Fahim Fahad
Enlear Academy
Published in
8 min readApr 6, 2022

--

AWS CodeDeploy and AWS CodePipeline are two AWS deployment services. AWS CodeDeploy automates the deployment of code to an EC2 instance. After we commit any changes to a specific branch, CodePipeline builds, tests, and deploys our application. Both services contribute to the continuous delivery of our application. In this article, I will deploy my Spring Boot application from GitHub to an EC2 instance using the CodeDeploy and CodePipeline services. Let’s get started.

The basic steps are below:

  1. Prepare Spring boot application and push it to GitHub
  2. Setup IAM role. We will need two IAM role. Role for EC2 and Code deploy. EC2 role will require S3 and code deploy permission.
  3. Launch EC2 instance
  4. Create application in code deploy
  5. Setup code pipeline

Prepare Spring Boot Application

In my spring boot application, I need to add a few configuration files in the application root folder. They are appspec.yml and buildspec.yml.

buildspec.yml

version: 0.2

phases:
install:
runtime-versions:
java: corretto11
build:
commands:
- mvn clean install
post_build:
commands:
- echo Build completed
artifacts:
files:
- target/*.jar
- scripts/*.sh
- appspec.yml
discard-paths: yes

Here, I am using corretto11(java) and maven as build tools. After the build, jar file will be created inside the target folder. Also, I have added some scripts inside the scrips folder that will be needed. Details of this file can be found in the AWS documentation: https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html

appspec.yml

version: 0.0
os: linux

files:
- source: /
destination: /home/ec2-user/server

permissions:
- object: /
pattern: "**"
owner: ec2-user
group: ec2-user

hooks:
BeforeInstall:
- location: server_clear.sh
timeout: 300
runas: ec2-user
AfterInstall:
- location: fix_privileges.sh
timeout: 300
runas: ec2-user
ApplicationStart:
- location: server_start.sh
timeout: 20
runas: ec2-user
ApplicationStop:
- location: server_stop.sh
timeout: 20
runas: ec2-user

Details of this file can be found in the AWS documentation: https://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file-example.html

This will copy files to /home/ec2-user/server folder that I mentioned in the artifacts part of the buildspec.yml. Hooks allow us to run different scripts at different stages of the deployment. In the start script, I added the command to run the jar and open port 80 so we can access the API. I have added all the scripts in my GitHub project inside the scripts folder. GitHub project: https://github.com/olein/Java-AWS-RnD/tree/codepipeline.

IAM Role setup

I will need two (2) IAM roles. Role for EC2 and Code deploy. EC2 will need S3 and code deploy permission. CodeDeploy role is already created by AWS.

EC2 role creation: First go to the IAM dashboard and move to create role section. I selected AWS service and EC2.

I added 2 permissions AmazonEC2RoleforAWSCodeDeploy and AmazonS3FullAccess.

Give that role a name. When deploying EC2 instances, it will be required.

CodeDeploy Role creation: For this, I just needed to select CodeDeploy from the service list.

AWS already configured permission for this service. I do not need to add any extra permission.

Give a name and create role.

IAM roles are ready.

Launch EC2 Instance

I will not go into the details of launching an EC2 instance, but I do need to mention a few points that will be important for automatic deployment.

For the IAM role, I have selected the role which i created in the second step.

And also need to add a tag. This tag will be used by CodeDeploy to find the EC2 instances to deploy the application.

I will open port 80 to call the api I added for testing and also port 22 for ssh connection.

After the EC2 instance is fully running, I will install the CodeDeploy agent and Java 11.

//run below commands

sudo yum update
sudo yum install ruby
sudo yum install wget
cd /home/ec2-user
wget https://aws-codedeploy-us-east-1.s3.us-east-1.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto
sudo yum install -y python-pip
sudo pip install awscli
sudo amazon-linux-extras install java-openjdk11

//verify installation
sudo service codedeploy-agent status
java -version

I need to explain this command a bit: wget https://aws-codedeploy-us-east-1.s3.us-east-1.amazonaws.com/latest/install

Here, I used the N. Virginia region to deploy my EC2 instance. As a result, I’ve added us-east-1. So the format is wget https://aws-codedeploy-{region}.s3.{region}.amazonaws.com/latest/install

After successful installation I can verify the setup and will get something like the below:

Create application in code deploy

I will now move to the CodeDeploy dashboard.

I will give a name and select EC2/On-premises.

Application is created. No need to set up a deployment group. A deployment group is a logical set of deployment target machines that have agents installed on each one.

Give a name to the deployment group. The role will be the IAM role for CodeDeploy I created in the second step.

The deployment type can be either in-place or blue/green. In short, blue/green deployment will create new instances with the most recent application and will move traffic once the deployment is successful. The most recent version of the application will be deployed on the same EC2 instance for in-place deployment.

Now I must choose the tags for the EC2 instance where I want to deploy my application. This is why tagging EC2 instances were critical.

We can update our CodeDeploy agent if we want. I will use the deployment setting as AllAtOnce.

After successful configuration, we will have below screen.

Setup code pipeline to deploy

Now the final step. I will create a pipeline from the CodePipeline dashboard.

Here I will give a name and create a new service role.

I will choose GitHub as the source. we can use any version of GitHub.

I need to authorize AWS to access my repository.

If authentication is successful, I will be able to select the repository and branch I want to use for code deployment.

I will select AWS CodeBuild as a builder. I need to create a project in CodeBuild.

Creating CodeBuild project:

OS should be Linux, runtime standard, and image should be the latest ones.

Create a new service role. AWS will create all the necessary permissions for these roles to function properly.

I will use buildspec.yml file that I added to my project.

Project created and I will use a single build.

Now configure the deployment provider and I will use CodeDeploy. The application and deployment group will be the ones I created before. We will get suggestions in the dropdown from the available applications and deployment group.

Everything is ready. After review, I will click create and it will initiate the process. For my application, it will download all the maven dependencies and build the jar.

If all the 3 steps are successful then we will have the below screen with all green.

To verify if our api is accessible I will call the api using the public IP of my EC2 instance.

I can see the time taken by each step.

In S3, the bucket contains the code of my application.

Now if I make any change to my application code and merge the code in a specific branch, our pipeline will automatically deploy the code.

Cleanup

I set up a lot of things. If we want to clean up, then we need to remove the bucket from S3, delete the application from CodeDeploy, delete the code builder project, and delete the pipeline from CodePipeline.

It was a big set up with a lot of steps. However, after the initial setup, everything will run smoothly and be ready to deploy the moment we make a change. It will undoubtedly save us a significant amount of time. I hope this helps. Best of luck 😊

--

--