EKS: Adding a Redirect Rule to an ALB

The Problem:

You have a service already running in EKS and the ingress is going through an ALB which is controlled already by the AWS ALB Controller. The url is company.example.com/api.

You are now asked to allow any requests to some other domain, like api.otherexample.com/api to also work on your service, because ‘convenience’. The DNS for both domains is under your control in AWS but resides in different AWS accounts. The service doesn’t care about headers at all, only the ALB rules do.

The Solution:

You control the DNS for both domains in Route 53. The first domain at company.example.com already has a default ‘A’ record pointing to the load balancer (an alias record in AWS R53).

You go to the other zone which happens to be in a different AWS account and add a ‘cname’ record pointing api.otherexample.com (which didn’t exist before as a record) to company.example.com. In theory now all traffic sent to api.otherexample.com goes to company.example.com. However, something still doesn’t work. The ALB rules are all host specific, and of course any requests coming in from api.otherexample.com now don’t have an associated rule. All you get is 404s.

We need to add a rule to the ALB without really doing anything else. Given that it is controlled by the ALB Controller inside the cluster we wouldn’t want to just ‘clickops’ our way out of this.

It turns out that we can actually add an ingress resource to the cluster to do just that, without doing anything else. (we use a generic path here but you could have limited it to /api instead).

apiVersion: networking.k8s.io/v1
 kind: Ingress
 metadata:
   name: api-otherexample-redirect
   namespace: api-namespace
   labels:
     app.kubernetes.io/instance: api-otherexample-redirect
     app.kubernetes.io/name: api-otherexample-redirect
   annotations:
     alb.ingress.kubernetes.io/actions.redirect: >
       {"Type":"redirect","RedirectConfig":{"Protocol":"HTTPS","Port":"443","Host":"company.example.com","Path":"/#{path}","Query":"#{query}","StatusCode":"HTTP_301"}}
     alb.ingress.kubernetes.io/scheme: internet-facing
 spec:
   ingressClassName: alb
   rules:
     - host: api.otherexample.com
       http:
         paths:
           - path: /*
             pathType: ImplementationSpecific
             backend:
               service:
                 name: redirect
                 port:
                   name: use-annotation

Note that the ‘name’ field for the service in the rule spec needs to match the annotation – if the service name was ‘redirect-service’ then the annotation for the redirect would need to start with ‘alb.ingress.kubernetes.io/actions.redirect-service’ instead to match.

Now the rule shows up in your ALB, and the traffic makes it to your service.