
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 Workflows, Argo 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 😊