# How to Easily Deploy a Spring Boot Application on AWS Fargate

Before entering the AWS Cloud world, as a Java developer, it was often difficult for me to get Java-based applications online for my clients. 
Fortunately, I found out later that AWS provides many proven, fully managed services for deploying Java-based applications such as [EC2](https://aws.amazon.com/ec2/), [Elastic Beanstalk](https://aws.amazon.com/elasticbeanstalk/), [Amazon ECS](https://aws.amazon.com/ecs/), etc.

In this post, we will show how to quickly deploy a Spring Boot Application on Amazon ECS with [AWS Fargate](https://aws.amazon.com/fargate/) deployment option. [AWS Fargate](https://aws.amazon.com/fargate/) is a Serverless compute engine that can be used to launch and run containers without having to provision or manage EC2 instances. 

In the next lines, we will :

- See how to create a Spring Boot REST API Docker image

- Go through how to push a containerized API on the docker repository and deploy this containerized API on AWS

- Create an ECS Cluster

- Create a Fargate compatible Task Definition

- Run the configured Task to make the application available online


## Prerequisites


1. Have a [Docker repository](https://hub.docker.com/repository/) account

1. [Install Docker Desktop](https://docs.docker.com/get-docker/) on your local machine

1. Have an [AWS account](https://console.aws.amazon.com/console/home)


## Create a Spring Boot REST API


Through this section, instead of creating a Spring Boot Web application, we will create a Spring Boot Rest API for simplicity. Notice that the deployment process is the same even for Spring Boot Web App and Spring Boot REST API. 
For demonstration purposes, you can clone the Git hub repository [here](https://github.com/wilkom2009/docker-demo2) and open it in your favorite IDE.


## Create a Docker container image for the Spring Boot Application


### 1\. Create a Docker file
In the project root, create a docker file named: **Dockerfile** (with no file extension). Paste the below content:

```java
FROM openjdk:11
COPY ./target/docker-demo-0.0.1-SNAPSHOT.jar docker-demo- 
0.0.1-SNAPSHOT.jar
CMD ["java","-jar","docker-demo-0.0.1-SNAPSHOT.jar"]
EXPOSE 8080
```

> Line 1: Instruction to build docker image from openjdk:11 image

> Line 2: Instruction to copy the jar file into the Docker container file system while building

> Line 3: is a java command to launch the jar file while executing the container

> Line 4:  informs Docker that the container listens on 8080 port at runtime.

### 2\. Build the Docker image
Open the terminal and execute the following docker command in the project root:

```bash
docker image build -t docker-demo .
```

You should have a result like this:

![Terminal : docker build success](https://cdn.hashnode.com/res/hashnode/image/upload/v1654310567355/UaY_T7kB-Q.png)

### 3\. Test the docker image locally
Open the terminal and execute the following command:

```bash
docker container run --name dockerDemoApp -p 8080:8080 -d 
docker-demo
```

Go to Docker Desktop, you should see this:
    
![Docker desktop](https://cdn.hashnode.com/res/hashnode/image/upload/v1654310568876/2q8QmA4ay.png)

You can then paste this link `http://localhost:8080/api/` in the browser to get the following result :

![Web browser showing get response](https://cdn.hashnode.com/res/hashnode/image/upload/v1654310570393/EkGxueQQz.png)

### 4\. Push Docker image into Docker hub repository
In order to push the Docker local image into the Docker hub repository, you just need to execute the following command line:

```bash
docker push xxx/docker-demo-app:latest
```

>Make sure to replace xxx with your user name.


## Deploy the Spring Boot REST API on AWS Fargate

In this section, we will work step by step to finally get the REST API online.

### 1\. Create Amazon ECS Cluster

- Sign in to the [AWS Console](https://console.aws.amazon.com/console/home), and type ECS in the Search bar.

![Amazon ECS Cluster page](https://cdn.hashnode.com/res/hashnode/image/upload/v1654310572068/16zzchZO4.png)

Click on **Create Cluster**

- Step 1: On **Select cluster template** step, select **Networking only** option and click on **Next Step**

- Step 2: Provide the **Cluster name** : _Demo-cluster_, check **Create VPC** option, leave all other default options and click on **Create**.

![Amazon ECS Cluster config](https://cdn.hashnode.com/res/hashnode/image/upload/v1654310573722/mqZBYnxNc.png)

- Click on **View Cluster**, and the Demo-cluster details should look like this:

![Amazon ECS Cluster view](https://cdn.hashnode.com/res/hashnode/image/upload/v1654310575947/rR0ISyAxd.png)

### 2\. Create a Task Definition
On the left side, click **Task Definitions** and **Create new Task Definition** to access the Create new Task Definition page.

#### a. Step 1: Select launch type compatibility

- Select **FARGATE** then click on **Next Step**

#### b. Step 2: Configure task and container definitions

- Type the **Task definition name** : _docker-demo-task_
- Leave **Task role** as is (an IAM role for ECS Task definition will be created on your behalf ) 
- Select _Linux_ as **Operating system family**
- **Task execution role**, leave _Create new role_ option
- **Task memory (GB)** : 1GB
- **Task CPU (vCPU)** : _0.5vCPU_
- Click on **Add Container**, and the information below:

-- **Container name** : _dockerDemoApp_

-- **Image** : _xxx/docker-demo-app:latest_, the Docker hub image repository (xxx : your Docker hub user name)

-- **Memory Limits (MiB)** : Soft limit : _128_

-- **Port mappings** : _80 -> tcp_ and _8080 -> tcp_
![ECS Container config](https://cdn.hashnode.com/res/hashnode/image/upload/v1654310577663/5XiHPoCtq.png)
-- Click on **Add** to navigate back to **Create new Task Definition** page

- Leave all other options and click on **Create**

- Click on **View task definition** to see the created task definition details.

![Amazon ECS Task definition detail](https://cdn.hashnode.com/res/hashnode/image/upload/v1654310579437/-I3j2tAst.png)

### 3\. Run the Task Definition
In this last section, we are going to run our Docker container image.

#### Step 1
In the **Task Definition: docker-demo-task:1** page, click on **Actions** then **Run Task**, the **Run Task** page will open.

#### Step 2

![Amazon ECS Run Task](https://cdn.hashnode.com/res/hashnode/image/upload/v1654310581282/sbbXWoCRU.png)
- **Launch type** : _FARGATE_
- **Operating system family** : _Linux_
- **Task Definition** : **Familly** -> _docker-demo-task_ / **Revision** -> _1_
- **Platform version** : _LATEST_
- **Cluster** : _Demo-cluster_
- **Number of tasks** : _1_
- **Cluster VPC** : select your VPC
- **Subnets** : Choose un subnet
- **Security groups** : click on **Edit** to modify the default security group as follow :

![ECS running Task security group config](https://cdn.hashnode.com/res/hashnode/image/upload/v1654310583002/T5neoluco.png)
-- **Assigned security groups** : _Create new security group_

-- **Security group name** : _docker-demo-sg_

-- **Inbound rules for security group**: Choose _All Traffic_ **Type** and _Anywhere_ **Source**

-- Click on **Save**, and you will be redirected to the **Run Task** page.

- **Auto-assign public IP** : _ENABLED_

- Leave all other default options and click on **Run Task**.

![Amazon ECS Task running](https://cdn.hashnode.com/res/hashnode/image/upload/v1654310584709/vyhQ6TDHf.png)

## Access Spring Boot REST API via public address

Now that the deployed API's container is running, let's try to access it through a public IP address.

#### Step 1: Task details

![Amazon ECS Task click](https://cdn.hashnode.com/res/hashnode/image/upload/v1654310586610/cqyFFyDuH.png)

- In the **Demo-cluster** details page, go to **Tasks** tab. 

- In the listed tasks, click on the **Task** whose **Task definition** column is _docker-demo-task:1_, and the Task details page should open.

#### Step 2: Task public IP address
![Amazon ECS Task definition running](https://cdn.hashnode.com/res/hashnode/image/upload/v1654310588551/XNGBnIFM7.png)

- In the Task details page, copy the Public IP address

- Open a browser or Postman, paste the IP address, and append the port and /api/ to see the magic happen!

![Web browser showing Get response](https://cdn.hashnode.com/res/hashnode/image/upload/v1654310590159/E7gJxHYsx.png)


### 4\. Clean up

- In the Task Details page, click on **Stop**
- In the Demo-cluster page, click on **Delete Cluster** then follow the instructions to delete the Cluster


## In Summary
Through this post, we saw how to easily and quickly deploy a Spring Boot Application on AWS using AWS Fargate by creating a Spring Boot REST API Docker container image, pushing it on the Docker hub repository, creating and configuring Amazon ECS Cluster and Task definition witch helped us to deploy and run our REST API container image on AWS Cloud.
Thanks for the reading.


