Deploy Neo4j on AKS with TLS and reverse proxy.

Amit Gujar
5 min readDec 28, 2023

Before we continue, let me explain the situation. I wanted to deploy Neo4j on Azure and initially tried using the Azure Container Instance. While everything was working perfectly, it didn't support HTTPS connections, which was a deal-breaker for me. I considered using the application gateway, but it didn't support the bolt protocol. After some research, I found that the only viable option was to use AKS. In this tutorial, we will take a detailed look at the steps involved in deploying Neo4j on Azure using AKS. However, before you dive into the tutorial, make sure you have all the necessary prerequisites.

What do you need?

  • An AKS cluster.
  • Helm and Kubectl.
  • Basic knowledge of k8s.
  • Custom domain name.

If you want to accelerate the process of creating an AKS cluster, you can use my modules from the Terraform Registry.

Terraform module: AKS.

Let’s Start 🤩.

Step 1: Create a file named values.yml

neo4j:
name: my-standalone
resources:
cpu: "0.5"
memory: "4Gi"

password: "test1234"

volumes:
data:
mode: "dynamic"
dynamic:
storageClassName: managed-csi

Step 2: Install neo4j through the helm.

helm repo add neo4j https://helm.neo4j.com/neo4j
helm repo update
helm install my-neo4j-release neo4j/neo4j -f values.yaml
Installation of Neo4j status

Step 3: Verify that neo4 installation.

Neo4j app status

Step 4: Install nginx-ingress-controller through the helm.

kubectl create namespace public-ingress

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace public-ingress \
--set controller.service.externalTrafficPolicy=Local

Step 5: Copy the external address of the ingress-controller and paste it into the DNS record of your custom domain.

Details of ingress-controller
DNS record update

Step 6: Install cert-manager in your cluster.

helm repo add jetstack https://charts.jetstack.io
helm repo update
# Install CRDs with kubectl
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.11.0/cert-manager.crds.yaml
# Install the cert-manager Helm chart
helm install cert-manager jetstack/cert-manager \
--version v1.11.0
Pod status of cert-manager

Step 7: Create an issuer

# Cluster Issuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-production
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: enter your email id here
privateKeySecretRef:
name: letsencrypt-production
solvers:
- http01:
ingress:
class: nginx

Step 8: Apply the issuer through the Kubectl command

kubectl apply -f issuer.yaml

Step 9: Create an ingress route configuration

We are creating this ingress just to set up a certificate for our domain. We won’t use this ingress to access the neo4j application from outside the cluster.

Here is why:

Ingress cannot be used because Neo4j’s driver protocol communicates at the TCP level and most Ingress only support HTTP communication. Node Port services cannot be associated with a static IP address, making setting up DNS and SSL very difficult. Using NodePort can additionally create configuration challenges for some Neo4j applications that expect to use port 7687

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: neo4j-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt-production
spec:
ingressClassName: nginx
tls:
- hosts:
- ct.akstest.tech
secretName: tls-secret
rules:
- host: ct.akstest.tech
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: my-neo4j-admin
port:
number: 7474

Step 10: Apply the configuration.

kubectl apply -f ingress.yaml

Step 11: Verify that the certificate is applied to your custom domain.

kubectl get certificate
Certificate status

As we cannot communicate with the ingress directly, we will be using a Helm chart named neo4j/neo4j-reverse-proxy to access Neo4j on either port 80 or port 443 through a Kubernetes Ingress. This Helm chart is available on the Neo4j Helm repository.

This Helm chart creates a reverse proxy that is configured to route traffic to the Neo4j service URL using the serviceName, namespace, and domain values.

Step 12: Create a new file named ingress-values. yml.

reverseProxy:
image: neo4j/helm-charts-reverse-proxy:5.12.0
serviceName: "my-neo4j-admin"
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-production
tls:
enabled: true
config:
- secretName: tls-secret
hosts:
- ct.akstest.tech
helm install rp neo4j/neo4j-reverse-proxy -f ingress-values.yaml
Neo4j installation
watch -n1 kubectl get ing #use this command to see status of ingress
Reverse proxy and ingress status

Step 13: To improve traffic routing and add extra features like request rewriting, rate limiting, or authentication, we will delete the current ingress. This means that instead of going straight to the my-neo4j-admin service, traffic for ct.akstest.tech will now be directed to the reverse proxy.

kubectl delete -f ingress.yaml

Step 14: Check your domain to see neo4j deployment.

Neo4j dashboard

Step 15: Double-check if you can access the database with either the neo4j+s:// or bolt+s:// protocol.

username = neo4j
password = test1234
Connection using neo4j+s
Connection using bolt+s

Conclusion😎:

If you’re too lazy to read the entire blog, clone this repo AmitGujar/k8s-neo4j-deployment and run the command “run.sh”.

Throughout this tutorial, we covered all the necessary steps involved in deploying Neo4j on an AKS cluster. By following these steps, you can efficiently deploy and utilize Neo4j on your AKS cluster with an TLS certificate, enabling you to take full advantage of its powerful graph database capabilities.

--

--