Redirect all traffic from port 80 to port 443 using the aws-load-balancer-controller

Hunter Thompson
3 min readNov 22, 2020

Sample ingress manifest :

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: "nginx"
namespace: "default"
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/certificate-arn: xxxxxxxxxxxxxx
spec:
rules:
- host: nginx.example.com
http:
paths:
- path: /*
backend:
serviceName: "nginx-svc"
servicePort: 80

The problem with this configuration is that it creates the same forwarding rule on both port 80, and port 443 listeners, but, we want to redirect all traffic from port 80 to port 443.

So, for this we can define an object that looks like this :

apiVersion: extensions/v1beta1 
kind: Ingress
metadata:
name: "nginx"
namespace: "default"
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internal
alb.ingress.kubernetes.io/certificate-arn: xxxxxxxxxxxxx
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
spec:
rules:
- host: nginx.example.com
http:
paths:
- path: /*
backend:
serviceName: ssl-redirect
servicePort: use-annotation
- path: /*
backend:
serviceName: "nginx-svc"
servicePort: 80

Notice how we added a new annotation called ssl-redirect , this annotation is responsible for redirecting all traffic from port 80 to port 443 for this host, and this is the only rule that is not duplicated for all listeners, only the port 80 will have this rule.

But another problem arises when we use the sample config above. Each host will have 2 rules in the ALB. One that redirects from port 80 to port 443 inside the port 80 listener, and one in port 443 that forwards to the target group.

If we have a lot of hosts inside a single ALB, we cannot afford to have host-specific rules for redirection, we need to redirect all traffic, regardless of the host or path, to the port 443.

Solution :

The solution would be to use the new annotation that was released in v2.0.0 of the aws-load-balancer-controller called group.name . This annotation allows us to use the same ALB for multiple different ingress objects irregardless of namespace, or name.

We will create 2 ingress manifests, one for port 80, and one for port 443 and we will use the same group.name annotation for each manifest.

This manifest will create a rule that redirects all traffic from /* path and by default all hosts in the 80 listener to the 443 listener.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: "nginx-p80"
namespace: "default"
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]'
alb.ingress.kubernetes.io/actions.ssl-redirect: >
{"type": "redirect", "redirectconfig": { "protocol": "HTTPS", "port": "443", "statuscode": "HTTP_301"}}
alb.ingress.kubernetes.io/group.name: nginx
spec:
rules:
- http:
paths:
- path: /*
backend:
serviceName: ssl-redirect
servicePort: use-annotation

This manifest will hold all our hosts , the forwarding rules, and the certificate information.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: "nginx-p443"
namespace: "default"
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]'
alb.ingress.kubernetes.io/certificate-arn: xxxxxxxxxxxxxx
alb.ingress.kubernetes.io/group.name: nginx
spec:
rules:
- host: nginx.example.com
http:
paths:
- path: /*
backend:
serviceName: "nginx-svc"
servicePort: 80

What we need to keep in mind is to use the same group.name for each ingress object.

This freed up 64 rules for us because we had 65 hosts that were using the same ALB, and as we all know, AWS ALB is capped at 100 rules.

--

--