> For the complete documentation index, see [llms.txt](https://docs.zerve.ai/zerve-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.zerve.ai/zerve-docs/self-hosting/azure-aks.md).

# Azure (AKS)

Run Zerve's compute and storage in your own Azure account, on your existing AKS cluster.

This guide sets up [bring your own cloud](/zerve-docs/self-hosting/self-hosting.md#bring-your-own-cloud) on Azure. Your code runs on your existing **AKS cluster**, and your data is stored in your own storage account.

## What you'll set up

| Resource                                    | Purpose                                                                                                                                                          |
| ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **A storage account and blob container**    | Stores block outputs, variables and files                                                                                                                        |
| **A container registry**                    | Stores environment images                                                                                                                                        |
| **An application service principal**        | Represents Zerve in your tenant, created by registering Zerve's multi-tenant app. It's authorized to do things such as schedule compute jobs and manage storage. |
| **An execution managed identity**           | The identity your code runs as. Grant it access to other Azure resources your code needs.                                                                        |
| **A build managed identity**                | The identity environment builds run as, with access to the blob container and container registry                                                                 |
| **Zerve's Helm chart, on your AKS cluster** | Sets up the permissions Zerve needs in your cluster                                                                                                              |

A template creates most of these for you.

## Before you start

Your AKS cluster needs:

* Kubernetes version **1.28 or higher**
* [Workload Identity](https://learn.microsoft.com/en-us/azure/aks/workload-identity-deploy-cluster) enabled
* [Microsoft Entra integration](https://learn.microsoft.com/en-us/azure/aks/enable-authentication-microsoft-entra-id) enabled. Zerve signs in to the cluster as its service principal, and Kubernetes decides what it can do.

You'll also need:

* The `az` CLI
* `kubectl`, pointing at the AKS cluster you'll use for Zerve
* `helm`

## 1. Choose your subscription

Point the `az` CLI at the subscription where Zerve's resources should be created:

```bash
az account set --subscription <subscription id>
```

## 2. Add Zerve's service principal

Register Zerve's app in your tenant, and save its ID:

```bash
export ZERVE_SP_ID=$(az ad sp create --id 05b06594-79df-44b0-8554-3e0a8a2c71be --query id --output tsv)
```

## 3. Create the resources

Create a resource group for Zerve. For best performance, put it in the same location as your AKS cluster:

```bash
az group create --name zerve --location <location>
```

Set these to identify your AKS cluster:

```bash
export CLUSTER_RG=      # The cluster's resource group
export CLUSTER_NAME=    # The cluster's name
```

Deploy Zerve's [Azure Resource Manager template](https://zerve-deployment-templates.s3.eu-west-1.amazonaws.com/azure/zerve.json) as a deployment stack. It creates the storage, registry and managed identities:

```bash
az stack group create \
  --name zerve-infra \
  --resource-group zerve \
  --template-uri https://zerve-deployment-templates.s3.eu-west-1.amazonaws.com/azure/zerve.json \
  --action-on-unmanage 'deleteAll' \
  --deny-settings-mode 'none' \
  --parameters aksClusterRg=$CLUSTER_RG aksClusterName=$CLUSTER_NAME zerveSpId=$ZERVE_SP_ID
```

## 4. Connect your AKS cluster

Get the IDs of the managed identities the template created:

```bash
export BUILD_CLIENT_ID=$(az stack group show --name zerve-infra --resource-group zerve --query 'outputs.buildIdentityClientId.value' --output tsv)
export EXECUTION_CLIENT_ID=$(az stack group show --name zerve-infra --resource-group zerve --query 'outputs.executionIdentityClientId.value' --output tsv)
```

Install Zerve's Helm chart, which sets up the permissions Zerve needs in the cluster:

```bash
cat <<- EOF > /tmp/values.yaml
  builder:
    # Link the "builder" Kubernetes service account to the build managed identity
    serviceAccount:
      annotations:
        azure.workload.identity/client-id: $BUILD_CLIENT_ID
  executor:
    # Link the "executor" Kubernetes service account to the execution managed identity
    serviceAccount:
      annotations:
        azure.workload.identity/client-id: $EXECUTION_CLIENT_ID
  scheduler:
    # Give the Zerve app full access to the zerve namespace
    user:
      enabled: true
      name: $ZERVE_SP_ID
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: admin
EOF

helm install zerve oci://public.ecr.aws/x8w6c8k3/helm/zerve \
  -n zerve \
  -f /tmp/values.yaml \
  --create-namespace
```

## 5. Connect Zerve to your account

In Zerve, go to **Settings → Self-Hosting** and fill in:

| Field                          | Value                                                                           |
| ------------------------------ | ------------------------------------------------------------------------------- |
| **Tenant ID**                  | The tenant ID of Zerve's service principal                                      |
| **Storage Account Name**       | From the deployment stack's outputs                                             |
| **Bucket Name**                | From the deployment stack's outputs                                             |
| **Image Registry**             | The container registry's login server, from the deployment stack's outputs      |
| **Namespace**                  | `zerve`                                                                         |
| **Endpoint**                   | Your AKS cluster's control plane endpoint                                       |
| **Service Account Token**      | Leave empty                                                                     |
| **Certificate Authority Data** | The base64-encoded certificate for your AKS cluster's control plane (see below) |

To see the deployment stack's outputs:

```bash
az stack group show --name zerve-infra --resource-group zerve --query 'outputs'
```

To find the certificate authority data:

```bash
kubectl config view \
  -o jsonpath="{.clusters[?(@.name == \"$CLUSTER_NAME\")].cluster.certificate-authority-data}" \
  --raw
```

Save the settings. Your organization's code now runs on your AKS cluster.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.zerve.ai/zerve-docs/self-hosting/azure-aks.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
