Table of contents
No headings in the article.
In this blog, we will walk you through how to create an Amazon Elastic Kubernetes Service (EKS) cluster, bind it with Elastic File System (EFS), and deploy an Angular and Java application using Elastic Container Registry (ECR) for image repository. We will also create an RDS database to store the application data.
Before we get started, make sure you have the following prerequisites in place:
An AWS account
Terraform installed on your machine
Basic knowledge of Kubernetes, Docker, and AWS services.
Step 1: Create an EKS cluster First, we will create an EKS cluster using Terraform. To create an EKS cluster, we need to define a few resources in Terraform, such as VPC, subnets, security group, and EKS cluster itself. Here is the Terraform code to create an EKS cluster:
provider "aws" {
region = "us-west-2"
}
module "eks" {
source = "terraform-aws-modules/eks/aws"
cluster_name = "my-eks-cluster"
subnets = ["subnet-abc123", "subnet-def456", "subnet-ghi789"]
tags = {
Terraform = "true"
Environment = "dev"
}
}
In the above code, we are using the Terraform module "terraform-aws-modules/eks/aws" to create the EKS cluster. We are providing the cluster name, subnets, and tags as input to the module.
Step 2: Bind EFS with EKS cluster Now that we have created an EKS cluster, we will bind it with Elastic File System (EFS) to enable persistent storage for our application. Here is the Terraform code to create an EFS file system and mount it to the EKS cluster:
resource "aws_efs_file_system" "efs" {
creation_token = "my-efs"
encrypted = true
performance_mode = "generalPurpose"
}
resource "aws_efs_mount_target" "mount_target" {
count = length(module.eks.subnets)
file_system_id = aws_efs_file_system.efs.id
subnet_id = module.eks.subnets[count.index]
security_groups = [module.eks.cluster_security_group_id]
}
In the above code, we are creating an EFS file system and mounting it to the EKS cluster's subnets. We are also specifying the security group associated with the EKS cluster.
Step 3: Create an ECR repository Next, we will create an Elastic Container Registry (ECR) repository to store our application images. Here is the Terraform code to create an ECR repository:
resource "aws_ecr_repository" "my_ecr_repo" {
name = "my-ecr-repo"
}
In the above code, we are creating an ECR repository with the name "my-ecr-repo".
Step 4: Deploy Angular and Java application to EKS cluster Now that we have an EKS cluster, EFS, and ECR repository, we will deploy our Angular and Java application to the EKS cluster using Kubernetes manifest files. Here is an example of Kubernetes manifest files for the Angular and Java applications:
apiVersion: apps/v1
kind: Deployment
metadata:
name: angular-deployment
spec:
replicas: 2
selector:
matchLabels:
app: angular
template:
metadata:
labels:
app: angular
spec:
containers:
- name: angular
image: <ecr-repo-uri>:<tag>
ports:
- containerPort: 80
volumeMounts:
- name: efs
mountPath: /usr/share/nginx/html
volumes:
- name: efs
persistentVolumeClaim:
claimName: efs-pvc
---
apiVersion: v1
kind: Service
metadata:
name: angular-service
spec:
selector:
app: angular
ports:
- name: http
port: 80
targetPort: 80
type: LoadBalancer
In the above manifest file, we are defining a deployment with two replicas of the Angular application container. We are using the ECR repository URI and tag to specify the container image. We are also mounting the EFS volume to the container at the path "/usr/share/nginx/html". Lastly, we are defining a service of type LoadBalancer to expose the deployment to the internet.
Java Application Manifest:
apiVersion: apps/v1
kind: Deployment
metadata:
name: java-deployment
spec:
replicas: 2
selector:
matchLabels:
app: java
template:
metadata:
labels:
app: java
spec:
containers:
- name: java
image: <ecr-repo-uri>:<tag>
ports:
- containerPort: 8080
env:
- name: SPRING_DATASOURCE_URL
value: jdbc:mysql://<rds-endpoint>:3306/<database-name>
- name: SPRING_DATASOURCE_USERNAME
valueFrom:
secretKeyRef:
name: rds-secret
key: username
- name: SPRING_DATASOURCE_PASSWORD
valueFrom:
secretKeyRef:
name: rds-secret
key: password
imagePullSecrets:
- name: ecr-creds
---
apiVersion: v1
kind: Service
metadata:
name: java-service
spec:
selector:
app: java
ports:
- name: http
port: 80
targetPort: 8080
type: LoadBalancer
Continuing from the previous blog, let's take a look at the Kubernetes manifest files for deploying the Angular and Java applications to the EKS cluster.
Angular Application Manifest:
yamlCopy codeapiVersion: apps/v1
kind: Deployment
metadata:
name: angular-deployment
spec:
replicas: 2
selector:
matchLabels:
app: angular
template:
metadata:
labels:
app: angular
spec:
containers:
- name: angular
image: <ecr-repo-uri>:<tag>
ports:
- containerPort: 80
volumeMounts:
- name: efs
mountPath: /usr/share/nginx/html
volumes:
- name: efs
persistentVolumeClaim:
claimName: efs-pvc
---
apiVersion: v1
kind: Service
metadata:
name: angular-service
spec:
selector:
app: angular
ports:
- name: http
port: 80
targetPort: 80
type: LoadBalancer
In the above manifest file, we are defining a deployment with two replicas of the Angular application container. We are using the ECR repository URI and tag to specify the container image. We are also mounting the EFS volume to the container at the path "/usr/share/nginx/html". Lastly, we are defining a service of type LoadBalancer to expose the deployment to the internet.
Java Application Manifest:
yamlCopy codeapiVersion: apps/v1
kind: Deployment
metadata:
name: java-deployment
spec:
replicas: 2
selector:
matchLabels:
app: java
template:
metadata:
labels:
app: java
spec:
containers:
- name: java
image: <ecr-repo-uri>:<tag>
ports:
- containerPort: 8080
env:
- name: SPRING_DATASOURCE_URL
value: jdbc:mysql://<rds-endpoint>:3306/<database-name>
- name: SPRING_DATASOURCE_USERNAME
valueFrom:
secretKeyRef:
name: rds-secret
key: username
- name: SPRING_DATASOURCE_PASSWORD
valueFrom:
secretKeyRef:
name: rds-secret
key: password
imagePullSecrets:
- name: ecr-creds
---
apiVersion: v1
kind: Service
metadata:
name: java-service
spec:
selector:
app: java
ports:
- name: http
port: 80
targetPort: 8080
type: LoadBalancer
In the above manifest file, we are defining a deployment with two replicas of the Java application container. We are using the ECR repository URI and tag to specify the container image. We are also setting the environment variables for the database connection using the RDS endpoint, database name, and username/password from the RDS secret. Lastly, we are defining a service of type LoadBalancer to expose the deployment to the internet.
Step 5: Create an RDS database Lastly, we will create an RDS database to store the application data. Here is the Terraform code to create an RDS database:
Step 1: Create a new file named rds.tf
.
Step 2: Add the following code to the rds.tf
file to create an RDS instance.
resource "aws_db_instance" "my_rds_instance" {
allocated_storage = 20
engine = "mysql"
engine_version = "5.7"
instance_class = "db.t2.micro"
name = "my-rds-db"
username = "admin"
password = "mysecretpassword"
parameter_group_name = "default.mysql5.7"
skip_final_snapshot = true
tags = {
Name = "My RDS Instance"
}
vpc_security_group_ids = [
aws_security_group.my_rds_sg.id,
]
db_subnet_group_name = aws_db_subnet_group.my_db_subnet_group.name
}
resource "aws_db_subnet_group" "my_db_subnet_group" {
name = "my-db-subnet-group"
subnet_ids = [
aws_subnet.private_subnet_1.id,
aws_subnet.private_subnet_2.id,
]
}
resource "aws_security_group" "my_rds_sg" {
name_prefix = "my-rds-sg-"
description = "Security group for my RDS instance"
ingress {
from_port = 3306
to_port = 3306
protocol = "tcp"
security_groups = [
aws_security_group.my_ec2_sg.id,
]
}
tags = {
Name = "My RDS Security Group"
}
vpc_id = aws_vpc.my_vpc.id
}