Skip to main content
This tutorial walks you through deploying ClickHouse Private on AWS using Amazon EKS, step by step. By the end, you will have a running ClickHouse cluster with S3-backed storage, NVMe SSD caching, and the ClickHouse operator managing the deployment. For detailed infrastructure specifications, see reference/infrastructure-requirements.md. For an overview of how the operator works, see explanation/architecture.md.

Prerequisites

Before you begin, ensure you have the following tools installed:
  • AWS CLI (aws) — configured with appropriate credentials
  • kubectl — compatible with your target EKS version
  • Helm v3.x
  • skopeo — for copying container images between registries
  • Access to the ClickHouse Private ECR repository (<<SOURCE_ECR_ACCOUNT_ID>>.dkr.ecr.us-east-1.amazonaws.com). The source ECR account ID is provided by ClickHouse during onboarding.
You will also need:
  • An AWS account with permissions to create IAM roles, EKS clusters, S3 buckets, and EC2 resources
  • The version tags for your deployment (provided by ClickHouse):
    • <<SERVER_TAG>> — ClickHouse server image tag
    • <<KEEPER_TAG>> — ClickHouse keeper image tag
    • <<OPERATOR_TAG>> — Operator image and Helm chart tag
    • <<CR_HELM_TAG>> — Cluster Helm chart tag

Step 1: Create IAM Role for ECR Access

Create an IAM role that allows pulling images from the ClickHouse private ECR. Deploy this CloudFormation template in your AWS account:
Once the stack is created, provide the output Role ARN to the ClickHouse team.

Step 2: Copy Container Images

Create ECR repositories in your account for each artifact, then use skopeo to copy images from the ClickHouse ECR to your own. The --all flag preserves all architectures (amd64, arm64).
Replace TARGET_REGION and TARGET_ECR_REPO with your ECR region and host. Replace the <<TAG>> placeholders with the versions provided by ClickHouse.

Step 3: Create VPC

Create a VPC with at least 3 availability zones for high availability. Here is an example configuration: Example subnets (us-west-2): See reference/infrastructure-requirements.md for detailed networking requirements.

Step 4: Create EKS Cluster

Create an EKS cluster associated with the VPC from Step 3. The cluster requires:
  • A CNI plugin using IPv4 (e.g., Amazon VPC CNI with IRSA)
  • EBS CSI Driver (installed in Step 7)
  • CoreDNS
  • Recommended: Cluster Autoscaler
Create the cluster using the AWS console or CLI, then add it to your kubeconfig:
Create an OIDC provider for the EKS cluster (required for IRSA).

Step 5: Create Node Groups

Create three node groups. All nodes require IMDS for authentication. For keeper and server node groups, create one node group per AZ if you want to support cluster autoscaler across AZs.

Keeper Node Group

Server Node Group

The Server node group requires an NVMe SSD-backed instance type for the ClickHouse disk cache (use the “d” series, e.g. m7gd.16xlarge). The AMI flavor determines how NVMe is mounted and how the helm chart is configured in Step 9. Choose one:
Important: For instances with NVMe SSD, use the launch template below to automatically mount the NVMe SSD as a RAID array for ClickHouse caching.Create an EC2 launch template with this user data script, then associate it with the server node group:
Note: If the launch template already has user data, separate this script using the MIME boundary.In Step 9, leave server.ssdCacheConfiguration.isOnEmptyDir at its default (false).

Operator Node Group

This can be an existing node group if the EKS cluster already exists.

Step 6: Create S3 Bucket and IAM Roles

S3 Bucket

Create an S3 bucket (Standard class) with encryption enabled in the same region as the EKS cluster. You can use one bucket per ClickHouse cluster, or a single bucket with a unique prefix per cluster.
Do not create S3 Lifecycle rules on this bucketClickHouse manages its own data in S3. S3 Lifecycle policies (expiration, transition, abort incomplete multipart uploads with short timeouts) will delete objects that ClickHouse still depends on, causing data loss and cluster outages. To manage data retention, use ClickHouse TTL rules and partition operations instead. See Manage data lifecycle.

IAM Roles

Create an IAM role for each ClickHouse cluster using IRSA (IAM Roles for Service Accounts). Naming convention: CH-S3-$NAME-$REGION-$ORDINAL-Role
  • $NAME — cluster name, e.g., default-xx-01
  • $REGION — shortened region name, e.g., uw2 for us-west-2
  • $ORDINAL — reserved, set to 00
  • Example: CH-S3-default-xx-01-uw2-00-Role
Required permissions: s3:* and s3:ListBucket on the bucket resource. Example trust policy (update namespace, service account name, and OIDC provider):

Step 7: Install Kubernetes Prerequisites

Install VolumeSnapshot CRDs

These CRDs are required by the ClickHouse operator.

Install StorageClass via Helm

Only perform this step if you do not have a custom or existing StorageClass. Installing it separately from the cluster ensures it is not removed if the cluster is deleted.

Install EBS CSI Driver

Create an IAM role with the managed policy arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy and an IRSA trust policy for the EKS cluster OIDC provider. Then install:

Step 8: Install the Operator

Log into ECR from Helm if needed:
Then install the operator:

Step 9: Deploy a ClickHouse Cluster

Naming Your Cluster

Each ClickHouse cluster needs a unique name within the EKS cluster. Use the convention $DESCRIPTOR-$LETTERS-$ORDINAL:
  • $DESCRIPTOR — descriptive name using letters only
  • $LETTERS — reserved, use xx for simplicity
  • $ORDINAL — incrementing ordinal starting with 01
  • Example: default-xx-01

Generate Password Hash and Deploy

Guaranteed QoS (recommended)ClickHouse workloads should run with matching requests and limits for both CPU and memory. The single SERVER_CPU/SERVER_MEMORY/KEEPER_CPU/ KEEPER_MEMORY values below are applied to both resources.requests and resources.limits in the helm invocation that follows, which places the pods in the Guaranteed QoS class. If you need to run with a different QoS class, review Pod QoS: Guaranteed (recommended) first for the trade-offs.

Step 10: Run Preflight Checks

To validate the readiness of your cluster we recommend running preflight checks. The preflight checks use Troubleshoot, a Kubernetes plugin for cluster diagnostics.

Install the Plugin

Copy the Preflight Helm Chart

Add the preflight chart to your ECR copy step:

Run the Checks

Use helm template to render the preflight spec, then pipe it to kubectl preflight:
This validates node labels, StorageClass configuration, and other requirements. The output shows each check and its status. If a check fails, it includes recommendations on how to fix the issue. For more details see the How To: Run Preflight Checks page.

Step 11: Verify Installation

Port-forward the ClickHouse Service

This forwards port 9000 to your local machine.

Connect and Run a Query

Run a simple query:
Expected output:

Next Steps

Last modified on August 7, 2026