In this post, I will go over the steps needed to provision a Kubernetes cluster in AWS, and deploy a Neo4j cluster using Neo4j’s helm charts.

This post takes steps from the official Neo4j Kubernetes Documentation

Prerequisites

  • An AWS Account
  • Configured AWS Command Line Interface
  • An SSH Key named id_rsa.pub. If you do not have one, you can generate it by running: ssh-keygen -t rsa -C "[email protected]"

Setting up a Kubernetes Cluster in EKS

Installation of tools and applications

  1. In order to create a Kubernetes (EKS) cluster in AWS, you will need to download the following applications:
  1. Add the neo4j helm chart repository for neo4j:
helm repo add neo4j https://helm.neo4j.com/neo4j
helm repo update
helm search repo neo4j/

You should see some output like this, to show that the helm repository has been installed and the neo4j charts are available:

Update Complete. ⎈Happy Helming!⎈
NAME                                    CHART VERSION   APP VERSION     DESCRIPTION                                       
neo4j/neo4j                             5.5.0           5.5.0           Neo4j is the world's leading graph database       
neo4j/neo4j-cluster-core                4.4.17          4.4.17          Neo4j is the world's leading graph database       
neo4j/neo4j-cluster-headless-service    4.4.17          -               Neo4j is the world's leading graph database       
neo4j/neo4j-cluster-loadbalancer        4.4.17          -               Neo4j is the world's leading graph database       
neo4j/neo4j-cluster-read-replica        4.4.17          4.4.17          Neo4j is the world's leading graph database       
neo4j/neo4j-docker-desktop-pv           4.4.17          -               Sets up persistent disks suitable for simple de...
neo4j/neo4j-gcloud-pv                   4.4.17          -               Sets up persistent disks suitable for simple de...
neo4j/neo4j-headless-service            5.5.0           -               Neo4j is the world's leading graph database       
neo4j/neo4j-persistent-volume           5.5.0           -               Sets up persistent disks suitable for a Neo4j H...
neo4j/neo4j-standalone                  4.4.17          4.4.17          Neo4j is the world's leading graph database   
  1. Export Variable for AWS_DEFAULT_REGION and AWS_PROFILE. Details can be found in your ~/.aws/credentials and ~/.aws/config files (assuming the the aws-cli is correctly configured).
export AWS_DEFAULT_REGION="eu-west-1"
export AWS_PROFILE=your-aws-profile-name
  1. Create the EKS cluster:
eksctl create cluster --name "my-neo4j-eks-cluster" \
  --nodes 4 \
  --with-oidc \
  --ssh-access \
  --nodes-min 1 \
  --nodes-max 4 \
  --node-type c4.xlarge \
  --node-volume-size 10 \
  --profile $AWS_PROFILE \
  --region $AWS_DEFAULT_REGION \
  --nodegroup-name "test-neo4j-nodes"

This command will create a cloudformation stack with a number of resources required by the EKS Cluster. You can check the CloudFormation console to check on the progress of the EKS Cluster installation.

Assuming you are working in the eu-west-1 region, the following links point to the CloudFormation and EKS consoles.

EKS Cluster creation can take upwards of 15 minutes

  1. Create an IAM role (e.g., AmazonEKS_EBS_CSI_DriverRole) and attach the required AWS-managed policy to it (e.g., AmazonEBSCSIDriverPolicy).
eksctl create iamserviceaccount \
  --approve \
  --role-only \
  --profile $AWS_PROFILE \
  --namespace kube-system \
  --name ebs-csi-controller-sa \
  --cluster my-neo4j-eks-cluster \
  --role-name AmazonEKS_EBS_CSI_DriverRole \
  --attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy
  1. Add the EBS CSI Driver as an Amazon EKS add-on to your cluster. Note that you will need to paste your AWS Account ID into this command to define the service-account-role-arn.

The EBS CSI (Container Storage Interface) Driver is a plugin for Kubernetes that allows you to use Amazon Elastic Block Store (EBS) volumes as Persistent Volumes (PVs) in your cluster. It implements the CSI specification and provides a way for pods to access EBS volumes dynamically. With the EBS CSI Driver, you can create and manage EBS volumes dynamically, and attach and detach them from your pods as needed, without manual intervention. This makes it easier to use EBS volumes in your Kubernetes environment, and provides a more dynamic and flexible storage solution for your containers.

eksctl create addon \
  --force \
  --profile $AWS_PROFILE \
  --name aws-ebs-csi-driver \
  --cluster my-neo4j-eks-cluster \
  --service-account-role-arn arn:aws:iam::<aws-account-id>:role/AmazonEKS_EBS_CSI_DriverRole
  1. Configure kubectl to use the EKS cluster that you’ve just created:
aws eks update-kubeconfig \
  --name my-neo4j-eks-cluster \
  --profile $AWS_PROFILE \
  --region $AWS_DEFAULT_REGION
  1. Create a namespace for our neo4j and configure it to be used in the current context:
kubectl create namespace neo4j
kubectl config set-context --current --namespace=neo4j
  1. Create a values.yaml file which we can use for each server we are going to install:
neo4j:
  name: my-standalone
  resources:
    cpu: "0.5"
    memory: "2Gi"

  # Uncomment to set the initial password
  #password: "my-initial-password"

  # Uncomment to use enterprise edition
  #edition: "enterprise"
  #acceptLicenseAgreement: "yes"

volumes:
  data:
    mode: "dynamic"
    dynamic:
     # gp2 is a general-purpose SSD volume
     storageClassName: gp2
  1. Install servers 1, 2 and 3
for pod in $(seq 1 3); 
  do helm install server-$pod neo4j/neo4j --set neo4j.edition=enterprise --namespace neo4j -f neo4j.values.yaml; 
done
  1. Verify that pods are ready
kubectl get pods
  1. Verify that the service is available
kubectl get service

Use the output of this command to find the internet facing fqdn of the load balancer, for example:

NAME                  TYPE           CLUSTER-IP       EXTERNAL-IP                                                               PORT(S)                                                                   AGE
my-cluster-lb-neo4j   LoadBalancer   10.100.2.118     a436a6dddecdd4135b820a8fb425bce4-1398122496.eu-west-1.elb.amazonaws.com   7474:31184/TCP,7473:30564/TCP,7687:32567/TCP                              7m3s
server-1              ClusterIP      10.100.5.218     <none>                                                                    7687/TCP,7474/TCP,7473/TCP                                                7m3s
server-1-admin        ClusterIP      10.100.91.203    <none>                                                                    6362/TCP,7687/TCP,7474/TCP,7473/TCP                                       7m3s
server-1-internals    ClusterIP      None             <none>                                                                    6362/TCP,7687/TCP,7474/TCP,7473/TCP,7688/TCP,5000/TCP,7000/TCP,6000/TCP   7m3s
server-2              ClusterIP      10.100.49.12     <none>                                                                    7687/TCP,7474/TCP,7473/TCP                                                7m1s
server-2-admin        ClusterIP      10.100.179.98    <none>                                                                    6362/TCP,7687/TCP,7474/TCP,7473/TCP                                       7m1s
server-2-internals    ClusterIP      None             <none>                                                                    6362/TCP,7687/TCP,7474/TCP,7473/TCP,7688/TCP,5000/TCP,7000/TCP,6000/TCP   7m1s
server-3              ClusterIP      10.100.166.51    <none>                                                                    7687/TCP,7474/TCP,7473/TCP                                                7m
server-3-admin        ClusterIP      10.100.249.212   <none>                                                                    6362/TCP,7687/TCP,7474/TCP,7473/TCP                                       7m
server-3-internals    ClusterIP      None             <none>                                                                    6362/TCP,7687/TCP,7474/TCP,7473/TCP,7688/TCP,5000/TCP,7000/TCP,6000/TCP   7m
  1. Connect to the neo4j browser at:
http://EXTERNAL-IP:7474

for example:

http://a436a6dddecdd4135b820a8fb425bce4-1398122496.eu-west-1.elb.amazonaws.com:7474
  1. Clean Up and delete

Use the eksctl command (example shown below) to destroy your entire EKS environment, or use delete the CloudFormation Stacks which have been deployed.

eksctl delete cluster --name=my-neo4j-eks-cluster