Handle URL redirects in an AKS Sitecore multisite solution with Ingress-NGINX Controller using GitOps – Part 1

Dear Sitecorians, recently Sitecore released XM Cloud. Interesting times ahead.

Today’s post will be about using NGINX to handle rewrites/redirects for your Sitecore multisite solution. The flow is this: We will have a “manifest repo,” where the rewrite rules reside. Then, ArgoCD (GitOps) will listen to any changes and deploy them to our Kubernetes cluster in AKS, which means that every time a change is made in the rewrite rules, they will be automatically deployed to the Kubernetes cluster.

NGINX is very powerful, and (as always) you can handle/set up redirects/rewrites in many ways, as you can see in this post – Kubernetes Nginx Ingress: Traffic Redirect Using Annotations Demystified. We want to be able to add many “rewrite rules” per site, and the best suitable seems to be the annotation – Configuration Snippet. Together with another annotation gem – Use Regex, we are now ready to do some serious rewriting 😊

So let’s begin! I will assume you already have NGINX(Controller) running in your Kubernetes cluster. Next will be to set up/create the ingress manifests for your sites. We will use Kustomize(Helm is also a good option). Instead of having one big Ingress definition for all your sites(including CM and CD), you should instead break it down to several ingress definitions – One ingress definition per site. Say your multisite solution contains 4 sites, then you should have one ingress definition per site. Since we are using Kustomize the setup could look like something like this:

my-manifests (folder)
– ingress-site-a(folder)
– – kustomization.yaml
– – site.yaml
– – patches (folder)
– – – rewrite-rules-configuration.yaml
– ingress-site-b(folder)
– – kustomization.yaml
– – site.yaml
– – patches (folder)
– – – rewrite-rules-configuration.yaml

Let’s have a look at the kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- site.yaml  

patchesStrategicMerge:
- patches/rewrite-rules-configuration.yaml

The (ingress definition) file, site.yaml contains the ingress basics for the site. With the use of patchesStrategicMerge, we will be able to merge rewrite-rules-configuration.yaml into the site.yaml

Let’s have a look at the site.yaml (ingress definition) for site a:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: sitea-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/custom-http-errors: "503"
  labels:
    app.kubernetes.io/instance: sitea-ingress
spec:
  rules:
  - host: sitea.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nodejs-sitea
            port:
              number: 3000 
      
  tls:
  - secretName: global-sitea-tls
    hosts:
     - sitea.com

Notice the name, sitea-ingress. Also notice the annotation, Use Regex. It will allow us to use Reg Exp in the rewrite rules.

Finally the rewrite-rules-configuration.yaml. Here we have some rewrite rules 😊

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: sitea-ingress
  annotations:
    nginx.ingress.kubernetes.io/configuration-snippet: |
      rewrite ^/someoldpage.html /the-new-page permanent;
      rewrite ^/something-not-ready-yet /under-construction redirect;
      rewrite ^/old/products/(.*)$ /shiny-new/products/$1 permanent;

Here we are using the annotation, Configuration Snippet. It allows us to add a bunch of rewrite/redirect rules.

The first rule is a classic permanent(301) rule. The second is a temporary rule – redirect. The third is using Reg Exp. And you can do so much more here 😊

To apply the ingress definition(kustomization) to our Kubernetes cluster, we would probably do something like this:

kubectl apply -k .\my-manifests\ingress-site-a

And that’s it. We now have rewrite rules up and running for Site A 😊

Now, let’s take this a step further. What if we could automate this? Say whenever there is a change in the rewrite-rules-configuration.yaml file, it would automatically be deployed/applied to the Kubernetes cluster. GitOps to the rescue 😊

There are some GitOps tools, but the big ones seem to be ArgoCD and FluxCD. My favourite is ArgoCD, and Argo has some pretty cool tools in their toolbox – Argo WorkflowsArgo Rollouts, and Argo Events. Check out my favourite DevOps channel – DevOpsToolkit. And listen to the beauty of Argo!

So we will also need ArgoCD, the wonderful GitOps tool which will automatically deploy any manifest changes to your Kubernetes cluster. To set it up, just follow the instructions from ArgoCD.

Next is to create our manifest repo. A good practice is to have a GitOps repo(manifest repo) for each environment(test, stage, prod, and so on). Don’t forget to connect your repo to ArgoCD.

It’s time to add our ingress definitions and kustomize files to the repo. We will have the same structure as before:

my-manifests (folder)
– apps
– – ingress-site-a.yaml
– – ingress-site-b.yaml

– ingress-site-a(folder)
– – kustomization.yaml
– – site.yaml
– – patches (folder)
– – – rewrite-rules-configuration.yaml
– ingress-site-b(folder)
– – kustomization.yaml
– – site.yaml
– – patches (folder)
– – – rewrite-rules-configuration.yaml

We will add a new folder – apps. Here we will place the “ArgoCD apps”, which will listen to changes and automatically sync to our Kubernetes cluster.

Let’s look at the “ArgoCD app” file – ingress-site-a.yaml:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: ingress-site-a
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/my-organization/My.GitOps.Test
    targetRevision: main
    path: my-manifests/ingress-site-a
  destination:
    server: https://kubernetes.default.svc
    namespace: my-cool-sitecore-sites
  syncPolicy:
    automated:
      selfHeal: true  
      prune: false

In “source”, we tell the URL to our repo, what branch to use, and the path to the ingress(kustomize) files. And “destination” is our Kubernetes cluster and the namespace.

The last part does the magic – syncPolicy. It will automatically sync any changes.

What is left is to apply/deploy the ArgoCD apps to our Kubernetes cluster:

kubectl apply -f .\my-manifests\apps\ingress-site-a.yaml
kubectl apply -f .\my-manifests\apps\ingress-site-b.yaml

And now it’s all automated. Whenever we make a change in the “manifests repo” ArgoCD will automatically deploy the change. How cool is that! 😊

Stay tuned for part 2, where we’ll go one step further and do something crazy.

That’s all for now folks 😊


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.