AWS EKS Ingress Context Path Routing with Terraform
Step-01: Introduction¶
- Discuss about the Architecture we are going to build as part of this Section
- We are going to deploy all these 3 apps in kubernetes with context path based routing enabled in Ingress Controller
- /app1/* - should go to app1-nginx-nodeport-service
- /app2/* - should go to app1-nginx-nodeport-service
- /* - should go to app3-nginx-nodeport-service
- As part of this process, this respective annotation
alb.ingress.kubernetes.io/healthcheck-path:will be moved to respective application NodePort Service. - Only generic settings will be present in Ingress manifest annotations area
04-ALB-Ingress-ContextPath-Based-Routing.yml
Step-02: Review Nginx App1, App2 & App3 Deployment & Service¶
- Differences for all 3 apps will be only two fields from kubernetes manifests perspective and their naming conventions
- Kubernetes Deployment: Container Image name
- Kubernetes Node Port Service: Health check URL path
- App1 Nginx: 01-Nginx-App1-Deployment-and-NodePortService.yml
- image: stacksimplify/kube-nginxapp1:1.0.0
- Annotation: alb.ingress.kubernetes.io/healthcheck-path: /app1/index.html
- App2 Nginx: 02-Nginx-App2-Deployment-and-NodePortService.yml
- image: stacksimplify/kube-nginxapp2:1.0.0
- Annotation: alb.ingress.kubernetes.io/healthcheck-path: /app2/index.html
- App3 Nginx: 03-Nginx-App3-Deployment-and-NodePortService.yml
- image: stacksimplify/kubenginx:1.0.0
- Annotation: alb.ingress.kubernetes.io/healthcheck-path: /index.html
Step-03: Create ALB Ingress Context path based Routing Kubernetes manifest¶
- 04-ALB-Ingress-ContextPath-Based-Routing.yml
# Annotations Reference: https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/ingress/annotations/ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-cpr-demo annotations: # Load Balancer Name alb.ingress.kubernetes.io/load-balancer-name: cpr-ingress # Ingress Core Settings #kubernetes.io/ingress.class: "alb" (OLD INGRESS CLASS NOTATION - STILL WORKS BUT RECOMMENDED TO USE IngressClass Resource) alb.ingress.kubernetes.io/scheme: internet-facing # Health Check Settings alb.ingress.kubernetes.io/healthcheck-protocol: HTTP alb.ingress.kubernetes.io/healthcheck-port: traffic-port #Important Note: Need to add health check path annotations in service level if we are planning to use multiple targets in a load balancer alb.ingress.kubernetes.io/healthcheck-interval-seconds: '15' alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '5' alb.ingress.kubernetes.io/success-codes: '200' alb.ingress.kubernetes.io/healthy-threshold-count: '2' alb.ingress.kubernetes.io/unhealthy-threshold-count: '2' spec: ingressClassName: my-aws-ingress-class # Ingress Class rules: - http: paths: - path: /app1 pathType: Prefix backend: service: name: app1-nginx-nodeport-service port: number: 80 - path: /app2 pathType: Prefix backend: service: name: app2-nginx-nodeport-service port: number: 80 - path: / pathType: Prefix backend: service: name: app3-nginx-nodeport-service port: number: 80 # Important Note-1: In path based routing order is very important, if we are going to use "/*", try to use it at the end of all rules. # 1. If "spec.ingressClassName: my-aws-ingress-class" not specified, will reference default ingress class on this kubernetes cluster # 2. Default Ingress class is nothing but for which ingress class we have the annotation `ingressclass.kubernetes.io/is-default-class: "true"`
Step-04: Deploy all manifests and test¶
# Change Directory
cd 28-EKS-Ingress-Context-Path-Routing
# Deploy Kubernetes manifests
kubectl apply -f 03-kube-manifests-ingress-cpr
# List Pods
kubectl get pods
# List Services
kubectl get svc
# List Ingress Load Balancers
kubectl get ingress
# Describe Ingress and view Rules
kubectl describe ingress ingress-cpr-demo
# Verify AWS Load Balancer Controller logs
kubectl -n kube-system get pods
kubectl -n kube-system logs -f aws-load-balancer-controller-794b7844dd-8hk7n
Step-05: Verify Application Load Balancer on AWS Management Console**¶
- Verify Load Balancer
- In Listeners Tab, click on View/Edit Rules under Rules
- Verify Target Groups
- GroupD Details
- Targets: Ensure they are healthy
- Verify Health check path
- Verify all 3 targets are healthy)
Step-06: Clean Up¶
Step-07: c1-versions.tf¶
- Project Folder: 04-ingress-cpr-terraform-manifests
- Create DynamoDB Table
dev-aws-lbc-ingress - Create S3 Bucket Key as
dev/aws-lbc-ingress/terraform.tfstate# Terraform Settings Block terraform { required_version = ">= 1.0.0" required_providers { aws = { source = "hashicorp/aws" version = "~> 4.12" } kubernetes = { source = "hashicorp/kubernetes" version = "~> 2.11" } } # Adding Backend as S3 for Remote State Storage backend "s3" { bucket = "terraform-on-aws-eks" key = "dev/aws-lbc-ingress/terraform.tfstate" region = "us-east-1" # For State Locking dynamodb_table = "dev-aws-lbc-ingress" } }
Step-08: c2-remote-state-datasource.tf¶
- Project Folder: 04-ingress-cpr-terraform-manifests
Step-09: c3-providers.tf¶
- Project Folder: 04-ingress-cpr-terraform-manifests
# Terraform AWS Provider Block provider "aws" { region = "us-east-1" } data "aws_eks_cluster" "cluster" { name = data.terraform_remote_state.eks.outputs.cluster_id } data "aws_eks_cluster_auth" "cluster" { name = data.terraform_remote_state.eks.outputs.cluster_id } # Terraform Kubernetes Provider provider "kubernetes" { host = data.terraform_remote_state.eks.outputs.cluster_endpoint cluster_ca_certificate = base64decode(data.terraform_remote_state.eks.outputs.cluster_certificate_authority_data) token = data.aws_eks_cluster_auth.cluster.token }
Step-10: c4-kubernetes-app1-deployment.tf¶
- Project Folder: 04-ingress-cpr-terraform-manifests
# Kubernetes Deployment Manifest resource "kubernetes_deployment_v1" "myapp1" { metadata { name = "app1-nginx-deployment" labels = { app = "app1-nginx" } } spec { replicas = 1 selector { match_labels = { app = "app1-nginx" } } template { metadata { labels = { app = "app1-nginx" } } spec { container { image = "stacksimplify/kube-nginxapp1:1.0.0" name = "app1-nginx" port { container_port = 80 } } } } } }
Step-11: c5-kubernetes-app2-deployment.tf¶
- Project Folder: 04-ingress-cpr-terraform-manifests
# Kubernetes Deployment Manifest resource "kubernetes_deployment_v1" "myapp2" { metadata { name = "app2-nginx-deployment" labels = { app = "app2-nginx" } } spec { replicas = 1 selector { match_labels = { app = "app2-nginx" } } template { metadata { labels = { app = "app2-nginx" } } spec { container { image = "stacksimplify/kube-nginxapp2:1.0.0" name = "app2-nginx" port { container_port = 80 } } } } } }
Step-12: c6-kubernetes-app3-deployment.tf¶
- Project Folder: 04-ingress-cpr-terraform-manifests
# Kubernetes Deployment Manifest resource "kubernetes_deployment_v1" "myapp3" { metadata { name = "app3-nginx-deployment" labels = { app = "app3-nginx" } } spec { replicas = 1 selector { match_labels = { app = "app3-nginx" } } template { metadata { labels = { app = "app3-nginx" } } spec { container { image = "stacksimplify/kubenginx:1.0.0" name = "app3-nginx" port { container_port = 80 } } } } } }
Step-13: c7-kubernetes-app1-nodeport-service.tf¶
- Project Folder: 04-ingress-cpr-terraform-manifests
# Kubernetes Service Manifest (Type: Node Port Service) resource "kubernetes_service_v1" "myapp1_np_service" { metadata { name = "app1-nginx-nodeport-service" annotations = { "alb.ingress.kubernetes.io/healthcheck-path" = "/app1/index.html" } } spec { selector = { app = kubernetes_deployment_v1.myapp1.spec.0.selector.0.match_labels.app } port { name = "http" port = 80 target_port = 80 } type = "NodePort" } }
Step-14: c8-kubernetes-app2-nodeport-service.tf¶
- Project Folder: 04-ingress-cpr-terraform-manifests
# Kubernetes Service Manifest (Type: Node Port Service) resource "kubernetes_service_v1" "myapp2_np_service" { metadata { name = "app2-nginx-nodeport-service" annotations = { "alb.ingress.kubernetes.io/healthcheck-path" = "/app2/index.html" } } spec { selector = { app = kubernetes_deployment_v1.myapp2.spec.0.selector.0.match_labels.app } port { name = "http" port = 80 target_port = 80 } type = "NodePort" } }
Step-15: c9-kubernetes-app3-nodeport-service.tf¶
- Project Folder: 04-ingress-cpr-terraform-manifests
# Kubernetes Service Manifest (Type: Node Port Service) resource "kubernetes_service_v1" "myapp3_np_service" { metadata { name = "app3-nginx-nodeport-service" annotations = { "alb.ingress.kubernetes.io/healthcheck-path" = "/index.html" } } spec { selector = { app = kubernetes_deployment_v1.myapp3.spec.0.selector.0.match_labels.app } port { name = "http" port = 80 target_port = 80 } type = "NodePort" } }
Step-16: c10-kubernetes-ingress-service.tf¶
- Project Folder: 04-ingress-cpr-terraform-manifests
# Kubernetes Service Manifest (Type: Load Balancer) resource "kubernetes_ingress_v1" "ingress" { metadata { name = "ingress-cpr" annotations = { # Load Balancer Name "alb.ingress.kubernetes.io/load-balancer-name" = "ingress-cpr" # Ingress Core Settings "alb.ingress.kubernetes.io/scheme" = "internet-facing" # Health Check Settings "alb.ingress.kubernetes.io/healthcheck-protocol" = "HTTP" "alb.ingress.kubernetes.io/healthcheck-port" = "traffic-port" #Important Note: Need to add health check path annotations in service level if we are planning to use multiple targets in a load balancer "alb.ingress.kubernetes.io/healthcheck-interval-seconds" = 15 "alb.ingress.kubernetes.io/healthcheck-timeout-seconds" = 5 "alb.ingress.kubernetes.io/success-codes" = 200 "alb.ingress.kubernetes.io/healthy-threshold-count" = 2 "alb.ingress.kubernetes.io/unhealthy-threshold-count" = 2 } } spec { ingress_class_name = "my-aws-ingress-class" # Ingress Class default_backend { service { name = kubernetes_service_v1.myapp3_np_service.metadata[0].name port { number = 80 } } } rule { http { path { backend { service { name = kubernetes_service_v1.myapp1_np_service.metadata[0].name port { number = 80 } } } path = "/app1" path_type = "Prefix" } path { backend { service { name = kubernetes_service_v1.myapp2_np_service.metadata[0].name port { number = 80 } } } path = "/app2" path_type = "Prefix" } } } } }
Step-17: Execute Terraform Commands¶
# Change Directory
cd 04-ingress-basics-terraform-manifests
# Terraform Initialize
terraform init
# Terraform Validate
terraform validate
# Terraform Plan
terraform plan
# Terraform Apply
terraform apply -auto-approve
Step-18: Verify Ingress Service¶
# List Pods
kubectl get pods
# List Services
kubectl get svc
# List Ingress Load Balancers
kubectl get ingress
# Describe Ingress and view Rules
kubectl describe ingress ingress-cpr-demo
# Verify AWS Load Balancer Controller logs
kubectl -n kube-system get pods
kubectl -n kube-system logs -f aws-load-balancer-controller-794b7844dd-8hk7n
# Access Application
http://<ALB-DNS-URL>/app1/index.html
http://<ALB-DNS-URL>/app2/index.html
http://<ALB-DNS-URL>/
Step-19: Clean-Up Ingress¶
# Change Directory
cd 04-ingress-cpr-terraform-manifests
# Terraform Destroy
terraform apply -destroy -auto-approve
rm -rf .terraform*
Step-20: Don't Clean-Up LBC Controller & EKS Cluster¶
- Dont destroy the Terraform Projects in below two folders
- Terraform Project Folder: 01-ekscluster-terraform-manifests
- Terraform Project Folder: 02-lbc-install-terraform-manifests
- We are going to use them for all upcoming Usecases.
🎉 New Course
Ultimate DevOps Real-World Project Implementation on AWS
$15.99
$84.99
81% OFF
DEVOPS2026FEB
Enroll Now on Udemy →
🎉 Offer