Applying a Single AWS ALB to Multiple Namespaces in AWS EKS

When deploying your application on EKS, using ALB to expose it is the most cloud-native approach. The AWS Load Balancer Controller simplifies the process of converting Kubernetes-native Ingress into AWS-native ALB automatically.
The Ingress objects are namespace-scoped. What happens if your applications are deployed in multiple namespaces? By default, the AWS Load Balancer Controller will create a separate ALB for each ingress object. Even if there are multiple Ingress objects in the same namespace, you will end up having an individual ALB for each of them. And that's perfectly fine.
However, if you have 50 or 100 namespaces, and your application needs to be deployed in multiple namespaces, you will incur higher costs because each ALB will charge you for the number of hours they remain active, even if you do not use them.
There is a simple trick to consolidate all Ingress objects into a single ALB, where all those routes will be combined into ALB rule groups. All you need to do is annotate each Ingress with the following labels.
alb.ingress.kubernetes.io/group.name: myapp
For all matching group.name labels in all namespaces, the AWS Load Balancer Controller will create a single ALB with multiple rules inside it. Here is a detailed example:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/backend-protocol: HTTP
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-1:987654321:certificate/37c33c94-e3be-41cc-9ec8-fd16b2873bd4
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/load-balancer-name: myapp
alb.ingress.kubernetes.io/group.name: myapp
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/ssl-redirect: "443"
alb.ingress.kubernetes.io/success-codes: "200"
alb.ingress.kubernetes.io/target-type: instance
kubernetes.io/ingress.class: alb
name: myapp-dev
namespace: myapp-dev
spec:
rules:
- host: myapp-dev.example.com
http:
paths:
- backend:
service:
name: app
port:
number: 80
path: /
pathType: Prefix
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/backend-protocol: HTTP
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-1:987654321:certificate/37c33c94-e3be-41cc-9ec8-fd16b2873bd4
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/load-balancer-name: myapp
alb.ingress.kubernetes.io/group.name: myapp
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/ssl-redirect: "443"
alb.ingress.kubernetes.io/success-codes: "200"
alb.ingress.kubernetes.io/target-type: instance
kubernetes.io/ingress.class: alb
name: myapp-stage
namespace: myapp-prstageod
spec:
rules:
- host: myapp-stage.example.com
http:
paths:
- backend:
service:
name: app
port:
number: 80
path: /
pathType: Prefix
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/backend-protocol: HTTP
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-1:987654321:certificate/37c33c94-e3be-41cc-9ec8-fd16b2873bd4
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/load-balancer-name: myapp
alb.ingress.kubernetes.io/group.name: myapp
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/ssl-redirect: "443"
alb.ingress.kubernetes.io/success-codes: "200"
alb.ingress.kubernetes.io/target-type: instance
kubernetes.io/ingress.class: alb
name: myapp-prod
namespace: myapp-prod
spec:
rules:
- host: myapp.example.com
http:
paths:
- backend:
service:
name: app
port:
number: 80
path: /
pathType: Prefix
You can find all available annotations here: https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.6/guide/ingress/annotations/




