> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Provisionner une infrastructure AWS avec Terraform

> Créez un EKS cluster Amazon pour le mode managé, ou ajoutez les éléments requis à un VPC ou à un cluster existant, avec Terraform ou OpenTofu

Aperçu privé

Le mode managé s'exécute sur un cluster Amazon EKS dont vous êtes propriétaire. Chaque version fournit quatre modules racines Terraform (appelés « racines » ci-dessous) qui créent un cluster répondant à ses exigences ou ajoutent les éléments nécessaires à un VPC ou à un cluster existant. Les racines créent le cluster avec son groupe de nœuds système et ses add-ons managés (`vpc-cni`, `kube-proxy`, `coredns`, `aws-ebs-csi-driver`), ainsi que les rôles IAM, les clés KMS et les balises ; `existing-eks` installe uniquement les add-ons que vous indiquez dans `install_addons`. Sur la cible Helm, `clicklink clctl init` installe ensuite la couche plateforme à partir des sorties et d'un bundle de plateforme : Karpenter, le contrôleur AWS Load Balancer, la StorageClass et les composants à version figée (voir [initialiser le connecteur à partir des sorties Terraform](#hand-off)). Les racines nécessitent Terraform 1.10+ ou OpenTofu 1.12+, ainsi que le fournisseur AWS `~> 6.0`. Vous pouvez utiliser `tofu` à la place de `terraform` dans toutes les commandes de cette page.

![Flux de provisionnement Terraform pour le ClickHouse Connector sur AWS](https://mintcdn.com/private-7c7dfe99/rJQNifKkddKyB_KW/images/cloud/reference/byoc-connector-terraform-flow.svg?fit=max\&auto=format\&n=rJQNifKkddKyB_KW\&q=85\&s=8b0e95133f61d6b4278f29df9631e44e)

## Avant de commencer

Vous aurez besoin de :

* Terraform 1.10+ ou OpenTofu 1.12+, ainsi que le fournisseur AWS `~> 6.0`.
* Une identity AWS autorisée à créer et à modifier les ressources requises par la racine choisie.
* `curl`, un outil SHA-256 (`sha256sum` ou `shasum`) et `cosign` pour télécharger et vérifier l’archive de la version.
* Issus de l’[enregistrement](/docs/fr/products/bring-your-own-cloud/connector/onboarding#registration) : le `chart_repository_arn` exigé par chaque racine, ainsi que votre connector endpoint, le jeton d’inscription et le bundle de plateforme à transmettre à `init` à la dernière étape.

Pour `production` et `existing-vpc`, déterminez à l’avance comment la machine qui exécute `clicklink clctl init` et `kubectl` accédera à l’API EKS privée, par exemple via un VPN, un bastion, un réseau appairé ou une redirection de port SSM.

## 1. Choisissez le répertoire racine Terraform adapté à votre environnement

Les quatre racines génèrent la même sortie `clicklink`. La transmission à `clicklink clctl init` est identique, quelle que soit celle que vous appliquez.

| Racine | Point de départ | Crée |
| - | - | - |
| `minimal` | Clusters de développement et de preuve de concept | Identique, une seule zone, endpoint public, sans endpoints ni CMK |
| `production` | Un compte et une région vides | VPC, EKS cluster, groupe de nœuds, IAM, KMS |
| `existing-vpc` | Un VPC dont vous disposez déjà | EKS cluster, groupe de nœuds, IAM, KMS, balises de sous-réseau |
| `existing-eks` | Un cluster que vous exploitez déjà | IAM, modules complémentaires nommés, autorisations sur les clés, balises de découverte |

### `minimal`

`minimal` assouplit l'endpoint public, les endpoints d'interface, les flow logs, la rétention des logs et la taille du pool système. Chaque variable assouplie existe dans les deux racines sous le même nom. Passer l'une d'elles à sa valeur de production se résume à modifier `terraform.tfvars` puis à appliquer de nouveau la configuration. En revanche, la zone unique de charge de travail et l'absence de clés KMS sont figées : les sous-réseaux ne peuvent pas changer de zone, et la racine ne propose aucune variable pour le chiffrement des secrets EKS. Pour combler ces écarts, il faut appliquer `production` sous la forme d'un nouveau cluster.

### `production`

Le VPC couvre trois zones (`availability_zone_count`, de 2 à 4) avec un sous-réseau privé `/19` et un sous-réseau public `/21` par zone, une passerelle NAT par zone, un endpoint de passerelle S3, des endpoints d’interface pour ECR, STS, EKS, EC2, CloudWatch Logs, SSM, SQS, KMS et ELB, ainsi que des logs de flux VPC. Le cluster EKS dispose d’un endpoint d’API privé, d’une authentification par entrées d’accès (access entries), de tous les types de journaux du plan de contrôle dans un groupe de journaux appartenant au module racine, et de secrets chiffrés avec une clé KMS gérée par le client. Le cluster reçoit les modules complémentaires gérés `vpc-cni`, `kube-proxy`, `coredns` et `aws-ebs-csi-driver`, ainsi qu’un groupe de nœuds système sans taint, étiqueté `clickhouseGroup=system` (de deux à quatre nœuds `m7g.large` par défaut). Le module racine crée également les ressources IAM de Karpenter avec une file d’attente d’interruption et des balises `karpenter.sh/discovery`, des rôles IRSA pour le contrôleur AWS Load Balancer et pour l’executor du connector, ainsi que des clés KMS pour les volumes EBS et pour les buckets de stockage d’objet.

### `existing-vpc` et `existing-eks`

Aucune des deux racines ne modifie ce qu'elle n'a pas créé : tables de routage, passerelles NAT, endpoints, règles de groupe de sécurité, groupes de nœuds, modèles de lancement, configuration du cluster ou clés KMS. Toutes deux appliquent aux sous-réseaux privés les balises `karpenter.sh/discovery=<cluster_name>` et `kubernetes.io/role/internal-elb=1` ; `existing-vpc` applique également la balise `kubernetes.io/role/elb=1` aux sous-réseaux publics, et `existing-eks` balise le groupe de sécurité du cluster.

Avec `existing-vpc`, le VPC doit déjà disposer des éléments suivants :

* Prise en charge DNS et noms d’hôte DNS activés.
* Deux à quatre sous-réseaux privés répartis sur au moins deux zones de disponibilité, avec `map_public_ip_on_launch` désactivé, et routés vers une NAT gateway ou vers des endpoints d’interface pour ECR, STS, EKS, EC2, CloudWatch Logs, SSM, SQS, KMS et ELB. Ajoutez un endpoint de passerelle S3 : sans lui, le trafic vers le stockage d’objet transite par les NAT gateways.
* Des sous-réseaux publics uniquement si vous souhaitez des répartiteurs de charge exposés à Internet. Laissez `public_subnet_ids` vide si le VPC ne comporte pas de niveau public.

Pour `existing-eks`, le cluster doit déjà disposer des éléments suivants :

* Kubernetes 1.34 ou version ultérieure.
* Mode d’authentification `API` ou `API_AND_CONFIG_MAP`. Pour un cluster en mode `CONFIG_MAP`, le plan affiche la commande permettant de changer de mode.
* Un fournisseur OIDC IAM pour l'émetteur du cluster.
* Des sous-réseaux privés répartis sur au moins deux zones de disponibilité, disposant d’un accès sortant vers les API AWS via une passerelle NAT ou des endpoint d’interface. Par défaut, le module racine les déduit des sous-réseaux du cluster en excluant ceux dont la table de routage mène à une passerelle Internet. Définissez `private_subnet_ids` si les sous-réseaux du cluster sont des `/28` réservés au plan de contrôle, ou si les nœuds doivent être placés dans d’autres sous-réseaux.
* Aucune installation existante de Karpenter : ce module racine crée les ressources IAM de Karpenter ainsi que la file d’attente d’interruption. Cette file d’attente étant nommée `<cluster_name>-clicklink`, elle ne peut pas entrer en conflit avec une file résiduelle provenant d’une installation de Karpenter supprimée.
* Des nœuds système sans taint, portant les labels définis dans `system_node_selector` (`clickhouseGroup=system` par défaut). Ce module racine ne crée aucun groupe de nœuds.

`terraform plan` échoue si l'un de ces éléments manque.

Si un module complémentaire listé dans `install_addons` est déjà installé et exécuté en mode autogéré, EKS renvoie `Conflicts found when trying to apply`. Définissez `addon_resolve_conflicts_on_create = "OVERWRITE"` pour que le module complémentaire géré prenne le relais, ou retirez-le de `install_addons`.

## 2. Téléchargez et vérifiez l’archive de la version de Terraform

Les racines sont distribuées sous la forme d'une archive par version, dont le numéro de version suit celui du binaire `clicklink`. Récupérez l'archive correspondant à la version actuelle, ainsi que sa somme de contrôle et son bundle cosign :

```bash theme={null}
CLICKLINK_VERSION="$(curl -fsSL https://releases.clicklink.clickhouse.com/latest-version.txt)"
# Or pin a specific release: CLICKLINK_VERSION='vX.Y.Z'
TERRAFORM_TARBALL="clicklink-terraform-${CLICKLINK_VERSION}.tar.gz"
for suffix in '' .sha256 .bundle; do
  curl -fsSLO "https://releases.clicklink.clickhouse.com/${TERRAFORM_TARBALL}${suffix}"
done
if command -v sha256sum >/dev/null; then
  sha256sum -c "${TERRAFORM_TARBALL}.sha256"
else
  shasum -a 256 -c "${TERRAFORM_TARBALL}.sha256"
fi
```

Vérifiez la signature avec cosign avant d'extraire l'archive :

```bash theme={null}
cosign verify-blob \
  --bundle "${TERRAFORM_TARBALL}.bundle" \
  --certificate-identity-regexp '^https://github\.com/ClickHouse/data-plane-clicklink/\.github/workflows/release\.yaml@refs/tags/v[0-9]+\.[0-9]+\.[0-9]+(-.*)?$' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  "${TERRAFORM_TARBALL}"
```

Puis extrayez-le :

```bash theme={null}
tar -xzf "${TERRAFORM_TARBALL}"
cd "clicklink-terraform-${CLICKLINK_VERSION}"
```

L'archive s'extrait dans un seul répertoire contenant `aws/production`, `aws/minimal`, `aws/existing-vpc`, `aws/existing-eks` et `aws/modules`. Les configurations racines font référence aux modules via `../modules`. Conservez l'arborescence extraite telle quelle au lieu d'en extraire une seule racine. Les README racines de l'archive peuvent présenter le passage de relais `init` sans `--platform-bundle` ; la commande indiquée dans [initialiser le connector à partir des sorties Terraform](#hand-off) est celle qui est prise en charge.

## 3. Configurez et appliquez la racine sélectionnée

Depuis le répertoire racine, copiez le fichier de variables d'exemple, puis renseignez-le :

```bash theme={null}
cp terraform.tfvars.example terraform.tfvars
```

Chaque racine requiert `region`, `cluster_name` et `chart_repository_arn`. `cluster_name` définit le nom du cluster, sert de préfixe à chaque ressource et constitue la valeur du tag de découverte. Dans `production`, `minimal` et `existing-vpc`, il comporte de 3 à 32 lettres minuscules, chiffres et traits d’union, doit commencer par une lettre et ne pas se terminer par un trait d’union. Pour `existing-eks`, il s’agit du nom du cluster que vous exploitez déjà, dans la limite de 32 caractères. `chart_repository_arn` désigne le dépôt ECR du chart du cluster ClickHouse, que votre équipe de compte vous communique lors de l’[inscription](/docs/fr/products/bring-your-own-cloud/connector/onboarding#registration). Les racines qui créent un cluster requièrent également `cluster_admin_principal_arns`, c’est-à-dire les principaux qui obtiennent les droits d’administrateur du cluster via les entrées d’accès EKS. L’identity qui exécute la racine doit figurer dans cette liste, faute de quoi elle ne pourra plus accéder au cluster par la suite. Le créateur du cluster ne reçoit aucun accès implicite. Selon la racine :

* `minimal` requiert `endpoint_public_access_cidrs`, la liste d’autorisation IPv4 de l’endpoint public de l’API. Le réseau depuis lequel vous exécutez `init` et `kubectl` doit y figurer. Un `/0` est refusé, sauf si `allow_public_endpoint_from_anywhere = true`. Avec `endpoint_public_access = false`, la liste peut être vide et l’endpoint est alors uniquement privé, comme dans `production`.
* `existing-vpc` requiert `vpc_id` et `private_subnet_ids`. `public_subnet_ids` est facultatif et sert aux répartiteurs de charge exposés à Internet.
* `existing-eks` ne requiert aucune autre variable. `install_addons` indique les modules complémentaires gérés qui manquent au cluster, et `ebs_kms_key_arn` fournit une clé pour les volumes des services.

Ensuite, initialisez, planifiez et appliquez :

```bash theme={null}
terraform init
terraform providers lock -platform=linux_amd64 -platform=darwin_arm64
terraform plan
terraform apply
```

L’archive ne contient pas de fichier de verrouillage des providers. La commande `terraform providers lock` en génère un, que vous pourrez commiter dans votre copie. Par défaut, l’état est stocké localement. Le fichier `versions.tf` contient un bloc `backend "s3"` commenté qui illustre la configuration d’un état partagé.

> [!NOTE]
>
> Les points de terminaison de l’API `production` et `existing-vpc` sont privés. Exécutez `init` et `kubectl` depuis le VPC (via une redirection de port SSM vers un nœud système, un bastion, un VPN ou un réseau appairé), ou activez l’accès public avec `endpoint_public_access = true` en définissant une liste d’autorisation dans `endpoint_public_access_cidrs`.

## 4. Initialisez le connector à partir des sorties de Terraform

Exportez les sorties, puis transmettez-les à `init` avec le bundle de la plateforme, depuis une machine dont le contexte kube pointe vers le nouveau cluster :

```bash theme={null}
terraform output -json > outputs.json
clicklink clctl init --enroll https://<subdomain>.<connector-domain> --target helm --managed \
  --from-terraform outputs.json --platform-bundle bundle.yaml
```

Les modules racines ne prennent en charge que la cible Helm. Sur une VM (`--target systemd`), `init` refuse `--platform-bundle`, et `clicklink clctl platform approve --bundle` n'installe que les composants épinglés : le cluster ne dispose donc d'aucun provisionneur de nœuds. Réservez `--target systemd` aux connectors qui enregistrent un ClickHouse que vous exploitez vous-même ; cette option n'est pas prise en charge avec ces modules racines.

`--platform-bundle` installe ce que les modules racines laissent de côté : Karpenter avec un `EC2NodeClass` et les NodePools `clickhouse-server` et `clickhouse-keeper`, le contrôleur AWS Load Balancer, la StorageClass `gp3-encrypted` (chiffrée avec la clé EBS lorsque les sorties en contiennent une), ainsi que les composants de plateforme épinglés par le bundle : le contrôleur de snapshots, le ClickHouse Operator et les collectors de supervision. Le bundle est le manifeste de plateforme que ClickHouse Cloud génère pour votre environnement ; votre équipe de compte vous le fournit lors de l'onboarding, et sa section `cluster:` épingle les versions de Karpenter et du contrôleur de répartiteur de charge. L'indicateur nécessite `--target helm`, `--managed` et `--from-terraform`. Les composants déjà présents sont laissés en l'état : la commande peut donc être réexécutée sans risque, et `init` affiche un rapport indiquant ce qui a été installé, ce qui a été ignoré et pour quelle raison. Sans cet indicateur, `init` enregistre le connector mais n'installe aucun de ces éléments, et le cluster ne peut exécuter aucun service tant qu'ils ne sont pas en place. Les [mises à jour de plateforme](/docs/fr/products/bring-your-own-cloud/connector/platform-updates) ultérieures modifient le contrôleur de snapshots, l'opérateur et les collectors ; Karpenter, le contrôleur de répartiteur de charge et la StorageClass restent tels que `init` les a installés.

`--from-terraform` accepte soit le document complet affiché par `terraform output -json`, soit l'objet brut renvoyé par `terraform output -json clicklink`. La sortie `clicklink` contient l'identité du cluster (`account_id`, `region`, `cluster_name`, `cluster_endpoint`, `cluster_ca`), le fournisseur OIDC, le namespace du connector, le rôle IAM de l'executor (`executor_role_arn`), la clé EBS, le rôle et la file d'attente des nœuds Karpenter, le rôle du contrôleur de répartiteur de charge et `system_node_selector`. `init` lit dans le fichier l'identité du cluster et le namespace du connector. Il définit `executor_role_arn` comme annotation IRSA sur le ServiceAccount `pcm-executor` du connector et applique le sélecteur de nœuds aux pods du connector. Les services managés ne partagent pas ce rôle : `clicklink clctl executor prepare` crée un rôle par service (`CH-S3-<service>-<region>-00-Role` par défaut), associé au service lors de sa création ; consultez le [modèle de privilèges](/docs/fr/products/bring-your-own-cloud/connector/reference/privilege-model#identities).

`init` rejette tout indicateur, tel que `--cluster-name` ou `--target-namespace`, qui contredit le fichier, en indiquant les deux valeurs. Supprimez l'indicateur ou corrigez les sorties. Il rejette également tout contexte kube dont le serveur d'API n'est pas `cluster_endpoint`, ou dont l'ARN EKS désigne un autre cluster. La sortie comporte un champ `schema`, actuellement égal à `1`. `clctl` rejette tout fichier dont il ne prend pas en charge le `schema`.

Le reste de l'enregistrement suit la procédure standard décrite dans [onboarding](/docs/fr/products/bring-your-own-cloud/connector/onboarding#install-and-enroll).

## Clés KMS et grants requis

`production` et `existing-vpc` créent trois clés KMS gérées par le client, avec rotation activée, pour les secrets EKS, les volumes EBS et les buckets de stockage d’objet, sauf si vous fournissez des ARN dans `kms`. `existing-eks` crée la clé de stockage sauf si vous définissez `storage_kms_key_arn`, et accepte `ebs_kms_key_arn` pour les volumes des services sans en créer. `minimal` n’en crée aucune ; sans `storage_kms_key_arn`, ses buckets restent en SSE-S3. Une clé créée comporte un unique statement pour le compte root, qui délègue l’accès à IAM. Une clé que vous fournissez doit disposer de la même délégation, ou bien des grants suivants dans sa politique de clé :

| Clé | Principal | Actions |
| - | - | - |
| Secrets EKS | `<cluster_name>-cluster` | `kms:Encrypt`, `kms:Decrypt`, `kms:DescribeKey` |
| EBS | `<cluster_name>-ebs-csi-driver`, `<cluster_name>-karpenter-controller` | `kms:Encrypt`, `kms:Decrypt`, `kms:ReEncrypt*`, `kms:GenerateDataKey*`, `kms:DescribeKey`, `kms:CreateGrant` avec la condition `kms:GrantIsForAWSResource = true` |
| Stockage | Chaque `CH-S3-<service>-<region>-00-Role` créé par `clicklink clctl executor prepare --storage-kms-key-arn` | `kms:Decrypt`, `kms:GenerateDataKey`, `kms:DescribeKey` |
| Stockage | `<cluster_name>-clicklink-executor`, pour l’enregistrement de clé `_tde/` stocké à côté des sauvegardes d’un service | `kms:GenerateDataKey`, `kms:Decrypt` |

Dans tous les cas, les modules racines rattachent les politiques des rôles IAM pour les clés des secrets EKS et EBS, ainsi que la politique de clé de stockage de l’executor dès lors que le module racine dispose d’une clé de stockage ; `executor prepare` rattache la politique de chaque rôle de service. Les volumes racines des nœuds système contiennent les images et les logs du kubelet, et non les données des services ; ils utilisent la clé EBS par défaut du compte.

## Détruire l’infrastructure gérée par Terraform

`terraform destroy` supprime tout ce que la racine a créé. Les clés KMS créées entrent dans une période de suppression de 30 jours. Les groupes de logs sont supprimés avec les logs qu’ils conservent : exportez donc au préalable ce dont vous avez besoin. Les instances lancées par Karpenter et les volumes créés par le ClickHouse Operator ne figurent pas dans l’état Terraform ; supprimez d’abord vos services et désinstallez Karpenter, faute de quoi la suppression du VPC et du rôle des nœuds échouera.

`existing-eks` conserve le cluster. Il supprime les rôles, la file d’attente d’interruption et ses règles, l’entrée d’accès ainsi que les balises qu’il a ajoutées. Les addons `vpc-cni`, `kube-proxy` et `coredns` qu’il a installés ne sont plus gérés par EKS, mais leurs pods continuent de s’exécuter. Si la racine a installé l’addon du driver EBS CSI, celui-ci est supprimé avec elle, car son rôle IRSA est également détruit. Pour conserver le driver, recréez l’addon avec votre propre rôle avant la destruction.

La destruction supprime toutes les balises ajoutées par ces racines, y compris une éventuelle balise `kubernetes.io/role/internal-elb` antérieure à la racine, car `aws_ec2_tag` s’approprie toute balise existante. Pour les conserver, définissez `manage_subnet_tags = false` (`existing-vpc`) ou `manage_discovery_tags = false` (`existing-eks`) et appliquez la configuration avant la destruction, ou retirez les ressources `aws_ec2_tag` de l’état avec `terraform state rm`.
