既存 TiDB Cloud Starter (旧: Serverless) クラスタを Terraform 管理へ import する

既存 TiDB Cloud Starter (旧: Serverless) クラスタを Terraform 管理へ import する

作成済みの TiDB Cloud Starter クラスタを壊さずに Terraform 管理へ移す手順を解説します。API キー、Project ID と Cluster ID、terraform import、refresh-only の確認、そして region.name には regions/aws-<region-id> と書く、要点のまとめです。

はじめに

本記事では、作成済みの TiDB Cloud クラスタを Terraform 管理下に取り込む手順を解説します。今回の対象は Starter とし、 Dedicated については本記事のスコープ外とします。Terraform プロバイダの導入、API キー設定、Project ID と Cluster ID の取得、リージョン指定、terraform import の実行と整合性確認までを、最小の構成でまとめます。Starter においては選択可能なリージョンが制限される点に加え、region.name には regions/aws-<region-id> の正規形で指定する必要がある点がつまずきやすい箇所です。

TiDB とは

TiDB は MySQL 互換の分散データベースです。オンライン処理と分析処理を同一クラスターで扱えます。TiDB Cloud を使うとマネージドで運用可能で、無償枠の Starter と、構成を柔軟に選べる Dedicated が提供されています。

Terraform とは

Terraform は IaC ツールです。クラウドリソースの望ましい状態をコードで宣言し、planapply で差分を反映できます。既存資産は import で状態管理に取り込めます。

対象読者

  • 既に TiDB Cloud コンソールでクラスタを作成済みで、Terraform 管理に移したい方
  • Starter のリージョン指定や import まわりのつまずきポイントを短時間で把握したい方
  • CI から安全に再実行できる形に整えたい方

参考

環境構築

既存の Starter クラスタを後から import する前提で、Terraform の作業環境を整えます。目的は、プロバイダが正しく初期化され、最小構成で plan が通る状態を作ることです。

Terraform とプロバイダを導入する

最初に CLI を用意します。macOS の例です。

brew tap hashicorp/tap
brew install hashicorp/tap/terraform
terraform -version

他 OS は Install Terraform を参照してください。プロバイダは後述の init 時に自動取得されます。

API キーを発行して環境変数で渡す

TiDB Cloud コンソールで API キーを作成します。

Organization Settings > API Keys > By Project > Create Project API Key で作成します。

Craete Project API Key

環境変数としてシェルに渡します。

export TIDBCLOUD_PUBLIC_KEY="xxxxxxxx"
export TIDBCLOUD_PRIVATE_KEY="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

CI ではリポジトリシークレットとして登録し、ジョブ環境変数で同名に展開してください。

Project ID と Cluster ID を控える

  • Project ID
    TiDB Cloud コンソールの対象プロジェクトの URL で確認できます。以降の変数 tidbcloud_project_id に指定します。
  • Cluster ID
    既存クラスタを取り込む場合に使います。コンソールの対象クラスタの URL で確認できます。import 時にリソースアドレスと並べて指定します。

Project ID と Cluster ID

最小構成のファイルを用意する

Starter を対象に、後から import できる最小構成を作ります。作業用ディレクトリに以下の 4 ファイルを配置します。

versions.tf

terraform {
  required_version = ">= 1.0.0"
  required_providers {
    tidbcloud = {
      source  = "tidbcloud/tidbcloud"
      version = "~> 0.4.0"
    }
  }
}

providers.tf

provider "tidbcloud" {
  # 環境変数 TIDBCLOUD_PUBLIC_KEY と TIDBCLOUD_PRIVATE_KEY を自動検出
  sync = true  # クラスタ関連の操作を同期で待機
}

variables.tf

variable "tidbcloud_project_id" {
  description = "TiDB Cloud project id"
  type        = string
}

variable "cluster_region" {
  description = "Starter のリージョン名 正規形を指定 例: regions/aws-eu-central-1 や regions/aws-ap-northeast-1"
  type        = string
}

variable "display_name" {
  description = "クラスタの表示名"
  type        = string
  default     = "my-starter-db"
}

main.tf

Starter クラスタの宣言です。リージョンは単なる文字列ではなく、provider と name を持つブロックで指定します。

resource "tidbcloud_serverless_cluster" "starter" {
  project_id   = var.tidbcloud_project_id
  display_name = var.display_name

  region = {
    provider = "AWS"
    name     = var.cluster_region
  }

  lifecycle {
    prevent_destroy = true
    ignore_changes  = [display_name]
  }
}

仕様の詳細は tidbcloud_serverless_cluster リソースを使用する を参照してください。

初期化して動作を確認する

変数を環境変数で渡し、init と plan を実行します。

export TF_VAR_tidbcloud_project_id="xxxxxxxxxxxxxxxxxxx"
export TF_VAR_cluster_region="regions/aws-eu-central-1"  # 正規形を指定

terraform init -reconfigure # -reconfigure はバックエンドやプロバイダ設定を強制的に再読み込みします。既存の作業ディレクトリでも安全に繰り返し実行できます。
terraform validate
terraform plan

plan が通れば準備完了です。リージョン不一致時はエラーになります コンソールの候補に合わせて TF_VAR_cluster_region を修正してください。

既存クラスタを import する

すでにコンソールで作成済みの Starter クラスタを、破壊せずに Terraform の状態管理に取り込みます。実体に合わせた宣言を用意し、terraform import で state に結び付けたあと、plan -refresh-only で整合を確認します。

import は、リソースを state に追加する操作です。HCL(※) 側の宣言と実体が食い違っていると、後続の plan で差分が出ます。事前に前章の variables.tfmain.tf を、実体の Project と Region に合わせてください。

import を実行する

HCL に tidbcloud_serverless_cluster が宣言されている前提で実行します。単一リソースで管理している例です。

# import 専用の環境変数として cluster_id を用意
export TIDB_CLUSTER_ID="xxxxxxxxxxxxxxxxxxxx"

# まだ state に無ければ取り込む (単一リソース管理)
terraform state list | grep -q '^tidbcloud_serverless_cluster\.starter$' || \
  terraform import tidbcloud_serverless_cluster.starter "$TIDB_CLUSTER_ID"

モジュール配下で管理している場合は、フルアドレスで指定します。

# 例: modules/tidb 内に定義している場合
terraform state list | grep -q '^module\.tidb\.tidbcloud_serverless_cluster\.starter$' || \
  terraform import module.tidb.tidbcloud_serverless_cluster.starter "$TIDB_CLUSTER_ID"

取り込み直後の整合を確認する

import 後は 実体の読み取りのみを行い、差分がないことを確認します。

terraform plan -refresh-only

差分がなければ整合しています。

tidbcloud_serverless_cluster.starter: Refreshing state...

No changes. Your infrastructure still matches the configuration.

Terraform has checked that the real remote objects still match the result of your most recent changes, and found no
differences.

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if
you run "terraform apply" now.

まとめ

本記事では、Starter クラスタを 壊さずに Terraform 管理へ移す手順を、最小構成でまとめました。誤った置換計画を避けるため、region.name は常に regions/aws-<region-id> の正規形に合わせることを意識してください。

この状態まで整えば、以降は CI に refresh-only を組み込みつつ、段階的に管理範囲を広げられます。次の一歩として、接続ユーザーを tidbcloud_sql_user でコード化する、接続情報をパラメータストアに出力する、などの実装を追加していくと運用が安定します。

この記事をシェアする

facebookのロゴhatenaのロゴtwitterのロゴ

© Classmethod, Inc. All rights reserved.