> ## 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.

# Aprovisionar infraestructura de AWS con Terraform

> Cree un cluster de Amazon EKS para el modo administrado, o agregue los recursos necesarios a una VPC o un cluster existente, con Terraform u OpenTofu

Vista previa privada

El modo administrado se ejecuta en un cluster de Amazon EKS de su propiedad. Cada versión incluye cuatro módulos raíz de Terraform (en adelante, raíces) que crean un cluster que cumple sus requisitos o añaden lo necesario a una VPC o a un cluster que ya tenga. Las raíces crean el cluster con su grupo de nodos del sistema y los complementos administrados (`vpc-cni`, `kube-proxy`, `coredns`, `aws-ebs-csi-driver`), además de los roles de IAM, las claves de KMS y las etiquetas; `existing-eks` instala únicamente los complementos que indique en `install_addons`. En el destino de Helm, `clicklink clctl init` instala a continuación la capa de plataforma a partir de las salidas y de un paquete de plataforma: Karpenter, el controlador AWS Load Balancer, la clase de almacenamiento y los componentes con versión fijada (consulte [inicializar el connector a partir de las salidas de Terraform](#hand-off)). Las raíces requieren Terraform 1.10+ u OpenTofu 1.12+ y el provider de AWS `~> 6.0`. Puede usar `tofu` en lugar de `terraform` en todos los comandos de esta página.

![Flujo de aprovisionamiento con Terraform para el ClickHouse Connector en 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)

## Antes de comenzar

Necesita:

* Terraform 1.10+ u OpenTofu 1.12+, además del provider de AWS `~> 6.0`.
* Una identity de AWS con permisos para crear y modificar los recursos que requiere la raíz seleccionada.
* `curl`, una herramienta SHA-256 (`sha256sum` o `shasum`) y `cosign` para descargar y verificar el archivo de la versión publicada.
* Del [registro](/docs/es/products/bring-your-own-cloud/connector/onboarding#registration): el `chart_repository_arn` que requiere cada raíz, además del endpoint del conector, el token de inscripción y el paquete de la plataforma para el traspaso final a `init`.

Para `production` y `existing-vpc`, planifique cómo accederá a la API privada de EKS la máquina que ejecute `clicklink clctl init` y `kubectl`; por ejemplo, mediante una VPN, un bastión, una red con peering o un reenvío de puertos de SSM.

## 1. Elija el directorio raíz de Terraform para su entorno

Las cuatro raíces producen la misma salida de `clicklink`. El paso a `clicklink clctl init` es idéntico, sea cual sea la que apliques.

| Raíz | Punto de partida | Crea |
| - | - | - |
| `minimal` | Clusters de desarrollo y de prueba de concepto | Lo mismo, una zona, un endpoint público, sin endpoints ni CMK |
| `production` | Una cuenta y una región vacías | VPC, cluster de EKS, grupo de nodos, IAM, KMS |
| `existing-vpc` | Una VPC existente | Cluster de EKS, grupo de nodos, IAM, KMS, etiquetas de subred |
| `existing-eks` | Un cluster que ya tiene en funcionamiento | IAM, complementos con nombre, permisos sobre claves, etiquetas de descubrimiento |

### `minimal`

`minimal` flexibiliza el endpoint público, los endpoints de interfaz, los flow logs, la retención de logs y el tamaño del grupo del sistema. Cada variable flexibilizada existe en ambas raíces con el mismo nombre. Llevar una a su valor de producción solo requiere un cambio en `terraform.tfvars` y volver a aplicar. La zona única de workload y la ausencia de claves KMS son fijas: las subredes no pueden cambiar de zona y la raíz no tiene ninguna variable para el cifrado de secretos de EKS. Para resolver esas carencias, hay que aplicar `production` como un cluster nuevo.

### `production`

La VPC abarca tres zonas (`availability_zone_count`, de 2 a 4) con una subred privada `/19` y una pública `/21` por zona, un gateway NAT por zona, un endpoint de gateway para S3, endpoints de interfaz para ECR, STS, EKS, EC2, CloudWatch Logs, SSM, SQS, KMS y ELB, y logs de flujo de la VPC. El cluster de EKS tiene un endpoint privado de la API, autenticación mediante entradas de acceso, todos los tipos de log del plano de control en un grupo de logs propiedad del módulo raíz, y secretos cifrados con una clave KMS gestionada por el cliente. El cluster incorpora los complementos administrados `vpc-cni`, `kube-proxy`, `coredns` y `aws-ebs-csi-driver`, así como un grupo de nodos de sistema sin taints con la etiqueta `clickhouseGroup=system` (de dos a cuatro nodos `m7g.large` de forma predeterminada). El módulo raíz también crea los recursos de IAM de Karpenter con una cola de interrupciones y etiquetas `karpenter.sh/discovery`, roles de IRSA para el controlador de AWS Load Balancer y para el ejecutor del connector, y claves KMS para los volúmenes EBS y para los buckets de almacenamiento de objetos.

### `existing-vpc` y `existing-eks`

Ninguno de los dos módulos raíz modifica lo que no creó: tablas de rutas, gateways NAT, endpoints, reglas de grupos de seguridad, grupos de nodos, plantillas de lanzamiento, la configuración del cluster ni las claves de KMS. Ambos etiquetan las subredes privadas con `karpenter.sh/discovery=<cluster_name>` y `kubernetes.io/role/internal-elb=1`; `existing-vpc` también etiqueta las subredes públicas con `kubernetes.io/role/elb=1`, y `existing-eks` etiqueta el grupo de seguridad del cluster.

Con `existing-vpc`, la VPC ya debe contar con lo siguiente:

* Compatibilidad con DNS y nombres de host DNS habilitados.
* De dos a cuatro subredes privadas en al menos dos zonas de disponibilidad, con `map_public_ip_on_launch` desactivado y con enrutamiento hacia un gateway NAT o hacia endpoints de interfaz para ECR, STS, EKS, EC2, CloudWatch Logs, SSM, SQS, KMS y ELB. Agregue un endpoint de gateway para S3; de lo contrario, el tráfico hacia el almacenamiento de objetos pasará por los gateways NAT.
* Subredes públicas, solo si desea balanceadores de carga expuestos a Internet. Deje `public_subnet_ids` vacío si la VPC no tiene una capa pública.

Para `existing-eks`, el cluster ya debe contar con:

* Kubernetes 1.34 o posterior.
* Modo de autenticación `API` o `API_AND_CONFIG_MAP`. Para un cluster con `CONFIG_MAP`, el plan muestra el comando necesario para cambiar de modo.
* Un provider OIDC de IAM para el emisor del cluster.
* Subredes privadas en al menos dos zonas de disponibilidad con salida a las API de AWS a través de NAT o endpoints de interfaz. De forma predeterminada, el módulo raíz las obtiene a partir de las subredes del cluster y descarta aquellas cuya tabla de rutas apunta a un internet gateway. Configure `private_subnet_ids` cuando las subredes del cluster sean `/28` exclusivas del plano de control o cuando los nodos deban ubicarse en otras subredes.
* Karpenter no debe estar instalado: este módulo raíz crea los recursos de IAM de Karpenter y la cola de interrupciones. La cola se denomina `<cluster_name>-clicklink`, por lo que no puede entrar en conflicto con ninguna cola residual de una instalación de Karpenter eliminada.
* Nodos de sistema sin taints que tengan las etiquetas definidas en `system_node_selector` (`clickhouseGroup=system` de forma predeterminada). Este módulo raíz no crea ningún grupo de nodos.

`terraform plan` falla si falta alguno de estos elementos.

Si un complemento de `install_addons` ya se está ejecutando como instalación autogestionada, EKS devuelve `Conflicts found when trying to apply`. Establezca `addon_resolve_conflicts_on_create = "OVERWRITE"` para que el complemento administrado tome el control, o quítelo de `install_addons`.

## 2. Descargue y verifique el archivo comprimido de la versión de Terraform

Las raíces se distribuyen en un archivo por versión, con la misma numeración de versión que el binary `clicklink`. Descargue el archivo de la versión actual junto con su suma de comprobación y su paquete de 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
```

Verifique la firma con cosign antes de extraer el contenido:

```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}"
```

A continuación, extráigalo:

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

El archivo se extrae en un único directorio que contiene `aws/production`, `aws/minimal`, `aws/existing-vpc`, `aws/existing-eks` y `aws/modules`. Los módulos raíz hacen referencia a los módulos como `../modules`. Mantenga el árbol extraído completo en lugar de copiar un módulo raíz por separado. Es posible que los README de los módulos raíz del archivo muestren el traspaso a `init` sin `--platform-bundle`; el comando compatible es el que se indica en [inicializar el connector a partir de las salidas de Terraform](#hand-off).

## 3. Configure y aplique la raíz seleccionada

Desde el directorio raíz, copie el archivo de variables de ejemplo y rellénelo:

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

Cada raíz requiere `region`, `cluster_name` y `chart_repository_arn`. `cluster_name` asigna el nombre al cluster, sirve de prefijo para cada recurso y es el valor de la etiqueta de descubrimiento. En `production`, `minimal` y `existing-vpc` debe tener entre 3 y 32 caracteres (letras minúsculas, dígitos y guiones), empezar por una letra y no terminar en guion. En `existing-eks` se indica el nombre del cluster que ya tiene en ejecución, de hasta 32 caracteres. `chart_repository_arn` es el repositorio de ECR del chart del cluster de ClickHouse, que su account team le proporciona durante el [registro](/docs/es/products/bring-your-own-cloud/connector/onboarding#registration). Las raíces que crean un cluster también requieren `cluster_admin_principal_arns`, las entidades principales que obtienen permisos de administrador del cluster mediante entradas de acceso de EKS. La identidad que ejecuta la raíz debe figurar en esa lista; de lo contrario, no podrá acceder al cluster posteriormente. El creador del cluster no obtiene acceso implícito. Según la raíz:

* `minimal` requiere `endpoint_public_access_cidrs`, la lista de permitidos IPv4 para el endpoint público de la API. La red desde la que ejecute `init` y `kubectl` debe estar incluida en ella. Se rechaza un `/0` salvo que se establezca `allow_public_endpoint_from_anywhere = true`. Con `endpoint_public_access = false`, la lista puede quedar vacía y el endpoint es exclusivamente privado, como en `production`.
* `existing-vpc` requiere `vpc_id` y `private_subnet_ids`. `public_subnet_ids` es opcional y se usa para balanceadores de carga expuestos a internet.
* `existing-eks` no requiere más variables. `install_addons` indica los complementos administrados que le faltan al cluster, y `ebs_kms_key_arn` proporciona una clave para los volúmenes del servicio.

A continuación, inicialice, planifique y aplique:

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

El archivo comprimido no incluye un archivo de bloqueo de providers. `terraform providers lock` genera uno para que hagas commit en tu copia. De forma predeterminada, el estado es local. `versions.tf` incluye un bloque `backend "s3"` comentado que muestra cómo se estructura el estado compartido.

> [!NOTE]
>
> Los endpoints de API de `production` y `existing-vpc` son privados. Ejecuta `init` y `kubectl` desde dentro de la VPC (mediante un reenvío de puertos de SSM a un nodo del sistema, un bastión, una VPN o una red con peering), o habilita el acceso público con `endpoint_public_access = true` y una lista de permitidos en `endpoint_public_access_cidrs`.

## 4. Inicialice el connector con los valores de salida de Terraform

Exporte las salidas y luego páselas a `init` junto con el paquete de la plataforma, desde una máquina cuyo contexto de kube apunte al nuevo 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
```

Los módulos raíz solo admiten el destino Helm. En una VM (`--target systemd`), `init` rechaza `--platform-bundle`, y `clicklink clctl platform approve --bundle` instala únicamente los componentes fijados, por lo que el cluster no dispone de aprovisionador de nodos. Use `--target systemd` solo para connectors que registran un ClickHouse que usted mismo ejecuta; no es compatible con estos módulos raíz.

`--platform-bundle` instala lo que los módulos raíz no incluyen: Karpenter con un `EC2NodeClass` y los NodePools `clickhouse-server` y `clickhouse-keeper`, el controlador AWS Load Balancer, la clase de almacenamiento `gp3-encrypted` (cifrada con la clave de EBS cuando las salidas incluyen una) y los componentes de plataforma que fija el paquete: el controlador de instantáneas, el ClickHouse operator y los recolectores de monitorización. El paquete es el manifiesto de plataforma que ClickHouse Cloud genera para su entorno; su equipo de cuenta se lo entrega durante el onboarding, y su sección `cluster:` fija las versiones de Karpenter y del controlador del balanceador de carga. El indicador requiere `--target helm`, `--managed` y `--from-terraform`. Los componentes que ya están presentes no se modifican, por lo que es seguro volver a ejecutar el comando; además, `init` imprime un informe de lo que instaló, lo que omitió y por qué. Sin el indicador, `init` inscribe el connector pero no instala ninguno de estos componentes, y el cluster no puede ejecutar ningún servicio hasta que estén instalados. Las [actualizaciones de plataforma](/docs/es/products/bring-your-own-cloud/connector/platform-updates) posteriores modifican el controlador de instantáneas, el operador y los recolectores; Karpenter, el controlador del balanceador de carga y la clase de almacenamiento se mantienen tal como los instaló `init`.

`--from-terraform` acepta tanto el documento completo que imprime `terraform output -json` como el objeto simple que devuelve `terraform output -json clicklink`. La salida `clicklink` contiene la identity del cluster (`account_id`, `region`, `cluster_name`, `cluster_endpoint`, `cluster_ca`), el proveedor OIDC, el espacio de nombres del connector, el rol de IAM del ejecutor (`executor_role_arn`), la clave de EBS, el rol de nodo y la cola de Karpenter, el rol del controlador del balanceador de carga y `system_node_selector`. `init` lee del archivo la identity del cluster y el espacio de nombres del connector. Establece `executor_role_arn` como anotación IRSA en el ServiceAccount `pcm-executor` del connector y aplica el selector de nodos a los pods del connector. Los servicios gestionados no comparten ese rol: `clicklink clctl executor prepare` crea un rol por servicio (`CH-S3-<service>-<region>-00-Role` de forma predeterminada), que se vincula al servicio en el momento de su creación; consulte el [modelo de privilegios](/docs/es/products/bring-your-own-cloud/connector/reference/privilege-model#identities).

`init` rechaza cualquier indicador, como `--cluster-name` o `--target-namespace`, que no coincida con el archivo, e indica ambos valores. Elimine el indicador o corrija las salidas. También rechaza un contexto de kube cuyo servidor de API no sea `cluster_endpoint` o cuyo ARN de EKS corresponda a otro cluster. La salida incluye un campo `schema`, actualmente `1`. `clctl` rechaza cualquier archivo cuyo `schema` no admita.

El resto de la inscripción sigue el flujo estándar descrito en [onboarding](/docs/es/products/bring-your-own-cloud/connector/onboarding#install-and-enroll).

## Claves de KMS y permisos requeridos

`production` y `existing-vpc` crean tres claves de KMS gestionadas por el cliente, con la rotación activada, para los secretos de EKS, los volúmenes de EBS y los buckets de almacenamiento de objetos, salvo que proporcione ARN en `kms`. `existing-eks` crea la clave de almacenamiento salvo que establezca `storage_kms_key_arn`, y acepta `ebs_kms_key_arn` para los volúmenes de los servicios sin crear ninguna. `minimal` no crea ninguna; si no se establece `storage_kms_key_arn`, sus buckets siguen usando SSE-S3. Cada clave creada incluye una sentencia para la raíz de la cuenta que delega el acceso en IAM. Una clave que proporcione usted necesita esa misma delegación o bien los siguientes permisos en su política de clave:

| Clave | Principal | Acciones |
| - | - | - |
| Secretos de 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` con la condición `kms:GrantIsForAWSResource = true` |
| Almacenamiento | Cada `CH-S3-<service>-<region>-00-Role` que crea `clicklink clctl executor prepare --storage-kms-key-arn` | `kms:Decrypt`, `kms:GenerateDataKey`, `kms:DescribeKey` |
| Almacenamiento | `<cluster_name>-clicklink-executor`, para el registro de claves `_tde/` situado junto a las copias de seguridad de un servicio | `kms:GenerateDataKey`, `kms:Decrypt` |

En ambos casos, los módulos raíz adjuntan las políticas del rol de IAM para las claves de los secretos de EKS y de EBS, así como la política de la clave de almacenamiento del executor siempre que el módulo raíz disponga de una clave de almacenamiento; `executor prepare` adjunta la política del rol de cada servicio. Los volúmenes raíz de los nodos del sistema almacenan imágenes y logs del agente kubelet, no datos de los servicios, y usan la clave de EBS predeterminada de la cuenta.

## Destruir la infraestructura administrada por Terraform

`terraform destroy` elimina lo que creó el módulo raíz. Las claves KMS creadas entran en un período de eliminación de 30 días. Los grupos de logs se eliminan junto con los logs que conservan, así que exporte antes lo que necesite. Las instancias que lanzó Karpenter y los volúmenes que creó el ClickHouse Operator no están en el estado de Terraform; elimine primero sus servicios y desinstale Karpenter, o fallará la eliminación de la VPC y del rol de los nodos.

`existing-eks` no elimina el cluster. Elimina los roles, la cola de interrupciones y sus reglas, la entrada de acceso y las etiquetas que añadió. Los complementos `vpc-cni`, `kube-proxy` y `coredns` que instaló dejan de estar administrados por EKS, pero sus pods siguen en ejecución. Si instaló el complemento del controlador EBS CSI, este se elimina junto con el módulo raíz, ya que su rol de IRSA también se destruye. Para conservar el controlador, vuelva a crear el complemento con su propio rol antes de ejecutar la destrucción.

La destrucción elimina todas las etiquetas que añadieron estos módulos raíz, incluida una etiqueta `kubernetes.io/role/internal-elb` que ya existía antes del módulo raíz, porque `aws_ec2_tag` asume la propiedad de cualquier etiqueta existente. Para conservarlas, establezca `manage_subnet_tags = false` (`existing-vpc`) o `manage_discovery_tags = false` (`existing-eks`) y aplique los cambios antes de destruir, o ejecute `terraform state rm` sobre los recursos `aws_ec2_tag`.
