How to Deploy Spring Boot Microservices on AWS ECS with Fargate

How to Deploy Spring Boot Microservices on AWS ECS with Fargate

How to Deploy Spring Boot Microservices on AWS ECS with Fargate

Introduction

Deploying Spring Boot microservice on AWS ECS with Fargate allows us to run our applications in a serverless container environment. AWS Fargate allows us to run containers without having to manage the underlying infrastructure, making it easier to focus on our application code. In this tutorial, we’ll cover how to prepare our application, containerize it with Docker, and deploy it using AWS ECS and Fargate.

Prerequisites

Before we begin, ensure you have the following:

  1. AWS Account: You’ll need an active AWS account.
  2. AWS CLI: Installed and configured on your local machine.
  3. Docker: Installed on your local machine. If you haven’t already, download and install Docker from Docker’s official website based on your operating system.
  4. Java and Spring Boot: Basic knowledge of Java, Spring Boot, and Maven/Gradle for building your application.

Step 1: Prepare Our Spring Boot Application

To start, we need to ensure our Spring Boot application is ready for deployment. We’ll assume we have a basic Spring Boot application that we want to containerize. Our application should be working locally, with all necessary dependencies defined in the pom.xml file if we’re using Maven. You may also refer back to our previous tutorial on creating a microservice with Spring Boot.

We should ensure our application is listening on port 8080, which is important when we configure our Docker container.

Step 2: Create a Dockerfile

Next, we need to containerize our Spring Boot application using Docker. A Dockerfile is used to create a Docker image of our application. Here’s a basic Dockerfile for a Spring Boot application:

# Stage 1: Build the application with Maven
FROM maven:3.8.6-openjdk-17 AS build

# Set the working directory in the container
WORKDIR /app

# Copy the Maven project files
COPY pom.xml .
COPY src ./src

# Build the application
RUN mvn clean package -DskipTests

# Stage 2: Create a minimal image with only the runtime environment
FROM openjdk:17-jre-slim

# Set the working directory in the container
WORKDIR /app

# Copy the JAR file from the build stage
COPY --from=build /app/target/my-application.jar /app/my-application.jar

# Expose the port our application will run on
EXPOSE 8080

# Run the JAR file
ENTRYPOINT ["java", "-Dspring.profiles.active=${SPRING_PROFILES_ACTIVE}", "-jar", "/app/my-application.jar"]

This Dockerfile starts from a Maven image with OpenJDK 17 to build our application. Then we set a working directory inside the container to /app. Next, we copy the Maven pom.xml file and source code into the container. We then run Maven to build the application, skipping tests to speed up the build process. This command compiles the source code and packages it into a JAR file, which will be placed in the target directory.

Next, we start a new stage with a smaller base image that includes only the JRE needed to run our application. We copy the JAR file from the build stage into the runtime image. Then we expose port 8080, where the application will listen. Finally, we specify the command to run when the container starts.

After building the JAR file, we can then proceed to build the Docker image using the Dockerfile as described previously:

docker build --platform linux/amd64 --tag=my-application --force-rm=true .

Here we use the --force-rm=true flag to remove all intermediate containers, even if the build is not successful, to save space on our hard drive.

--platform linux/amd64 is to specify the platform for which the image should be built. Adjust this if targeting a different platform.

Step 3: Push Docker Image to Amazon ECR

Amazon Elastic Container Registry (ECR) is where we will store our Docker images. To push our image to ECR, we first need to set up a repository and authenticate Docker with ECR.

Ensure we have the AWS Command Line Interface (CLI) installed and configured with the necessary credentials and default region:

aws --version
aws configure

Authenticate Docker to ECR:

We use the AWS CLI to authenticate Docker with our ECR registry:

aws ecr get-login-password --region your-region | docker login --username AWS --password-stdin your-account-id.dkr.ecr.your-region.amazonaws.com

Create a Repository in ECR:

We can create a repository using the AWS Management Console or via the CLI:

aws ecr create-repository --repository-name REPOSITORY_NAME

Tag and Push Our Docker Image:

Before pushing the image to ECR, tag the docker image with the full path to our ECR repository:

docker tag my-application:latest your-account-id.dkr.ecr.your-region.amazonaws.com/REPOSITORY_NAME

Push the image to ECR:

docker push your-account-id.dkr.ecr.your-region.amazonaws.com/REPOSITORY_NAME

Verify that the image was successfully pushed by listing the images in your ECR repository:

aws ecr list-images --repository-name REPOSITORY_NAME

Step 4: Create an ECS Cluster

Now, we need to create an ECS cluster where our container will run. An ECS (Elastic Container Service) Cluster is a logical grouping of resources that AWS ECS uses to run and manage containerized applications. Think of it as a container management environment where we deploy and manage our containers.

Cluster Types

When using AWS Fargate, we don’t need to manage EC2 instances. Fargate abstracts this management layer by automatically handling the compute resources required to run containers. We only define the task and container settings, and Fargate manages the rest.

  1. In the AWS Management Console, go to the ECS service.
  2. Choose to create a new cluster.
  3. Name our cluster, for example, my-application-cluster.
  4. Select AWS Fargate under the infrastructure tab.

Step 5: Define a Task Definition

Now that our ECS cluster is set up, the next step is to create a task definition.

Task

A task is the basic unit of work in ECS. It consists of one or more containers that are defined in a task definition. The task definition specifies which Docker images to use, resource requirements, and other configurations.

  1. In the ECS console, navigate to Task Definitions.
  2. Click on the Create a new task definition and choose.
  3. Provide a name for the task definition, such as my-application-task.
  4. Select Fargate launch type.
  1. Now, we’ll add the container definition, which includes specifying the Docker image and container-specific configurations:
    • Container Name: Give a name to the container, e.g., my-spring-boot-container.
    • Image: Provide the URL of the Docker image in ECR (Elastic Container Registry) that we pushed earlier. For example, 123456789012.dkr.ecr.region.amazonaws.com/my-application:latest.
    • Port Mapping: Map port 8081, which is the port our Spring Boot application runs on inside the container, to the same port on the host.
  2. Next, we specify the resource requirements for our task. These are important because they define how much CPU and memory will be allocated for each container.
    • CPU Units: Define how much CPU we want to allocate.
    • Memory: Allocate the amount of memory for our task, such as 512 MB or 1 GB, depending on our application’s requirements.
  3. Set Environment Variables (Optional): If our Spring Boot application requires environment variables, like database connection strings or API keys, we can define them here. For example, if we are using a MySQL database, we might set environment variables such as SPRING_PROFILES_ACTIVE, DB_HOST, DB_USERNAME, and DB_PASSWORD.
task-definition-container-1 How to Deploy Spring Boot Microservices on AWS ECS with Fargate

Step 6: Deploy the Service

With our task definition ready, we can now proceed to deploy the Spring Boot application as a service in the ECS cluster.

Service

A service is a long-running task that maintains a specified number of instances of a task definition running and ensures that they remain healthy and available. Services can be configured with load balancers to distribute incoming traffic.

In the ECS console, create a new service within our cluster and choose Fargate as the launch type for our service.

ecs-fargate How to Deploy Spring Boot Microservices on AWS ECS with Fargate

Next, we will select the task definition that was created earlier, ensuring we choose the latest revision of the task definition for the service. Provide a name for our service and set the desired number of tasks to 1, we can scale the service up later as needed.

ecs-deployment-configuration How to Deploy Spring Boot Microservices on AWS ECS with Fargate

Configure Service Connect

Service Connect is AWS’s managed service mesh solution integrated with Amazon ECS. It simplifies inter-service communication by handling service discovery, traffic management and security. When configuring Service Connect for our ECS services, we can choose between client or client and server modes based on how our services interact with each other.

Client Mode: Allows a service to initiate connections to other services within the Service Connect namespace. The service does not expose any endpoints for other services to connect to it. It solely acts as a client.

Client-Server Mode: Enables a service to both initiate connections to other services and provide endpoints for other services to connect to it. The service exposes endpoints that other services can connect to, effectively acting as both a client and a server.

ecs_serviceconnect-1024x718 How to Deploy Spring Boot Microservices on AWS ECS with Fargate

After setting up Service Connect, our ECS services can communicate with each other using DNS-based URLs. For example:

http://<DNS_NAME:<PORT_NUMBER>

By default, Service Connect is scoped within a single ECS cluster. However, if the architecture requires communication between services in different ECS clusters, we can achieve this by using Shared Namespaces. Namespaces act as logical groupings of services. To enable cross-cluster communication, services in different clusters must share the same Service Connect namespace.

Configure Networking in ECS

The next step is to configure networking in ECS. In the “Configure network” section, choose the Virtual Private Cloud (VPC) where our service will run. Select the public or private subnets that our service will use.

Click on “Create new security group” to define a set of rules that control traffic to our service. Add an inbound rule that allows traffic on port 8081. Set the source as appropriate. We set the source as 0.0.0.0/0, which allows access from any IP address, we will update to allow only traffic from ALB later.

ecs-networking How to Deploy Spring Boot Microservices on AWS ECS with Fargate

Configure Load Balancing in ECS

After configuring networking and security groups, the next step is to set up an Application Load Balancer (ALB) in Amazon ECS to evenly distribute traffic across tasks and manage incoming requests.

In the ECS service configuration, enable the option for load balancing. Select Application Load Balancer load balancer type. Next, select the container we created.

Next, we define the listener port for the ALB to HTTP. Under Target Group, select Create New target group. Next, we set the Health Check Protocol to HTTP and provide a health check path /health.

ecs-load-balancer How to Deploy Spring Boot Microservices on AWS ECS with Fargate

Click create to complete the ECS service creation.

Next, we need to create a new security group for the ALB to allow inbound traffic on port 80 or 443. Navigate to the EC2 console, then click on Security Groups under the Network & Security section. Create a new security group named product-services-alb-sg.

alb-security-group-1024x388 How to Deploy Spring Boot Microservices on AWS ECS with Fargate

Navigate to the load balancer we created during the ECS service set up, under the Security tab, click Edit. Change the security group to the one we newly created.

Now, return to the Listeners and Rules tab, and the warning icon should no longer be displayed.

alb-listeners How to Deploy Spring Boot Microservices on AWS ECS with Fargate

Now, return to the security groups product-services-sg we created in ECS, and update the source to the ALB security group product-services-alb-sg.

Screenshot-2024-09-26-at-9.43.49 AM How to Deploy Spring Boot Microservices on AWS ECS with Fargate

Step 7: Verify

Navigate back to the ECS console, and click on the product-service. We shall see one task is running healthy.

ecs-deployment-successfully-1024x361 How to Deploy Spring Boot Microservices on AWS ECS with Fargate

If everything is configured correctly, we should see the Spring Boot application started successfully in CloudWatch logs.

spring-boot-log-1024x509 How to Deploy Spring Boot Microservices on AWS ECS with Fargate

Step 8: Configure Auto Scaling

Additionally, we’ll notice only one task running in ECS, as we set the desired task count to 1. In this step, we’ll configure the auto-scaling group to automatically scale up when the request load increases.

Navigate to the product-service in the ECS console, click on Update service. Next, enable the auto-scaling feature by checking the option to enable service auto-scaling.

Specify the minimum number of tasks (e.g., 1) to ensure there is always at least one instance running. Then, we set the maximum number of tasks (e.g., 3 or more) to limit how many instances can run based on demand.

Select ALBRequestCountPerTarget as the metric to monitor. This metric tracks the number of requests per target in your load balancer. Set the scaling policy to increase the number of tasks when the request count exceeds a certain threshold.

For example, we might choose to scale up when the request count exceeds 5 requests per target over a 30-second period. In this case, when the request count reaches 5 within a 30-second windowECS will automatically scale out the containers to handle the increased load.

ecs-auto-scaling-1024x794 How to Deploy Spring Boot Microservices on AWS ECS with Fargate

Once all settings are configured, review our choices and click Save to apply the auto-scaling configuration.

Try to hit the ALB URL multiple times, this will help trigger the scaling conditions we’ve set. After initiating the requests, go to the CloudWatch console. We should see the alarm triggering as the request count meets the specified threshold.

cloud-watch How to Deploy Spring Boot Microservices on AWS ECS with Fargate

Navigate to the ECS console and check the service dashboard. We should observe that the service has automatically launched another task in response to the increased load.

ecs-service-auto-scale-out How to Deploy Spring Boot Microservices on AWS ECS with Fargate

Conclusion

Deploying Spring Boot microservices on AWS ECS using Fargate offers a robust, scalable solution for modern application architectures. Throughout this guide, we have walked through the essential steps, from setting up the environment to configuring services and implementing auto-scaling.

Share this content:

Leave a Comment

Discover more from nnyw@tech

Subscribe now to keep reading and get access to the full archive.

Continue reading