Skip to content

AWS EKS Ingress Basics automate with Terraform

Step-01: Introduction

  • Discuss about the Application Architecture which we are going to deploy
  • Understand the following Ingress Concepts
  • Annotations
  • ingressClassName
  • defaultBackend
  • rules

Step-02: Review App1 Deployment kube-manifest

  • File Location: 03-kube-manifests-ingress-basics/01-Nginx-App1-Deployment-and-NodePortService.yml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: app3-nginx-deployment
      labels:
        app: app3-nginx
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: app3-nginx
      template:
        metadata:
          labels:
            app: app3-nginx
        spec:
          containers:
            - name: app3-nginx
              image: stacksimplify/kubenginx:1.0.0
              ports:
                - containerPort: 80
    

Step-03: Review App1 NodePort Service

  • File Location: 03-kube-manifests-ingress-basics/01-Nginx-App1-Deployment-and-NodePortService.yml
    apiVersion: v1
    kind: Service
    metadata:
      name: app3-nginx-nodeport-service
      labels:
        app: app3-nginx
      annotations:
    #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-path: /index.html
    spec:
      type: NodePort
      selector:
        app: app3-nginx
      ports:
        - port: 80
          targetPort: 80
    

Step-04: Review Ingress kube-manifest with Default Backend Option

  • Annotations
  • File Location: 03-kube-manifests-ingress-basics/02-ALB-Ingress-Basic.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-basics
      labels:
        app: app3-nginx
      annotations:
        # Load Balancer Name
        alb.ingress.kubernetes.io/load-balancer-name: ingress-basics
        #kubernetes.io/ingress.class: "alb" (OLD INGRESS CLASS NOTATION - STILL WORKS BUT RECOMMENDED TO USE IngressClass Resource) # Additional Notes: https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.3/guide/ingress/ingress_class/#deprecated-kubernetesioingressclass-annotation
        # 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
        alb.ingress.kubernetes.io/healthcheck-path: /index.html    
        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
      defaultBackend:
        service:
          name: app3-nginx-nodeport-service
          port:
            number: 80                  
    
    
    # 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-05: Deploy kube-manifests and Verify

# Configure kubeconfig for kubectl
aws eks --region <region-code> update-kubeconfig --name <cluster_name>
aws eks --region us-east-1 update-kubeconfig --name hr-dev-eksdemo1

# Verify Kubernetes Worker Nodes using kubectl
kubectl get nodes
kubectl get nodes -o wide

# Change Directory
cd 27-EKS-Ingress-Basics

# Deploy kube-manifests
kubectl apply -f 03-kube-manifests-ingress-basics/

# Verify k8s Deployment and Pods
kubectl get deploy
kubectl get pods

# Verify Ingress (Make a note of Address field)
kubectl get ingress
Obsevation: 
1. Verify the ADDRESS value, we should see something like "ingress-basics-1334515506.us-east-1.elb.amazonaws.com"

# Describe Ingress Controller
kubectl describe ingress ingress-nginxapp1
Observation:
1. Review Default Backend and Rules

# List Services
kubectl get svc

# Verify Application Load Balancer using 
Goto AWS Mgmt Console -> Services -> EC2 -> Load Balancers
1. Verify Listeners and Rules inside a listener
2. Verify Target Groups

# Access App using Browser
kubectl get ingress
http://<ALB-DNS-URL>
or
http://<INGRESS-ADDRESS-FIELD>

# Sample from my environment (for reference only)
http://ingress-basics-154912460.us-east-1.elb.amazonaws.com

# Verify AWS Load Balancer Controller logs
kubectl get po -n kube-system 
## POD1 Logs: 
kubectl -n kube-system logs -f <POD1-NAME>
kubectl -n kube-system logs -f aws-load-balancer-controller-65b4f64d6c-h2vh4
##POD2 Logs: 
kubectl -n kube-system logs -f <POD2-NAME>
kubectl -n kube-system logs -f aws-load-balancer-controller-65b4f64d6c-t7qqb

Step-06: Clean Up

# Delete Kubernetes Resources
kubectl delete -f 03-kube-manifests-ingress-basics/

Step-07: c1-versions.tf

  • Project Folder: 04-ingress-basics-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-basics-terraform-manifests
    # Terraform Remote State Datasource - Remote Backend AWS S3
    data "terraform_remote_state" "eks" {
      backend = "s3"
      config = {
        bucket = "terraform-on-aws-eks"
        key    = "dev/eks-cluster/terraform.tfstate"
        region = "us-east-1"
      }
    }
    

Step-09: c3-providers.tf

  • Project Folder: 04-ingress-basics-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-app3-deployment.tf

  • Project Folder: 04-ingress-basics-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-11: c5-kubernetes-app3-nodeport-service.tf

  • Project Folder: 04-ingress-basics-terraform-manifests
    # Kubernetes Service Manifest (Type: Node Port Service)
    resource "kubernetes_service_v1" "myapp3_np_service" {
      metadata {
        name = "app3-nginx-nodeport-service"
        annotations = {
          #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-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-12: c6-kubernetes-ingress-service.tf

  • Project Folder: 04-ingress-basics-terraform-manifests
    # Kubernetes Service Manifest (Type: Load Balancer)
    resource "kubernetes_ingress_v1" "ingress" {
      metadata {
        name = "ingress-basics"
        annotations = {
          # Load Balancer Name
          "alb.ingress.kubernetes.io/load-balancer-name" = "ingress-basics"
          # 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-path" =  "/index.html"
          "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
            }
          }
        }
      }
    }
    

Step-13: 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-14: Verify Ingress Service

# Verify k8s Deployment and Pods
kubectl get deploy
kubectl get pods

# Verify Ingress (Make a note of Address field)
kubectl get ingress
Obsevation: 
1. Verify the ADDRESS value, we should see something like "ingress-basics-1334515506.us-east-1.elb.amazonaws.com"

# List Services
kubectl get svc

# Verify Application Load Balancer using 
Goto AWS Mgmt Console -> Services -> EC2 -> Load Balancers
1. Verify Listeners and Rules inside a listener
2. Verify Target Groups

# Access App using Browser
kubectl get ingress
http://<ALB-DNS-URL>
or
http://<INGRESS-ADDRESS-FIELD>

# Sample from my environment (for reference only)
http://ingress-basics-154912460.us-east-1.elb.amazonaws.com

Step-15: Clean-Up Ingress

# Change Directory 
cd 04-ingress-basics-terraform-manifests

# Terraform Destroy
terraform apply -destroy -auto-approve
rm -rf .terraform*

Step-16: 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