正式なドキュメントは英語版であり、この日本語訳はAI支援翻訳により作成された参考用のものです。日本語訳の一部の内容は人間によるレビューがまだ行われていないため、翻訳のタイミングにより英語版との間に差異が生じることがあります。最新かつ正確な情報については、英語版をご参照ください。

GitLab管理のTerraform/OpenTofuステート

  • プラン: Free、Premium、Ultimate
  • 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated

チーム全体でインフラストラクチャのステートファイルを管理するには、セキュリティと信頼性の両方が必要とされます。GitLab管理のOpenTofuステートにより、状態管理の一般的な課題が解消されます。最小限の設定で、OpenTofuの状態をGitLabプロジェクトの通常の拡張機能にすることができます。この統合により、インフラストラクチャの定義、コード、状態のすべてを1つの安全な場所に保持できます。

GitLab管理のOpenTofuステートを使用すると、次のことが可能になります:

  • 保存時に自動で暗号化してステートファイルを安全に保存する
  • 組み込みのバージョニングで変更を追跡し、誰がいつ何を変更したかを特定する
  • 個別の認証システムを作成するのではなく、GitLab権限モデルを使用してアクセスを制御する
  • ステートファイルを競合または破損させることなくチーム間で共同作業を行う
  • 既存のGitLab CI/CDパイプラインとシームレスに統合する
  • CI/CDジョブとローカル開発環境の両方から状態にリモートでアクセスする

Disaster recovery planning(ディザスターリカバリ計画)OpenTofuのステートファイルは、ディスク上およびオブジェクトストレージ内で、db_key_baseアプリケーション設定由来のキーを使用して、Lockbox Ruby gemで暗号化されます。ステートファイルを復号化するには、GitLabが利用可能である必要があります。オフラインの場合、GitLabが必要とするインフラストラクチャ(仮想マシン、Kubernetesクラスター、ネットワークコンポーネントなど)のデプロイにGitLabを使用しても、ステートファイルに簡単にアクセスしたり、復号化したりすることはできません。さらに、GitLabのブートストラップに必要なOpenTofuモジュールまたはその他の依存関係をGitLabが提供している場合、これらにアクセスできなくなります。この問題を回避するには、これらの依存関係をホストまたはバックアップするために別途調整を行うか、障害点を共有しない別のGitLabインスタンスを使用することを検討してください。

前提要件

GitLab Self-Managedの場合、OpenTofuのステートファイルにGitLabを使用する前に、次のことを行う必要があります:

  • 管理者がTerraform/OpenTofuステートストレージを設定します
  • プロジェクトのインフラストラクチャメニューをオンにします:
    1. 設定 > 一般に移動します。
    2. 可視性、プロジェクトの機能、権限を展開します。
    3. インフラストラクチャの切替をオンにします。

GitLab CI/CDを使用してOpenTofuステートをバックエンドとして初期化する

前提要件:

  • tofu applyを使用して、状態のロック、ロック解除、および書き込みを行うには、メンテナー以上のロールが必要です。
  • tofu plan -lock=falseを使用して状態を読み取るには、デベロッパー以上のロールが必要です。

他のジョブアーティファクトと同様に、OpenTofuプランのデータは、リポジトリに対するゲストロールを持つすべてのユーザーが表示できます。OpenTofuおよびGitLabは、いずれもデフォルトではプランファイルを暗号化しません。OpenTofuのplan.jsonファイルまたはplan.cacheファイルに、パスワード、アクセストークン、証明書などの機密データが含まれている場合は、プランの出力を暗号化するか、プロジェクトの表示レベル設定を変更する必要があります。また、パブリックパイプラインdisable(無効にし)、アーティファクトのアクセスフラグを「デベロッパー」access: 'developer')に設定する必要があります。この設定により、アーティファクトは、GitLab管理者と、デベロッパー以上のロールを持つプロジェクトメンバーのみがアクセスできるようになります。

GitLab CI/CDをバックエンドとして設定するには:

  1. OpenTofuプロジェクトで、backend.tfなどの.tfファイルにHTTPバックエンドを定義します:

    terraform {
      backend "http" {
      }
    }
  2. プロジェクトリポジトリのルートディレクトリに.gitlab-ci.ymlファイルを作成します。OpenTofu CI/CDコンポーネントを使用して、.gitlab-ci.ymlファイルを形成します。

  3. プロジェクトをGitLabにプッシュします。このアクションにより、gitlab-tofu initgitlab-tofu validate、およびgitlab-tofu planコマンドを実行するパイプラインがトリガーされます。

  4. 前のパイプラインから手動のdeployジョブをトリガーします。このアクションによりgitlab-tofu applyコマンドが実行され、定義されたインフラストラクチャがプロビジョニングされます。

上記のコマンドからの出力は、ジョブログで表示できるはずです。

gitlab-tofu CLIは、tofu CLIのラッパーです。

OpenTofuの環境変数をカスタマイズする

CI/CDジョブの定義時に、OpenTofu HTTP設定変数を使用できます。

initをカスタマイズし、OpenTofuの設定をオーバーライドするには、init -backend-config=...アプローチではなく、環境変数を使用します。-backend-configを使用すると、設定は次のようになります:

  • planコマンドの出力にキャッシュされます。
  • 通常はapplyコマンドに転送されます。

この設定により、CIジョブでステートファイルをロックできないなどの問題が発生する可能性があります。

プランファイル名をカスタマイズ

デフォルトでは、gitlab-tofu plan(またはgitlab-terraform plan)コマンドは、常にプランの出力をplan.cacheという名前のファイルに書き込みます。

ファイル名を変更するには、CI/CDパイプラインの設定でTF_PLAN_CACHE環境変数を設定します。たとえば、ファイル名をmy-plan.tfplanに設定するには、次のようにします:

variables:
  TF_PLAN_CACHE: "my-plan.tfplan"

-out=<filename>オプションを渡して出力ファイル名を設定しないでください。GitLabコマンドはこのオプションをオーバーライドします。

ローカルマシンから状態にアクセスする

ローカルマシンからGitLab管理のOpenTofuステートにアクセスできます。

GitLabのクラスター化されたデプロイでは、ローカルストレージを使用しないでください。ノード間で状態が分割され、後続のOpenTofuの実行に矛盾が生じる可能性があります。代わりに、リモートストレージリソースを使用してください。

  1. OpenTofuの状態がCI/CD用に初期化されていることを確認します。

  2. 自動入力されたOpenTofu initコマンドをコピーします:

    1. 左側のサイドバーで、検索または移動先を選択して、プロジェクトを見つけます。
    2. 操作 > Terraformステートを選択します。
    3. 使用する環境の横にあるアクション ellipsis_v )を選択し、Terraform initコマンドをコピーを選択します。
  3. ターミナルを開き、ローカルマシンでこのコマンドを実行します。

GitLab管理のOpenTofuステートに移行する

OpenTofuは、バックエンドの変更時または再設定時に状態をコピーする操作をサポートしています。これらのアクションを使用して、別のバックエンドからGitLab管理のOpenTofuステートに移行します。

GitLab管理のOpenTofuステートへの移行に必要なコマンドを実行するには、ローカルターミナルを使用する必要があります。

以下の例は、状態名の変更方法を示しています。別の状態のストレージバックエンドからGitLab管理のOpenTofuステートに移行するには、同じワークフローが必要です。

これらのコマンドはローカルマシンで実行する必要があります。

初期バックエンドを設定する

glabでバックエンドを初期化するには、次のコマンドを実行します:

glab opentofu init <old_state_name>

OpenTofu CLIを使用してバックエンドを初期化するには、次のコマンドを実行します:

PROJECT_ID="<gitlab-project-id>"
TF_USERNAME="<gitlab-username>"
TF_PASSWORD="<gitlab-personal-access-token>"
TF_ADDRESS="https://gitlab.com/api/v4/projects/${PROJECT_ID}/terraform/state/old-state-name"

tofu init \
  -backend-config=address=${TF_ADDRESS} \
  -backend-config=lock_address=${TF_ADDRESS}/lock \
  -backend-config=unlock_address=${TF_ADDRESS}/lock \
  -backend-config=username=${TF_USERNAME} \
  -backend-config=password=${TF_PASSWORD} \
  -backend-config=lock_method=POST \
  -backend-config=unlock_method=DELETE \
  -backend-config=retry_wait_min=5

バックエンドが正常に初期化されると、次のレスポンスが表示されます:

Initializing the backend...

Successfully configured the backend "http"! Terraform will automatically
use this backend unless the backend configuration changes.

Initializing provider plugins...

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
re-run this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

バックエンドを変更する

tofu initが古い状態の場所を認識する.terraform/ディレクトリを作成したので、新しい場所を教えることができます:

glab opentofu init <new-state-name> -- -migrate-state
TF_ADDRESS="https://gitlab.com/api/v4/projects/${PROJECT_ID}/terraform/state/<new-state-name>"

tofu init \
  -migrate-state \
  -backend-config=address=${TF_ADDRESS} \
  -backend-config=lock_address=${TF_ADDRESS}/lock \
  -backend-config=unlock_address=${TF_ADDRESS}/lock \
  -backend-config=username=${TF_USERNAME} \
  -backend-config=password=${TF_PASSWORD} \
  -backend-config=lock_method=POST \
  -backend-config=unlock_method=DELETE \
  -backend-config=retry_wait_min=5

バックエンドが正常に初期化されると、次のレスポンスが表示されます。yesと入力すると、状態が古い場所から新しい場所にコピーされます。その後、GitLab CI/CDでの実行に戻ることができます:

Initializing the backend...
Backend configuration changed!

Terraform has detected that the configuration specified for the backend
has changed. Terraform will now check for existing state in the backends.


Acquiring state lock. This may take a few moments...
Do you want to copy existing state to the new backend?
  Pre-existing state was found while migrating the previous "http" backend to the
  newly configured "http" backend. No existing state was found in the newly
  configured "http" backend. Do you want to copy this state to the new "http"
  backend? Enter "yes" to copy and "no" to start with an empty state.

  Enter a value: yes


Successfully configured the backend "http"! Terraform will automatically
use this backend unless the backend configuration changes.

Initializing provider plugins...

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

GitLabバックエンドをリモートデータソースとして使用する

GitLab管理のOpenTofuステートバックエンドをOpenTofuデータソースとして使用できます。

  1. main.tfまたはその他の関連ファイルで、これらの変数を宣言します。値は空のままにします。

    variable "example_remote_state_address" {
      type = string
      description = "Gitlab remote state file address"
    }
    
    variable "example_username" {
      type = string
      description = "Gitlab username to query remote state"
    }
    
    variable "example_access_token" {
      type = string
      description = "GitLab access token to query remote state"
    }
  2. 前の手順の値をオーバーライドするには、example.auto.tfvarsという名前のファイルを作成します。このファイルは、プロジェクトリポジトリでnot(バージョニングしないでください)。

    example_remote_state_address = "https://gitlab.com/api/v4/projects/<TARGET-PROJECT-ID>/terraform/state/<TARGET-STATE-NAME>"
    example_username = "<GitLab username>"
    example_access_token = "<GitLab personal access token>"
  3. .tfファイルで、OpenTofu入力変数を使用してデータソースを定義します:

    data "terraform_remote_state" "example" {
      backend = "http"
    
      config = {
        address = var.example_remote_state_address
        username = var.example_username
        password = var.example_access_token
      }
    }
    • アドレス: データソースとして使用するリモート状態バックエンドのURLです。たとえば、https://gitlab.com/api/v4/projects/<TARGET-PROJECT-ID>/terraform/state/<TARGET-STATE-NAME>などです。
    • ユーザー名: データソースで認証するためのユーザー名です。パーソナルアクセストークンを認証に使用している場合、この値はGitLabのユーザー名になります。GitLab CI/CDを使用している場合、この値は'gitlab-ci-token'になります。
    • パスワード: データソースで認証を行うためのパスワードです。パーソナルアクセストークンを認証に使用している場合、この値はトークン値になります(トークンにはAPIスコープが必要です)。GitLab CI/CDを使用している場合、この値は${CI_JOB_TOKEN} CI/CD変数の内容になります。

データソースからの出力は、data.terraform_remote_state.example.outputs.<OUTPUT-NAME>を使用してTerraformリソースで参照できるようになりました。

ターゲットプロジェクトでOpenTofuステートを読み取るには、デベロッパー以上のロールが必要です。

OpenTofuのステートファイルを管理する

OpenTofuのステートファイルを表示するには:

  1. 左側のサイドバーで、検索または移動先を選択して、プロジェクトを見つけます。
  2. 操作 > Terraformステートを選択します。

このUIの改善を追跡するためのエピックが存在します

個々のOpenTofuステートバージョンを管理する

GitLab CLI(glab)またはAPIを使用して、個々のステートのバージョンを管理します。

前提要件:

  • シリアル番号を使用してステートのバージョンを取得するには、少なくともデベロッパーロールが必要です。
  • シリアル番号を使用してステートのバージョンを削除するには、少なくともメンテナーロールが必要です。

シリアル番号を使用してステートのバージョンを取得するには:

glab opentofu state download <your_state_name> <version_serial_number>
curl --header "Private-Token: <your_access_token>" \
     --url "https://gitlab.example.com/api/v4/projects/<your_project_id>/terraform/state/<your_state_name>/versions/<version_serial_number>"

シリアル番号を使用してステートのバージョンを削除するには、次のようにします:

glab opentofu state delete <your_state_name> <version_serial_number>
curl --request DELETE --header "Private-Token: <your_access_token>" \
     --url "https://gitlab.example.com/api/v4/projects/<your_project_id>/terraform/state/<your_state_name>/versions/<version_serial_number>"

ステートファイルを削除する

前提要件:

  • ステートファイルを削除するには、少なくともメンテナーロールが必要です。
glab opentofu state delete <your_state_name>
curl --request DELETE --header "Private-Token: <your_access_token>" \
     --url "https://gitlab.example.com/api/v4/projects/<your_project_id>/terraform/state/<your_state_name>"

CI/CDジョブトークンと基本認証も使用できます:

curl --request DELETE --user "gitlab-ci-token:$CI_JOB_TOKEN" \
     --url "https://gitlab.example.com/api/v4/projects/<your_project_id>/terraform/state/<your_state_name>"

GraphQL APIも使用できます。

UIを使用してステートファイルを削除するには、次のようにします:

  1. 左側のサイドバーで、操作 > Terraformステートを選択します。
  2. アクション列で、アクション ellipsis_v )> Remove state file and versions(ステートファイルとバージョンを削除)を選択します。

ステートのロックとロック解除

前提要件:

  • ステートファイルをロックするには、少なくともメンテナーロールが必要です。
# Lock a state file
glab opentofu state lock <your_state_name>

# Unlock a state file
glab opentofu state unlock <your_state_name>
# Lock a state file
curl --request POST --header "Private-Token: <your_access_token>" \
     --url "https://gitlab.example.com/api/v4/projects/<your_project_id>/terraform/state/<your_state_name>/lock"

# Unlock a state file
curl --request DELETE --header "Private-Token: <your_access_token>" \
     --url "https://gitlab.example.com/api/v4/projects/<your_project_id>/terraform/state/<your_state_name>/lock"

UIを使用してステートファイルをロックまたはロック解除するには、次のようにします:

  1. 左側のサイドバーで、操作 > Terraformステートを選択します。
  2. アクション列で、アクション ellipsis_v )> ロックを選択してロックするか、アクション ellipsis_v )> ロック解除を選択します。

ステートファイルをダウンロード

前提要件:

  • ステートファイルをダウンロードするには、少なくともデベロッパーロールが必要です。
# Download the latest state
glab opentofu state download <your_state_name>

# Download a specific version (serial) of a state
glab opentofu state download <your_state_name> <your_serial>
# Download the latest state
curl --header "Private-Token: <your_access_token>" \
     --url "https://gitlab.example.com/api/v4/projects/<your_project_id>/terraform/state/<your_state_name>"

# Download a specific version (serial) of a state
curl --header "Private-Token: <your_access_token>" \
     --url "https://gitlab.example.com/api/v4/projects/<your_project_id>/terraform/state/<your_state_name>/versions/<version_serial_number>"

UIを使用して最新のステートファイルをダウンロードするには、次のようにします:

  1. 左側のサイドバーで、操作 > Terraformステートを選択します。
  2. アクション列で、アクション ellipsis_v )> JSONをダウンロードを選択します。

UIを使用してステートの特定のバージョンをダウンロードする方法はありません。