I have an EKS cluster where I have installed the AWS Load Balancer Controller and ExternalDNS Controller.
I have created:
A Deployment for a Spring Boot application
A Service of type NodePort
An Ingress resource to create an ALB with routing rules
In this setup, the ALB is created successfully and routes traffic directly to the backend service. This works correctly.
However, I am facing an issue with CORS when my frontend application sends requests to the backend. Since ALB does not handle CORS, I decided to introduce NGINX Ingress Controller.
I installed the NGINX Ingress Controller as a NodePort service (not as a LoadBalancer, because the ALB already exists).
Now, I want to forward traffic from the ALB → NGINX service → backend service, so that NGINX can handle CORS before forwarding the request.
The problem is that the NGINX service is not getting registered in the ALB target group. In the ALB target group, it shows “Service not found”.
How to forward traffic to ngx ingress controller service? What am i doing wronf here
Nginx ingress controller install - Nodeport
# ------------------------------------------------------
# NGINX Ingress Controller (Internal – behind ALB)
# ------------------------------------------------------
resource "helm_release" "nginx_ingress" {
name = "nginx-ingress"
repository = "https://kubernetes.github.io/ingress-nginx"
chart = "ingress-nginx"
namespace = "ingress-nginx"
create_namespace = true
# --------------------------------------------------
# Controller settings
# --------------------------------------------------
set {
name = "controller.replicaCount"
value = "2"
}
# IMPORTANT:
# Do NOT expose nginx via LoadBalancer
# ALB will forward traffic to this service
set {
name = "controller.service.type"
value = "NodePort"
}
# --------------------------------------------------
# IngressClass configuration
# --------------------------------------------------
set {
name = "controller.ingressClass"
value = "nginx"
}
set {
name = "controller.ingressClassResource.name"
value = "nginx"
}
set {
name = "controller.ingressClassResource.enabled"
value = "true"
}
set {
name = "controller.ingressClassResource.default"
value = "false"
}
# --------------------------------------------------
# Allow nginx annotations (required for CORS/snippets)
# --------------------------------------------------
set {
name = "controller.allowSnippetAnnotations"
value = "true"
}
# --------------------------------------------------
# Global CORS configuration (can override per ingress)
# --------------------------------------------------
set {
name = "controller.config.enable-cors"
value = "true"
}
set {
name = "controller.config.cors-allow-origin"
value = "*"
}
set_list {
name = "controller.config.cors-allow-methods"
value = ["GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS"]
}
set_list {
name = "controller.config.cors-allow-headers"
value = ["Authorization", "Content-Type", "Accept"]
}
set {
name = "controller.config.cors-allow-credentials"
value = "true"
}
# --------------------------------------------------
# Recommended production settings
# --------------------------------------------------
set {
name = "controller.config.use-forwarded-headers"
value = "true"
}
set {
name = "controller.config.compute-full-forwarded-for"
value = "true"
}
set {
name = "controller.config.proxy-body-size"
value = "50m"
}
set {
name = "controller.config.proxy-read-timeout"
value = "120"
}
set {
name = "controller.config.proxy-send-timeout"
value = "120"
}
}
Backend app service
# Kubernetes Service Manifest (Type: Node Port Service)
resource "kubernetes_service_v1" "construction_be_app_service" {
metadata {
name = "construction-be-app-service"
namespace = "default"
annotations = {
"alb.ingress.kubernetes.io/healthcheck-path" = "/construction-expenses-manager/health"
}
}
spec {
selector = {
app = kubernetes_deployment_v1.construction_be_app_deployment.spec.0.selector.0.match_labels.app
}
port {
name = "http"
port = 80
target_port = 8080
}
type = "NodePort"
}
}
Backend app ingress for alb
resource "time_sleep" "wait_60_seconds" {
depends_on = [module.acm]
create_duration = "120s"
}
# Kubernetes Service Manifest (Type: Load Balancer)
resource "kubernetes_ingress_v1" "ingress_app1" {
metadata {
name = "app1-ingress"
annotations = {
#"alb.ingress.kubernetes.io/target-type" = "ip"
# Load Balancer Name
"alb.ingress.kubernetes.io/load-balancer-name" = "ingress-groups-construction"
# 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
## SSL Settings
# Option-1: Using Terraform jsonencode Function
"alb.ingress.kubernetes.io/listen-ports" = jsonencode([{"HTTPS" = 443}, {"HTTP" = 80}])
# SSL Redirect Setting
"alb.ingress.kubernetes.io/ssl-redirect" = 443
# External DNS - For creating a Record Set in Route53
"external-dns.alpha.kubernetes.io/hostname" = "construction.foo-app.com"
# Ingress Groups
"alb.ingress.kubernetes.io/group.name" = "foo-app.web"
"alb.ingress.kubernetes.io/group.order" = 10
}
}
spec {
ingress_class_name = "my-aws-ingress-class" # Ingress Class
# SSL Certificate Discovery using TLS
tls {
hosts = [ "*.foo-app.com" ]
}
# Rule-1: Route requests to App1 if the DNS is "construction.foo-app.com"
rule {
host = "construction.foo-app.com"
http {
path {
backend {
service {
name = "nginx-ingress-ingress-nginx-controller"
port {
number = 80
}
}
}
path = "/"
path_type = "Prefix"
}
}
}
}
}
Backend app ingress nginx
resource "kubernetes_ingress_v1" "nginx_app_ingress" {
metadata {
name = "construction-nginx-ingress"
namespace = "default"
annotations = {
# ❌ NO rewrite-target
# CORS
"nginx.ingress.kubernetes.io/enable-cors" = "true"
"nginx.ingress.kubernetes.io/cors-allow-origin" = "https://construction.foo-app.com"
"nginx.ingress.kubernetes.io/cors-allow-methods" = "GET, POST, PUT, DELETE, OPTIONS"
"nginx.ingress.kubernetes.io/cors-allow-headers" = "Authorization, Content-Type"
"nginx.ingress.kubernetes.io/cors-allow-credentials" = "true"
# Important when backend is behind proxy
"nginx.ingress.kubernetes.io/use-forwarded-headers" = "true"
}
}
spec {
ingress_class_name = "nginx"
rule {
host = "construction.foo-app.com"
http {
path {
# 🔴 Backend REQUIRES full context path
path = "/construction-expenses-manager"
path_type = "Prefix"
backend {
service {
name = kubernetes_service_v1.construction_be_app_service.metadata[0].name
port {
number = 80
}
}
}
}
}
}
}
}
here is service created by nginx controller
kubectl get svc -n ingress-nginx
nginx-ingress-ingress-nginx-controller NodePort
nginx-ingress-ingress-nginx-controller-admission ClusterIP
Note - Unlock AWS load balancer controller, i have not created any IAM role for it. I didn't think it was necessary