Setting Up a CI/CD Pipeline for a Spring Boot Application on AWS

Kiran PawarKiran Pawar
3 min read

This tutorial guides you through setting up a CI/CD pipeline to deploy a Dockerized Spring Boot application to AWS. Weโ€™ll create a Dockerfile, build an image, push it to AWS Elastic Container Registry (ECR), and deploy it using AWS Elastic Container Service (ECS).

Prerequisites

  • AWS CLI and Docker installed

  • An AWS account with appropriate permissions

  • A GitHub repository (repo link used in this example: AWS CI/CD Repo)

Step 1: Create a Dockerfile

In the root of your project, create a Dockerfile for the Spring Boot application. This file tells Docker how to package your application.

# Use the official OpenJDK 17 image from Docker Hub
FROM openjdk:17

# Set working directory inside the container
WORKDIR /app

# Copy the compiled Java application JAR file into the container
COPY ./target/course-service.jar /app

# Expose the port the Spring Boot application will run on
EXPOSE 8080

# Command to run the application
CMD ["java", "-jar", "course-service.jar"]

Step 2: Create an ECR Repository

In the AWS Management Console:

  1. Go to Amazon ECR.

  2. Click Create Repository.

  3. Enter a name for your repository (e.g., springboot-app).

  4. Select visibility as Private and click Create Repository.

Note down the repository URI (e.g., 471112792443.dkr.ecr.ap-south-1.amazonaws.com/springboot-app), which will be used in the build configuration.

Step 3: Create a Buildspec File

The buildspec.yml file is used by AWS CodeBuild to define build commands and phases. Place this file in the root of your project.

version: 0.2

phases:
  pre_build:
    commands:
      - mvn clean install
      - echo Logging in to Amazon ECR...
      - aws --version
      - REPOSITORY_URI=471112792443.dkr.ecr.ap-south-1.amazonaws.com/springboot-app
      - aws ecr get-login-password --region ap-south-1 | docker login --username AWS --password-stdin $REPOSITORY_URI
      - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
      - IMAGE_TAG=build-$(echo $CODEBUILD_BUILD_ID | awk -F":" '{print $2}')
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...
      - docker build -t $REPOSITORY_URI:latest .
      - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker images...
      - docker push $REPOSITORY_URI:latest
      - docker push $REPOSITORY_URI:$IMAGE_TAG
      - echo Writing image definitions file...
      - printf '[{"name":"course-service","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
      - echo Writing image definitions file...
      - DOCKER_CONTAINER_NAME=springboot-app
      - printf '[{"name":"%s","imageUri":"%s"}]' $DOCKER_CONTAINER_NAME $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
      - echo $DOCKER_CONTAINER_NAME
      - echo printing imagedefinitions.json
      - cat imagedefinitions.json

artifacts:
  files:
    - imagedefinitions.json
    - target/course-service.jar

Explanation

  • Pre-Build: Installs dependencies, logs into ECR, and sets up variables for image tags.

  • Build: Builds the Docker image and tags it.

  • Post-Build: Pushes the Docker image to ECR and creates an imagedefinitions.json file for deployment.

Step 4: Create a CodeBuild Project for CI

  1. Go to AWS CodeBuild.

  2. Click Create Project.

  3. Set the project name and select GitHub as the source, connecting your repository.

  4. Choose Managed Image as the environment and select an image with Docker support (e.g., aws/codebuild/standard:5.0).

  5. Add the necessary environment variables and specify buildspec.yml as the build configuration.

  6. Under Artifacts, select imagedefinitions.json.

CodeBuild will build your Docker image and push it to ECR each time code is pushed to GitHub.

Step 5: Deploy the Application Using AWS ECS

  1. In ECS, create a new cluster.

  2. Create a task definition with your container configuration.

  3. Set the image to the ECR image URI generated by CodeBuild.

  4. Define your service and deploy it.

Step 6: Test the Deployment

Navigate to the ECS service URL and add /swagger-ui/index.html to access the Swagger UI of your deployed application.

Example URL:

http://65.0.69.103:8080/swagger-ui/index.html

Step 7: Trigger the CodeBuild Pipeline Manually

Make a minor change in your GitHub repository and push it. The CodeBuild project should automatically trigger, rebuild, and push the updated Docker image.

Verify Webhook

To test if the webhook is set up correctly, make a code change, commit, and push. The pipeline should start automatically, deploying the latest version to ECS.

0
Subscribe to my newsletter

Read articles from Kiran Pawar directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Kiran Pawar
Kiran Pawar

"Hello, I'm Kiran Pawar, a passionate Cloud and Devops Engineer with a strong background in cloud automation, configuration, and deployment. My journey in the world of technology has been a thrilling adventure, where I've had the privilege to work with cutting-edge tools and practices. ๐Ÿš€ As a DevOps Engineer: I specialize in automating, configuring, and deploying instances in cloud environments and data centers. My expertise extends to DevOps, GitOps, CI/CD pipeline management, HashiCorp Terraform, and containerization. I'm proficient in AWS and Linux/Unix administration, ensuring robust infrastructure and application performance. ๐Ÿ”ง My Tech Stack: Front-end skills: HTML, CSS, SCSS, Tailwind CSS, Bootstrap, React, Material-UI, JavaScript DevOps toolbox: GIT, OWASP,Nexus,Trivy, Github, Gitlab, Terraform, Ansible, Docker, Kubernetes, Helm, Jenkins, Prometheus, Grafana, Argo CD, AWS EKS. ๐ŸŒ My Cloud Expertise: I have hands-on experience managing AWS services, including EC2, S3, EBS, VPC, ELB, RDS, IAM, Route53, and more. ๐Ÿ”’ Networking and Security: My skills include managing networking concepts such as TCP/IP protocols, security policies, and subnet interfacing. I have a strong understanding of infrastructure and networking, covering topics like firewalls, IP addressing, DNS, and more. ๐Ÿ’ก What Sets Me Apart: I bring a positive attitude, a strong work ethic, and a collaborative spirit to every project. I'm a self-starter, a fast learner, and an effective team player with strong interpersonal skills. In addition to my DevOps skills, I've developed shell scripts (Bash) for automating tasks and have proficiency in Python scripting. My ability to communicate and manage projects, along with a track record of resolving client issues, adds value to every team I work with. If you're looking for a DevOps engineer who is also well-versed in front-end technologies, feel free to connect with me. Let's explore new possibilities and create exceptional technical solutions together!"