Kubernetes: AWS ALB Ingress Controller – add redirect to another domain

By | 10/09/2020
 

We have an application – an old version, and a new one, and two domains for them.

The application is working on AWS Elastic Kubernetes Service, behind an AWS LoadBalancer created with AWS ALB Ingress Controller.

The task is to create a redirect from the old domain’s Ingress to a new LoadBalancer:

  • old URL: dev.api.old-example.com
  • new URL: dev.api.new-example.com

On the AWS LoadBalancer this can be done via Listener Rules but in the case of the Kubernetes AWS ALB Ingress Controller – we will use the Ingress annotations which will be applied to a LoadBalancer’s Listener.

At this moment our Ingress resource of the old application has the following manifest:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig":
      { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-east-2:534***385:certificate/2811e48b-***-971272859a74
    alb.ingress.kubernetes.io/healthcheck-path: /is-running
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
    alb.ingress.kubernetes.io/load-balancer-attributes: access_logs.s3.enabled=true,access_logs.s3.bucket=access-logs-eksdev1,access_logs.s3.prefix=apps
    alb.ingress.kubernetes.io/scheme: internet-facing
    kubernetes.io/ingress.class: alb
...
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: ssl-redirect
          servicePort: use-annotation
        path: /*
      - backend:
          serviceName: apps-backend-svc
          servicePort: 80
        path: /*

And its 443 port Listener sends traffic to an AWS TargetGroup with Kubernetes WorkerNodes:

Now, add a new annotation describing the 301 redirect to the dev.api.new-example.com domain:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    alb.ingress.kubernetes.io/actions.redirect-to-quiz: '{"Type":"redirect","RedirectConfig":{"Host":"dev.api.new-example.com","Path":"/#{path}","Port":"443","Protocol":"HTTPS","Query":"#{query}","StatusCode":"HTTP_301"}}'
...

Next, need to update the spec.rules.

Instead of the redirect to a backend’s Service which is sending traffic to pods with the old application like it is now:

...
      - backend:
          serviceName: apps-backend-svc
          servicePort: 80
        path: /*
...

Specify another redirect with the annotation defined above:

...
      - backend:
          serviceName: redirect-to-quiz
          servicePort: use-annotation
        path: /*
...

Save it, and go to check the Listener again:

And go to check how the redirect is working:

curl -LvI https://dev.api.old-example.com
...
< HTTP/2 301
HTTP/2 301
< server: awselb/2.0
server: awselb/2.0
...
< location: https://dev.api.new-example.com:443/
location: https://dev.api.new-example.com:443/
<
* Connection #0 to host dev.api.old-example.com left intact
* Issue another request to this URL: 'https://dev.api.new-example.com:443/'
*   Trying 3.***.***.151:443...
* Connected to dev.api.new-example.com (3.***.***.151) port 443 (#1)
...

Well, “It works!” (c)

Done.