# EKS

Deploy Quor on AWS EKS

import DeploymentNextSteps from "/snippets/deployment-next-steps.mdx"

<Warning>
  EKS has recently updated their cluster and node group creation process. The contents of this guide are still relevant,
  but the flow has changed slightly.

  Updates to this guide are coming soon!
</Warning>

## Guide

<Steps>
  <Step title="Install requirements">
    EKS requires the AWS CLI and kubectl CLI.

    - Download and install the [AWS CLI](https://aws.amazon.com/cli/)
    - Download and install [kubectl CLI](https://kubernetes.io/docs/tasks/tools/install-kubectl-macos/)
  </Step>

  <Step title="Create the cluster">
    For this guide, we will use standard settings with the EBS CSI driver.

    - Navigate to Elastic Kubernetes Service (EKS) and create a new cluster
    - For **Cluster service role**, create a new IAM role with a descriptive name like `onyx-eks-cluster-role`

    <Note>
      If you do not see the newly created role in the dropdown, click the refresh button in the UI.
    </Note>

    - For **Kubernetes version**, select a version with standard support
    - Choose **Standard** upgrade policy
    - Add the **Amazon EBS CSI Driver** add-on for Quor's `Persistent Volume Claims`
    - Keep the other default add-ons enabled
    - Review and click **Create**

    The cluster may take several minutes to become ready

    <img className="rounded-image" src="/assets/deployment/eks_cluster_create.png" alt="EKS Cluster Creation"/>
  </Step>

  <Step title="Add nodes">
    Once the cluster is active, add worker nodes where Quor services will run.

    - On the **Cluster** page, select the **Compute** tab and click **Add node group**
    - Provide a **Name** for the group (e.g., `onyx-node-group`)
    - For **Node IAM role**, either select an existing role used by your organization or create
    a new one.

    <Note>
      Ensure the role has the `AmazonEBSCSIDriverPolicy` attached so that PVCs can be fulfilled. If creating a role,
      add this policy in addition to the default policies.
    </Note>

    - Replace the **Instance types** with `c5.2xlarge` machines (or `c5.4xlarge` if you plan to scale beyond 100k documents)
    - Set **Volume size** in the 200GB - 800GB range depending on your document count

    <Tip>
      See the [Resourcing Guide](/deployment/getting_started/resourcing) for more details on storage requirements.
    </Tip>

    - For most setups, set the **Desired size** and **Minimum size** to 1. You can increase
    these later to scale up.
    - **Maximum unavailable** can remain at the default
    - Keep the default networking configuration and click **Create**

    It may take up to 15 minutes for the compute nodes to come online.
  </Step>

  <Step title="Create and connect a user">
    We will need an IAM user with CLI access to manage AWS and the cluster.

    - Navigate to the [IAM Dashboard](https://console.aws.amazon.com/iam/), select **Users** in the left sidebar, and click **Create user**
    - Give the user a descriptive name (e.g., `onyx-eks-user`)
    - Under permissions, click **Attach policies directly** and attach:
    - `AmazonEKSClusterPolicy`
    - `AmazonEKSServicePolicy`
    - Click **Create user**

    - On the user's page, click **Create access key** and follow the prompts.
    - Select the **Command Line Interface (CLI)** option during creation.

    <Tip>
      Save the **Access key** and **Secret access key** for later!
    </Tip>

    - Navigate back to the EKS cluster and select **Access** and then **Create access entry**
    - In **IAM principal**, select the IAM ARN we just created, then click **Next**
    - For Access policies, set **Policy name** to `AmazonEKSClusterAdminPolicy`, then click **Next** and **Create**
  </Step>

  <Step title="Fetch kubeconfig">
    Log in to the AWS CLI and provide the access key and secret key from the IAM user we just created:

        ```bash
        aws configure
        ```

    Configure your kubeconfig to connect to the cluster by filling in the `region-code` and `cluster-name`:

        ```bash
        aws eks update-kubeconfig --region region-code --name cluster-name
        ```

    <Info>
      Reference [AWS EKS kubeconfig docs](https://docs.aws.amazon.com/eks/latest/userguide/create-kubeconfig.html).
    </Info>
  </Step>

  <Step title="Install Quor services">
    The Quor Helm chart packages all the required services (API, web, PostgreSQL, Vespa, etc.) into a single deployment.
    By default, persistent volumes will be created for stateful services.

    First, ensure the `gp2` storage class is set as the default storage class (required for PVCs):

        ```bash
        kubectl patch storageclass gp2 -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
        ```

    Add the Quor Helm repository:

        ```bash
        helm repo add onyx https://onyx-dot-app.github.io/onyx/
        helm repo update
        helm search repo onyx
        ```

    Create a dedicated namespace and install Quor:

        ```bash
        kubectl create namespace onyx
        helm install onyx onyx/onyx -n onyx
        ```

    This will pull the latest Quor chart and deploy all dependencies.
  </Step>

  <Step title="Verify the installation">
        ```bash
        helm list -n onyx
        kubectl get pods -n onyx
        ```

    Wait until all pods are in a `Running` state before accessing Quor.

    To check the API server logs (often the last to become ready):

        ```bash
        kubectl -n onyx get pods | grep api-server | awk '{print $1}' | xargs -I {} kubectl -n onyx logs {} -f
        ```
  </Step>

  <Step title="Access Quor">
    For local testing, port-forward:

        ```bash
        kubectl -n onyx port-forward service/onyx-nginx 8080:80
        ```

    Then open [http://localhost:8080](http://localhost:8080).
  </Step>
</Steps>

## Upgrading

To upgrade Quor services, first update the Helm repository:

```bash
helm repo update
helm upgrade onyx onyx/onyx -n onyx
```

To upgrade to a specific version, use:

```bash
helm upgrade onyx onyx/onyx -n onyx --version <VERSION>
```

## Uninstalling

To remove the Quor services:

```bash
helm uninstall onyx -n onyx
```

Vespa, Postgres, and MinIO leave behind PVCs. To delete them:

```bash
kubectl -n onyx get pvc
kubectl -n onyx delete pvc vespa-storage-da-vespa-0
kubectl -n onyx delete pvc onyx-minio
kubectl -n onyx delete pvc data-onyx-postgresql-0
```

<DeploymentNextSteps />
