How to Deploy Spring Boot Application on AWS ECS

In this post, I will show how we can deploy a spring boot application on AWS ECS (Elastic Container Service). ECS is one of the amazon web services that is mainly used to run the applications. It is an alternative to use EC2 instances directly.

What is ECS?

ECS is a container orchestration service. ECS allows you to run your container. You can also easily build ECS cluster using AWS Farget. Farget removes the need to provision and manages a server. The advantage of using ECS is that you don’t have to decide which server EC2 instance to use, the service does that for you. It also improves security through application isolation.

As part of this demo, I will show step by step how you can deploy your spring boot application on the ECS cluster with AWS Fargate.

Spring Boot Application

I will not be showing you how to build a Spring Boot application, but you can visit my other posts about it. In this application, we will have a controller that will show a to-do list. We will also have form-based authentication using the MySQL database. The config method in security config will look like below:


    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception
    {
        httpSecurity
                .authorizeRequests()
                .antMatchers("/js/**","/css/**","/img/**").permitAll()
                .antMatchers("/signup","/forgotpassword")
                .permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
                .logout()
                .logoutUrl("/logout")
                .logoutSuccessHandler(logoutSuccessHandler)
                .deleteCookies("JSESSIONID")
                .permitAll()
                .and()
                .csrf();

    }

So, as you see above, we will allow anyone to access signup and forgotpassword pages.  Equally, anyone can access the login page. We will use our custom login form located on the login page.

If the user successfully logs in, the user will see a static TO-DO list page showing TO-DO list.

As part of this demo, we will also be creating a MySQL database in AWS RDS. Our application running in AWS Fargate ECS cluster will access this MySQL database for storing users and user authentication.

Building a docker container for Spring Boot Application

We will create a docker file.

FROM openjdk:8-jdk-alpine
COPY ./build/libs/todolist-0.0.1-SNAPSHOT.war todolist-0.0.1-SNAPSHOT.war
ENTRYPOINT ["java", "-jar","todolist-0.0.1-SNAPSHOT.war"]

Basically, we pull Java 8 image and copy the war file from our project into the docker instance. We also define the entry-point.

Command to create a docker image

docker build -t todolist .

If you want to run your application through docker locally, you can use the following command:

docker run -p 8743:8743 todolist

So to deploy our application on ECS, we will need to push this docker image to the elastic container repository (ECR).

Usually building a docker image and pushing it to ECR is all part of CI/CD. I will not be covering CI/CD in this post.

To push this docker image to ECR,

  1. You will need aws-cli tools installed on your machine.
  2. Create a repository in ECR

Now on the command line, execute this command to authenticate docker client to ECR repository

aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin XXXXXXX.dkr.ecr.us-east-1.amazonaws.com

Once we are authenticated, we can tag and push docker images to the ECR repository.

  1. Tag the docker image – docker tag IMAGEID XXXXXX.dkr.ecr.us-east-1.amazonaws.com/todolist
  2. Push the docker image – docker push XXXXX.dkr.ecr.us-east-1.amazonaws.com/todolist

Now our docker image is in ECR.

Deploying docker image in ECS

Before we can deploy our docker image in ECS, we will have to execute three steps.

  1. Create a database instance of MySQL in AWS RDS. The configuration to create this instance will look like below: Deploying Spring Boot Application on AWS ECS- Database Configuration
  2. Once you create the database, you will have database instance server and port available that you can use to connect to database server either through Database Administration UI or command line. Create a database simplifyingspringsecurity and database table users.
  3. Now let’s move to ECS service and create a task definition for AWS Fargate. It will look like below: Deploying Spring Boot Application on AWS ECS - Launch TypeDeploying Spring Boot Application on AWS ECS - TaskAlso remember to create a IAM role beforehand which should have a permission policy `AmazonECSTaskExecutionRolePolicy` . In the same task definition, we will have to add our container and the properties for this container. They will look like below: Deploying Spring Boot Application on AWS ECS - ContainerWe have mapped two ports 8743 and 80 from our host to the container. In the same container, also add environment properties if you want to override properties for your data source. These properties include spring.datasource.url, spring.datasource.username, spring.datasource.password, spring.datasource.driver-class-name, and spring.jpa.properties.hibernate.dialect.  That should cover our configuration for the task.
  4. Ultimately, we will create an ECS cluster which we will use to run our task. Deploying Spring Boot Application on ECS - Fargate ClusterAs you see, we have chosen a AWS Fargate based cluster. On the next step you provide a name for the cluster and click “Create” and that should create a cluster.
  5. Once the cluster is configured and running, we can go on the tab “Tasks” and click “Run new task”. Here we will provide few more configurations that will allow us to run our task in a way so that we can access the application once the task starts running. Deploying Spring Boot Application on ECS - Task Run We have security groups defined here, but it also provides the option to create a new security group when running. In this security group, you should choose which type of protocol and ports you want to allow for access. In this case, we want our port 8743 for internet and TCP. Now click ‘Run Task’ and that should start the task. Once the task starts, we will be able to see the logs from cloud watch as below: AWS Cloudwatch - LogsOn this basis, if you look at logs, now our application is running successfully on port 8743. Now we can access the application using the public IP that the Fargate task provided. Spring Boot Application HomePageHere we go, we have our application up and running.

Learnings

ECS can be complicated with the number of configurations a user can do when deploying an application. To keep this simple, just think this way AWS Cloud -> VPC -> Subnet -> ECS -> Fargate -> Task.

Conclusion

In this post, I showed how to deploy a Spring Boot Application on AWS ECS. As much as it seems straightforward, the issue comes up with the combination of configurations you can do in AWS ECS. Once you understand how the cloud handles private networks, it becomes simpler.