Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .github/workflows/lint-test-high-availability.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,22 @@ jobs:
echo "MEMGRAPH_ORGANIZATION_NAME=${{ secrets.MEMGRAPH_ORGANIZATION_NAME }}" >> $GITHUB_ENV

- name: Install csi-hostpath-delayed storage class
if: steps.list-changed.outputs.changed == 'true'
run: |
kubectl apply -f ./charts/memgraph-high-availability/storage-class.yaml

- name: Create Kubernetes secret for license
if: steps.list-changed.outputs.changed == 'true'
run: |
kubectl create secret generic memgraph-secrets \
--from-literal=MEMGRAPH_ENTERPRISE_LICENSE="$MEMGRAPH_ENTERPRISE_LICENSE" \
--from-literal=MEMGRAPH_ORGANIZATION_NAME="$MEMGRAPH_ORGANIZATION_NAME" \
--namespace default

- name: Install memgraph-high-availability
if: steps.list-changed.outputs.changed == 'true'
run: |
helm install memgraph-db ./charts/memgraph-high-availability \
--set env.MEMGRAPH_ENTERPRISE_LICENSE=$MEMGRAPH_ENTERPRISE_LICENSE \
--set env.MEMGRAPH_ORGANIZATION_NAME=$MEMGRAPH_ORGANIZATION_NAME \
--set storage.data.libStorageClassName=csi-hostpath-delayed \
--set storage.data.logStorageClassName=csi-hostpath-delayed \
--set storage.coordinators.libStorageClassName=csi-hostpath-delayed \
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/test-remote-monitoring.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,16 @@ jobs:
kubectl rollout status deployment/victoria-logs -n remote-monitoring --timeout=180s
kubectl rollout status deployment/monitoring-gateway -n remote-monitoring --timeout=180s

- name: Create Kubernetes secret for license
run: |
kubectl create secret generic memgraph-secrets \
--from-literal=MEMGRAPH_ENTERPRISE_LICENSE="$MEMGRAPH_ENTERPRISE_LICENSE" \
--from-literal=MEMGRAPH_ORGANIZATION_NAME="$MEMGRAPH_ORGANIZATION_NAME" \
--namespace default

- name: Install HA chart with remote monitoring enabled
run: |
helm install memgraph-db ./charts/memgraph-high-availability \
--set env.MEMGRAPH_ENTERPRISE_LICENSE="$MEMGRAPH_ENTERPRISE_LICENSE" \
--set env.MEMGRAPH_ORGANIZATION_NAME="$MEMGRAPH_ORGANIZATION_NAME" \
--set prometheus.enabled=true \
--set prometheus.namespace=monitoring \
--set prometheus.serviceMonitor.enabled=false \
Expand Down
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,20 @@ Deploys high available Memgraph cluster, that includes two data instances and th

For detailed information and usage instructions, please refer to the [chart's individual README file](./charts/memgraph-high-availability/README.md).

To install the chart, run the following command:
To install the chart, first create a Kubernetes secret holding your Memgraph
Enterprise license and organization name (the HA chart reads these via
`secretKeyRef`), then install the chart:

```
helm install my-release memgraph/memgraph-high-availability --set env.MEMGRAPH_ENTERPRISE_LICENSE=<your-license>,env.MEMGRAPH_ORGANIZATION_NAME=<your-organization-name>
kubectl create secret generic memgraph-secrets \
--from-literal=MEMGRAPH_ENTERPRISE_LICENSE=<your-license> \
--from-literal=MEMGRAPH_ORGANIZATION_NAME=<your-organization-name>

helm install my-release memgraph/memgraph-high-availability
```
Replace `my-release` with a name of your choice for the release.
Replace `my-release` with a name of your choice for the release. The secret
name and keys are configurable via `secrets.name`, `secrets.licenseKey`, and
`secrets.organizationKey`.

There are a few additional steps to make the cluster fully operational. Please take a look under the [Setting up the cluster](https://memgraph.com/docs/getting-started/install-memgraph/kubernetes#setting-up-the-cluster) docs section.

Expand Down
40 changes: 33 additions & 7 deletions charts/memgraph-high-availability/aks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,39 @@ az login
cd charts/memgraph-high-availability/aks

terraform init
terraform apply -var="subscription_id=<your-azure-subscription-id>"
terraform apply \
-var="subscription_id=<your-azure-subscription-id>" \
-var="memgraph_enterprise_license=<licence>" \
-var="memgraph_organization_name=<organization>"
```

Terraform will prompt for confirmation. Type `yes` to proceed, or use `-auto-approve` to skip.

To avoid passing the license on the command line, export them as environment variables:

```bash
export TF_VAR_memgraph_enterprise_license=<licence>
export TF_VAR_memgraph_organization_name=<organization>
terraform apply -var="subscription_id=<your-azure-subscription-id>"
```

### Configuration

All defaults can be overridden via variables:

| Variable | Default | Description |
|----------|---------|-------------|
| `subscription_id` | (required) | Azure subscription ID |
| `memgraph_enterprise_license` | (required) | Memgraph enterprise license key (stored in `memgraph-secrets`) |
| `memgraph_organization_name` | (required) | Memgraph organization name (stored in `memgraph-secrets`) |
| `resource_group_name` | `MG_RG` | Resource group name |
| `location` | `westeurope` | Azure region |
| `cluster_name` | `memgraph-ha` | AKS cluster name |
| `node_count` | `5` | Number of AKS nodes |
| `node_vm_size` | `Standard_A2_v2` | VM size for nodes |
| `values_file` | `values-aks.yaml` | Helm values file (relative to `aks/` directory) |
| `release_namespace` | `default` | Namespace for the Helm release and license secret |
| `secret_name` | `memgraph-secrets` | Secret name (must match `secrets.name` in chart values) |

Example with custom values:

Expand All @@ -59,7 +74,8 @@ terraform apply \
1. **Resource group** (`MG_RG`) in the specified Azure region
2. **AKS cluster** (`memgraph-ha`) with 5 nodes using SystemAssigned identity
3. **Node labels** via `label_nodes.sh` — first 3 nodes labeled `role=coordinator-node`, last 2 labeled `role=data-node`
4. **Helm release** (`memgraph-db`) installing the HA chart with `values-aks.yaml`
4. **License secret** (`memgraph-secrets`) in the release namespace, populated from the `memgraph_enterprise_license` and `memgraph_organization_name` variables
5. **Helm release** (`memgraph-db`) installing the HA chart with `values-aks.yaml`

### Connecting to the cluster after Terraform apply

Expand Down Expand Up @@ -151,7 +167,19 @@ kubectl label nodes aks-nodepool1-65392319-vmss000003 role=data-node
kubectl label nodes aks-nodepool1-65392319-vmss000004 role=data-node
```

In the following chapters, we will go over several most common deployment types:
In the following chapters, we will go over several most common deployment types.
Each of them assumes the Memgraph Enterprise license and organization name have
already been provisioned as a Kubernetes secret (the HA chart reads them via
`secretKeyRef`):

```
kubectl create secret generic memgraph-secrets \
--from-literal=MEMGRAPH_ENTERPRISE_LICENSE=<licence> \
--from-literal=MEMGRAPH_ORGANIZATION_NAME=<organization>
```

The secret name and keys can be overridden via `secrets.name`,
`secrets.licenseKey`, and `secrets.organizationKey` in `values.yaml`.

---

Expand All @@ -163,8 +191,7 @@ Users can connect to any coordinator or data instance by distinguishing bolt por

```
helm install mem-ha-test ./charts/memgraph-high-availability --set \
env.MEMGRAPH_ENTERPRISE_LICENSE=<licence>,\
env.MEMGRAPH_ORGANIZATION_NAME=<organization>,affinity.nodeSelection=true,\
affinity.nodeSelection=true,\
externalAccessConfig.dataInstance.serviceType=IngressNginx,externalAccessConfig.coordinator.serviceType=IngressNginx
```

Expand All @@ -187,8 +214,7 @@ are used and so that each data and coordinator instance is exposed through LoadB

```
helm install mem-ha-test ./charts/memgraph-high-availability --set \
env.MEMGRAPH_ENTERPRISE_LICENSE=<licence>,\
env.MEMGRAPH_ORGANIZATION_NAME=<organization>,affinity.nodeSelection=true,\
affinity.nodeSelection=true,\
externalAccessConfig.dataInstance.serviceType=LoadBalancer,externalAccessConfig.coordinator.serviceType=LoadBalancer
```

Expand Down
40 changes: 37 additions & 3 deletions charts/memgraph-high-availability/aks/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ terraform {
source = "hashicorp/helm"
version = "~> 2.17"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.30"
}
null = {
source = "hashicorp/null"
version = "~> 3.2"
Expand Down Expand Up @@ -63,6 +67,32 @@ provider "helm" {
}
}

provider "kubernetes" {
host = azurerm_kubernetes_cluster.memgraph_ha.kube_config[0].host
client_certificate = base64decode(azurerm_kubernetes_cluster.memgraph_ha.kube_config[0].client_certificate)
client_key = base64decode(azurerm_kubernetes_cluster.memgraph_ha.kube_config[0].client_key)
cluster_ca_certificate = base64decode(azurerm_kubernetes_cluster.memgraph_ha.kube_config[0].cluster_ca_certificate)
}

# ──────────────────────────────────────────────
# Memgraph enterprise license secret
# Consumed by the HA chart via secrets.name / secrets.licenseKey /
# secrets.organizationKey (see values.yaml).
# ──────────────────────────────────────────────
resource "kubernetes_secret" "memgraph_secrets" {
metadata {
name = var.secret_name
namespace = var.release_namespace
}

data = {
MEMGRAPH_ENTERPRISE_LICENSE = var.memgraph_enterprise_license
MEMGRAPH_ORGANIZATION_NAME = var.memgraph_organization_name
}

type = "Opaque"
}

# ──────────────────────────────────────────────
# Label nodes: first 3 → coordinator, last 2 → data
# Uses a single script to avoid for_each on
Expand All @@ -80,14 +110,18 @@ resource "null_resource" "label_nodes" {
# Helm release: Memgraph HA
# ──────────────────────────────────────────────
resource "helm_release" "memgraph_ha" {
name = "memgraph-db"
chart = "../"
name = "memgraph-db"
chart = "../"
namespace = var.release_namespace

values = [
file("${path.module}/${var.values_file}")
]

timeout = 600

depends_on = [null_resource.label_nodes]
depends_on = [
null_resource.label_nodes,
kubernetes_secret.memgraph_secrets,
]
}
Loading
Loading