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,
- You will need
aws-cli
tools installed on your machine. - 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.
- Tag the docker image –
docker tag IMAGEID XXXXXX.dkr.ecr.us-east-1.amazonaws.com/todolist
- 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.
- Create a database instance of MySQL in AWS RDS. The configuration to create this instance will look like below:
- 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 tableusers
. - Now let’s move to ECS service and create a task definition for AWS Fargate. It will look like below: Also 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: We 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
, andspring.jpa.properties.hibernate.dialect
. That should cover our configuration for the task. - Ultimately, we will create an ECS cluster which we will use to run our task. As 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.
- 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. 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: On 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. Here 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.