vpc-cni、kube-proxy、coredns、aws-ebs-csi-driver) を備えたクラスターを作成するほか、IAM role、KMS キー、タグも作成します。なお、existing-eks は install_addons で指定したアドオンのみをインストールします。Helm ターゲットの場合は、その後 clicklink clctl init が Terraform の出力とプラットフォームバンドルを使用してプラットフォームレイヤーをインストールします。プラットフォームレイヤーには、Karpenter、AWS Load Balancer コントローラー、StorageClass、およびバージョンが固定されたコンポーネントが含まれます (Terraform の出力からコネクタを初期化するを参照) 。ルートを使用するには、Terraform 1.10 以降または OpenTofu 1.12 以降と、AWS プロバイダー ~> 6.0 が必要です。このページのすべてのコマンドで、terraform の代わりに tofu を使用できます。
始める前に
以下が必要です。- Terraform 1.10 以降または OpenTofu 1.12 以降、および AWS プロバイダー
~> 6.0。 - 選択したルートで必要となるリソースの作成・変更権限を持つ AWS アイデンティティ。
- リリースアーカイブのダウンロードと検証に使用する
curl、SHA-256 ツール (sha256sumまたはshasum) 、およびcosign。 - 登録時に取得した以下の情報:すべてのルートで必要な
chart_repository_arn、および最後にinitへ引き渡すコネクタエンドポイント、登録トークン、プラットフォームバンドル。
production および existing-vpc を使用する場合は、clicklink clctl init と kubectl を実行するマシンからプライベートな EKS API にどのようにアクセスするかを事前に検討しておいてください。VPN、踏み台サーバー、ピアリング接続されたネットワーク、SSM ポートフォワーディングなどの方法があります。
環境に適した Terraform ルートを選択する
4つのルートはいずれも同じ
VPC は 3 つのゾーン (
いずれのルートも、自身が作成していないリソース (ルートテーブル、NAT ゲートウェイ、エンドポイント、セキュリティグループルール、ノードグループ、起動テンプレート、クラスター設定、KMS キー) は変更しません。どちらのルートも、プライベートサブネットに
clicklink の出力を生成します。どのルートを適用した場合でも、clicklink clctl init への引き継ぎ方法は変わりません。minimal
minimal では、パブリックエンドポイント、インターフェイスエンドポイント、フローログ、ログの保持期間、システム pool のサイズに関する設定が緩和されています。緩和された変数はいずれも、両方のルートに同じ名前で存在します。いずれかを本番環境向けの値に変更する場合は、terraform.tfvars を編集して再適用するだけで済みます。一方、ワークロードが単一ゾーンであることと KMS キーが存在しないことは後から変更できません。サブネットのゾーンは変更できず、またルートには EKS の Secret 暗号化用の変数がないためです。これらの差異を解消するには、production を新しいクラスターとして適用する必要があります。production
VPC は 3 つのゾーン (availability_zone_count で 2〜4 を指定可能) にまたがり、ゾーンごとにプライベート /19 サブネット、パブリック /21 サブネット、NAT ゲートウェイ 1 つを配置します。さらに、S3 ゲートウェイエンドポイント、ECR、STS、EKS、EC2、CloudWatch Logs、SSM、SQS、KMS、ELB 用のインターフェイスエンドポイント、および VPC フローログを備えます。 EKS クラスターは、プライベート API エンドポイント、アクセスエントリによる認証、ルートが所有するロググループへのすべてのコントロールプレーンログタイプの出力、およびカスタマー管理の KMS キーによる Secret の暗号化を備えます。 クラスターには、マネージドアドオン vpc-cni、kube-proxy、coredns、aws-ebs-csi-driver と、clickhouseGroup=system ラベルが付いた taint なしのシステムノードグループ 1 つ (デフォルトでは m7g.large ノード 2〜4 台) が構成されます。 さらにルートは、中断キューと karpenter.sh/discovery タグを含む Karpenter 用 IAM、AWS Load Balancer コントローラーおよびコネクタの executor 用の IRSA ロール、そして EBS ボリュームとオブジェクトストレージバケット用の KMS キーも作成します。existing-vpc と existing-eks
いずれのルートも、自身が作成していないリソース (ルートテーブル、NAT ゲートウェイ、エンドポイント、セキュリティグループルール、ノードグループ、起動テンプレート、クラスター設定、KMS キー) は変更しません。どちらのルートも、プライベートサブネットに karpenter.sh/discovery=<cluster_name> および kubernetes.io/role/internal-elb=1 のタグを付与します。さらに existing-vpc はパブリックサブネットに kubernetes.io/role/elb=1 のタグを付与し、existing-eks はクラスターのセキュリティグループにタグを付与します。existing-vpc を使用する場合、VPC で次のものがあらかじめ用意されている必要があります:- DNS サポートと DNS ホスト名が有効になっていること。
- 少なくとも 2 つのアベイラビリティゾーンにまたがる 2~4 個のプライベートサブネットがあること。これらのサブネットでは
map_public_ip_on_launchを無効にし、NAT ゲートウェイ、または ECR、STS、EKS、EC2、CloudWatch Logs、SSM、SQS、KMS、ELB 用のインターフェイスエンドポイントへルーティングされている必要があります。また、S3 ゲートウェイエンドポイントも追加してください。これがないと、オブジェクトストレージのトラフィックが NAT ゲートウェイを経由することになります。 - パブリックサブネットは、インターネット向けのロードバランサーを使用する場合にのみ必要です。VPC にパブリック層がない場合は、
public_subnet_idsを空のままにしてください。
existing-eks を使用する場合、クラスターに以下がすでに用意されている必要があります。- Kubernetes 1.34 以降。
- 認証モードが
APIまたはAPI_AND_CONFIG_MAPであること。CONFIG_MAPのクラスターでは、plan の出力に切り替え用のコマンドが表示されます。 - クラスターの issuer に対応する IAM OIDC プロバイダー。
- 2 つ以上のアベイラビリティゾーンにまたがるプライベートサブネットがあり、NAT またはインターフェイスエンドポイント経由で AWS API へのエグレスが可能であること。デフォルトでは、ルートモジュールはクラスターのサブネットから、ルートテーブルがインターネットゲートウェイに到達するものを除外してプライベートサブネットを導出します。クラスターのサブネットがコントロールプレーン専用の
/28である場合や、ノードを別のサブネットに配置する場合は、private_subnet_idsを設定してください。 - Karpenter がインストールされていないこと。Karpenter の IAM と中断キューはこのルートモジュールが作成します。キュー名は
<cluster_name>-clicklinkとなるため、アンインストール済みの Karpenter が残したキューと衝突することはありません。 system_node_selectorのラベル (デフォルトはclickhouseGroup=system) が付与され、taint が設定されていないシステムノード。このルートモジュールはノードグループを作成しません。
terraform plan は失敗します。install_addons 内のアドオンがすでにセルフマネージドでインストールされ稼働している場合、EKS は Conflicts found when trying to apply を返します。addon_resolve_conflicts_on_create = "OVERWRITE" を設定してマネージドアドオンに引き継がせるか、該当アドオンを install_addons から削除してください。Terraformのリリースアーカイブをダウンロードして検証する
ルート証明書はリリースごとに 1 つのアーカイブとして提供され、バージョンは 展開する前に、cosign を使用して署名を検証します。次に、ダウンロードしたファイルを展開します。アーカイブを展開すると、
clicklink バイナリと共通です。現在のリリースのアーカイブを、チェックサムおよび cosign バンドルとあわせて取得します:aws/production、aws/minimal、aws/existing-vpc、aws/existing-eks、aws/modules を含む1つのディレクトリが作成されます。各ルートはモジュールを ../modules として参照しています。ルートを1つだけ取り出してコピーせず、展開したツリーはそのままの構成で保持してください。アーカイブ内の各ルートの README には、--platform-bundle を指定しない init への引き渡し手順が記載されている場合があります。サポートされているのは、Terraform の出力からコネクタを初期化する に記載されているコマンドです。選択したルートを設定し、適用します
ルートディレクトリで、サンプルの変数ファイルをコピーして値を入力します:すべてのルートで アーカイブにはプロバイダーのロックファイルが含まれていません。
region、cluster_name、chart_repository_arn が必要です。cluster_name はクラスター名として使われるほか、すべてのリソース名のプレフィックスとなり、ディスカバリー用のタグの値にもなります。production、minimal、existing-vpc では、英小文字、数字、ハイフンからなる 3〜32 文字で指定します。先頭は英字とし、末尾をハイフンにすることはできません。existing-eks では、既存の稼働中クラスターの名前 (最大 32 文字) を指定します。chart_repository_arn は ClickHouse クラスターのチャートを格納した ECR リポジトリで、登録時にアカウントチームから提供されます。クラスターを作成するルートでは、cluster_admin_principal_arns も必要です。これは、EKS アクセスエントリを通じてクラスター管理者権限を付与するプリンシパルのリストです。ルートを実行するアイデンティティは必ずこのリストに含めてください。含まれていない場合、実行後にクラスターへアクセスできなくなります。クラスターの作成者に暗黙的なアクセス権は付与されません。ルートごとの要件は次のとおりです。minimalでは、パブリック API エンドポイントへのアクセスを許可する IPv4 の許可リストendpoint_public_access_cidrsが必要です。initやkubectlを実行するネットワークを、このリストに含める必要があります。/0は、allow_public_endpoint_from_anywhere = trueを指定しない限り拒否されます。endpoint_public_access = falseの場合はリストを空にでき、その場合エンドポイントはproductionと同様にプライベートアクセスのみとなります。existing-vpcでは、vpc_idとprivate_subnet_idsが必要です。public_subnet_idsは任意で、インターネット向けロードバランサーを使用する場合に指定します。existing-eksでは、ほかに必須の変数はありません。install_addonsにはクラスターに不足しているマネージドアドオンを指定し、ebs_kms_key_arnにはサービスのボリュームで使用する鍵を指定します。
terraform providers lock を実行するとロックファイルが生成されるので、手元のコピーにコミットしてください。ステートはデフォルトではローカルに保存されます。versions.tf にはコメントアウトされた backend "s3" ブロックが含まれており、ステートを共有する場合の構成例を示しています。production および existing-vpc の API エンドポイントはプライベートです。init と kubectl は VPC 内から実行してください (システムノードへの SSM ポートフォワード、踏み台サーバー、VPN、ピアリングされたネットワークなどを経由) 。または、endpoint_public_access = true を指定し、endpoint_public_access_cidrs に許可リストを設定して、パブリックアクセスを明示的に有効にすることもできます。Terraformの出力を使用してコネクタを初期化する
出力をエクスポートしてから、kube コンテキストが新しいクラスターを指しているマシン上で、プラットフォームバンドルとあわせて これらのルートは Helm ターゲットのみをサポートします。VM 上 (
init に渡します:--target systemd) では init が --platform-bundle を受け付けず、clicklink clctl platform approve --bundle もピン留めされたコンポーネントしかインストールしないため、クラスターにノードプロビジョナーが存在しない状態になります。--target systemd は、自身で運用している ClickHouse を登録するコネクタにのみ使用してください。これらのルートではサポートされていません。--platform-bundle は、ルートに含まれないものをインストールします。具体的には、EC2NodeClass と clickhouse-server および clickhouse-keeper の NodePool を備えた Karpenter、AWS Load Balancer コントローラー、gp3-encrypted StorageClass (出力に EBS 鍵が含まれている場合はその鍵で暗号化) 、そしてバンドルがピン留めするプラットフォームコンポーネント (スナップショットコントローラー、ClickHouse オペレーター、監視用 collector) です。バンドルは ClickHouse Cloud がお使いの環境向けに生成するプラットフォームマニフェストで、オンボーディング時にアカウントチームから提供されます。その cluster: セクションで Karpenter とロードバランサーコントローラーのバージョンがピン留めされています。このフラグを使用するには --target helm、--managed、--from-terraform の指定が必要です。既に存在するコンポーネントには手を加えないため、コマンドは安全に再実行できます。また init は、インストールしたもの、スキップしたもの、およびその理由をレポートとして出力します。このフラグを指定しない場合、init はコネクタを登録しますが、これらのコンポーネントは一切インストールしません。これらが揃うまで、クラスターでサービスを実行することはできません。その後のプラットフォーム更新で変更されるのは、スナップショットコントローラー、オペレーター、collector です。Karpenter、ロードバランサーコントローラー、StorageClass は init がインストールした状態のまま維持されます。--from-terraform には、terraform output -json が出力するドキュメント全体、または terraform output -json clicklink が出力するオブジェクト単体のどちらでも指定できます。clicklink 出力には、クラスターのアイデンティティ (account_id、region、cluster_name、cluster_endpoint、cluster_ca) 、OIDC プロバイダー、コネクタのネームスペース、executor の IAM ロール (executor_role_arn) 、EBS 鍵、Karpenter のノードロールとキュー、ロードバランサーコントローラーのロール、system_node_selector が含まれます。init はこのファイルからクラスターのアイデンティティとコネクタのネームスペースを読み取ります。さらに、executor_role_arn をコネクタの pcm-executor ServiceAccount に IRSA アノテーションとして設定し、コネクタの Pod にノードセレクターを適用します。マネージドサービスはこのロールを共有しません。clicklink clctl executor prepare はサービスごとにロールを 1 つ (デフォルトでは CH-S3-<service>-<region>-00-Role) 作成し、サービスの作成時にそのサービスへ紐付けます。詳細は権限モデルを参照してください。--cluster-name や --target-namespace などのフラグがファイルの内容と一致しない場合、init は両方の値を示してエラーとします。フラグを削除するか、出力を修正してください。また、API サーバーが cluster_endpoint と異なる kube コンテキストや、EKS ARN が別のクラスターを指している kube コンテキストも受け付けません。出力には schema フィールドがあり、現在の値は 1 です。clctl は、サポート対象外の schema を持つファイルを受け付けません。残りの登録手順は、オンボーディングの標準フローと同じです。KMS キーと必要な権限
production と existing-vpc は、kms で ARN を渡さない限り、EKS シークレット、EBS ボリューム、オブジェクトストレージのバケット用に、ローテーションを有効にしたカスタマー管理の KMS キーを 3 つ作成します。existing-eks は、storage_kms_key_arn を設定しない限りストレージ用キーを作成します。サービスボリューム用には ebs_kms_key_arn を受け取りますが、このキーは作成しません。minimal はキーを一切作成しません。storage_kms_key_arn を指定しない場合、バケットは SSE-S3 のままです。作成されたキーには、IAM にアクセスを委任するアカウントルートのステートメントが 1 つ含まれます。ユーザーが用意するキーには、同じ委任を設定するか、キーポリシーで以下の権限を付与する必要があります。
ルートは、どちらの場合でも EKS シークレット用および EBS 用キーに対する IAM role のポリシーをアタッチします。また、ルートがストレージ用キーを持つ場合は、executor のストレージキーポリシーも必ずアタッチします。各サービスロールのポリシーは
executor prepare がアタッチします。システムノードのルートボリュームに格納されるのはイメージとキューブレットのログのみで、サービスデータは含まれません。これらのボリュームにはアカウントのデフォルトの EBS キーが使用されます。
Terraform で管理されているインフラストラクチャの削除
terraform destroy は、ルートモジュールが作成したリソースを削除します。作成された KMS キーは 30 日間の削除待機期間に入ります。ロググループは保持されているログごと削除されるため、必要なログは事前にエクスポートしてください。Karpenter が起動したインスタンスや ClickHouse Operator が作成したボリュームは Terraform ステートで管理されていません。先にサービスを削除し、Karpenter をアンインストールしておいてください。そうしないと、VPC とノードロールの削除に失敗します。
existing-eks では、クラスター自体は削除されずに残ります。削除されるのは、このルートモジュールが追加したロール、中断キューとルール、アクセスエントリ、およびタグです。このルートモジュールがインストールした vpc-cni、kube-proxy、coredns アドオンは EKS の管理対象から外れますが、それらのポッドは引き続き実行されます。一方、このルートモジュールがインストールした EBS CSI ドライバーアドオンは、その IRSA ロールも削除されるため、ルートモジュールとともに削除されます。ドライバーを残したい場合は、destroy を実行する前に独自のロールを使ってアドオンを再作成してください。
destroy を実行すると、これらのルートモジュールが追加したタグはすべて削除されます。aws_ec2_tag は既存のタグの所有権を引き継ぐため、ルートモジュールの適用前から存在していた kubernetes.io/role/internal-elb タグも削除対象になります。タグを残すには、destroy の前に manage_subnet_tags = false (existing-vpc) または manage_discovery_tags = false (existing-eks) を設定して apply するか、terraform state rm で aws_ec2_tag リソースをステートから除外してください。