Deploying the Spring PetClinic Sample Application to an EKS Cluster with ECR
Published: 2024-03-20 23:34:10

As indicated by the title, our objective is to set up the well-known Spring PetClinic Sample Application on EKS starting from the very beginning.

## Prerequisites
1. An AWS account
2. Java 17
3. Maven
4. A knowledge of Kubernetes
5. kubectl
6. eksctl
7. Docker
8. AWS CLI

## Table of Contents
1. Cloning and running the Pet Clinic Application.
2. Creating a container image from the application.
3. Upload a custom image to the Elastic Container Registry (ECR).
4. Create an Elastic Kubernetes Service (EKS) cluster.
5. Deploy the created ECR image to the EKS cluster.
6. Delete all resources.

## Clone the application
For the first step, head over to Github to clone the application 

```
git clone https://github.com/spring-projects/spring-petclinic.git
```
Next, run the application

```
cd spring-petclinic
./mvnw package
java -jar target/*.jar
```

## Creating a container image from the application.

First, create a file; we'll name it Dockerfile. Note that it should be created in the root of the project.

```
FROM eclipse-temurin:17-jdk-jammy
WORKDIR /app
COPY .mvn/ .mvn 
COPY mvnw pom.xml ./
RUN ./mvnw dependency:resolve
COPY src ./src
CMD ["./mvnw", "spring-boot:run"]
```

Now, run the following:
```
docker build -t petclinic .
```
This command builds Docker images from the Dockerfile we created.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pjfrpyx2pdgmu3r6gc7t.png)

Then,
```
docker run -p 8080:8080 petclinic
```
This command runs a command in a new container, pulls the image if needed, and starts the container.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jleogqo6fu1npbso05eb.png)

After this step, you should see the app running in your browser using **localhost:8080**. If, by chance, port 8080 is busy, you can change the port.

## Upload a custom image to the Elastic Container Registry (ECR)
To begin, you'll want to set up an ECR registry. Start by logging into the AWS console and locating ECR using the search bar. Once you've found it, click on the "Create repository" button, which will switch the interface to a form where you'll need to provide more details.

Now, assign a name to your repository. I recommend setting it to private for added security. Finally, proceed by clicking on "Create repository" using the default settings.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jcgir1pa96grn2oig3rk.png)

For the next step, we login to the newly created private repository using this command:

```
aws ecr get-login-password --region _your-chosen-region_ | docker login --username AWS --password-stdin _your-account-id_.dkr.ecr.us-east-1.amazonaws.com/_your-repository-name_
```

We now use the following command to modify the tag of our local image:

```
docker tag 87fe7e888a17 _your-account-id_.dkr.ecr.us-east-1.amazonaws.com/_your-repository-name:v1
```
**87fe7e888a17** represents the local image tag; you can find it using the `docker images` command.

Finally, we can push this image using the following command. Remember, you have the flexibility to utilize any tag in place of v1:

```
docker push _your-account-id_.dkr.ecr.us-east-1.amazonaws.com/_your-repository-name:v1_
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tgu51eulshkhc2gzd2mk.png)

## Create an Elastic Kubernetes Service (EKS) cluster

With the previous steps, it's time to create an EKS cluster and use the image created in the previous step.

To create a cluster, run the following command:

```
eksctl create cluster --name _your-cluster-name_ --region _your-chosen-region_ --node-type t2.medium
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cvlxw7d4jdgxu938gmzo.png)

Next, create a namespace. (A Kubernetes namespace is a logical abstraction used to organise and partition resources within a Kubernetes cluster.)
```
kubectl create namespace petclinic-one
```

## Deploy the created ECR image to the EKS cluster
To add a Kubernetes resource. We will use two files.

1. A deployment file pointing to our image of the ECR
2. An AWS application load balancer that is automatically created for us by a service of the type LoadBalancer and network load balancer; we will point to port 8080 since that is where our application runs.

**petclinic-deployment.yaml**
```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: petclinic
  namespace: petclinic-one
  labels:
    name: petclinic
spec:
  replicas: 1
  selector: 
    matchLabels:
      app: petclinic
  template:
    metadata:
      labels:
        app: petclinic
    spec:
      containers:
        - name: petclinic
          image: _your-account-id_.dkr.ecr.us-east-1.amazonaws.com/_your-repository-name:v1_
          ports:
            - containerPort: 80
```

**petclinic-service.yaml**
```
apiVersion: v1
kind: Service
metadata:
  name: petclinic
  namespace: petclinic-one
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
    service.beta.kubernetes.io/aws-load-balancer-internal: "false"
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
spec:
  type: LoadBalancer
  ports:
    - name: web
      port: 80
      targetPort: 8080
  selector:
    app: petclinic
```

Next, apply the following commands:

```
kubectl apply -f petclinic-deployment.yaml
kubectl apply -f petclinic-service.yaml
```

Next, check the status

```
kubectl get pods -n eks-demo-app
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/we20tw1jtkgl4sd3dk27.png)

```
kubectl get svc -n eks-demo-app
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/drhugr76dsq16vgh4g9g.png)

Now use that external IP in your browser to hit your API.

## Delete all resources
To avoid a huge bill overnight, run the following command to delete the ECR repository EKS cluster:

```
eksctl delete cluster --name petclinic --region _your-chosen-region_
```