- 前提条件
- GitLab CI/CDを使ってバックエンドとしてTerraformの状態を初期化します。
- ローカルマシンから状態にアクセス
- GitLabが管理するTerraformの状態にマイグレーションします。
- GitLabバックエンドをリモートデータソースとして使う
- Terraform ステートファイルの管理
- 関連するトピック
GitLab が管理する Terraform の状態
Terraformはステートファイルを使ってインフラ設定の詳細を保存します。Terraformリモートバックエンドでは、ステートファイルをリモートと共有のストアに保存できます。
GitLabはTerraform HTTPバックエンドを提供し、最小限の設定で安全にステートファイルを保存できます。
GitLabでは以下のことができます:
- Terraformのステートファイルをバージョン管理します。
- 転送中と静止時の両方で状態ファイルを暗号化します。
- 状態のロックとロック解除
-
terraform plan
およびterraform apply
コマンドをリモートで実行。
前提条件
セルフマネージドGitLabの場合、TerraformのステートファイルにGitLabを使用する前:
- 管理者がTerraformのステートストレージを設定する必要があります。
- プロジェクトのインフラメニューを有効にする必要があります。Settings > General でVisibility, project features, permissions を展開し、Infrastructureで toggle をオンにします。
GitLab CI/CDを使ってバックエンドとしてTerraformの状態を初期化します。
terraform init
コマンドを実行した後、GitLab CI/CD を使ってterraform
コマンドを実行することができます。
前提条件:
-
terraform apply
を使用して状態をロック、アンロック、書き込みするには、少なくともメンテナーのロールが必要です。 -
terraform plan -lock=false
を使用して状態を読み取るには、少なくとも開発者ロールを持っている必要があります。
public: false
) に設定して、公開パイプラインを 無効にすることを強くお勧めします。この設定によって、アーティファクトは GitLab 管理者とレポーターロール以上のプロジェクトメンバーだけがアクセスできるようになります。GitLab CI/CDをバックエンドとして設定するには:
-
Terraformプロジェクトの
backend.tf
のような.tf
ファイルで、HTTPバックエンドを定義します:terraform { backend "http" { } }
- プロジェクトリポジトリのルートディレクトリに、
.gitlab-ci.yml
ファイルを作成します。Terraform.gitlab-ci.yml
テンプレートを使って入力します。 - プロジェクトを GitLab にプッシュします。このアクションがパイプラインのトリガーとなり、
gitlab-terraform init
、gitlab-terraform validate
、gitlab-terraform plan
コマンドが実行されます。 -
gitlab-terraform apply
コマンドを実行する前のパイプラインから手動deploy
ジョブをトリガーして、定義されたインフラストラクチャをプロビジョニングします。
上記のterraform
コマンドの出力は、ジョブログで見ることができるはずです。
gitlab-terraform
CLI はterraform
CLI のラッパーです。詳細はGitLab Terraformヘルパーを参照するか、gitlab-terraform
のソースコードをご覧ください。
terraform
コマンドを明示的に呼び出したい場合は、テンプレートをオーバーライドして、代わりに実現できることのリファレンスとして使うことができます。
Terraform環境変数のカスタマイズ
Terraform.gitlab-ci.yml
テンプレートを使用すると、CI/CD ジョブを定義する際にTerraform HTTP 設定変数を使用できます。
terraform init
をカスタマイズして Terraform の設定を上書きするには、terraform init -backend-config=...
のアプローチの代わりに環境変数を使います。-backend-config
を使用する場合、設定は次のようになります:
-
terraform plan
コマンドの出力にキャッシュされます。 - 通常は
terraform apply
コマンドに渡されます。
この設定は、CIジョブでTerraformのステートファイルをロックできないなどの問題につながる可能性があります。
ローカルマシンから状態にアクセス
ローカルマシンからGitLabが管理するTerraformの状態にアクセスすることができます。
- Terraformの状態がCI/CD用に初期化されていることを確認してください。
-
Terraform
init
コマンドをコピーします:- 左のサイドバーで「検索」または「移動」を選択してあなたのプロジェクトを検索します。
- オペレーション > Terraformの状態を選択します。
- 使用したい環境の横で、Actions({ellipsis_v})を選択し、Copy Terraform init commandを選択します。
- ターミナルを開き、ローカルマシンでこのコマンドを実行します。
GitLabが管理するTerraformの状態にマイグレーションします。
Terraformはバックエンドが変更されたり再設定されたときに状態をコピーすることをサポートしています。別のバックエンドからGitLabが管理するTerraformの状態にマイグレーションするには、以下のアクションを使います。
GitLabが管理するTerraformの状態へのマイグレーションに必要なコマンドを実行するには、ローカルターミナルを使用する必要があります。
以下の例は、ステート名を変更する方法を示しています。異なるステートストレージバックエンドからGitLab管理下のTerraformステートにマイグレーションする場合も同じワークフローが必要です。
初期バックエンドのセットアップ
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"
terraform 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.
バックエンドの変更
terraform init
が.terraform/
ディレクトリを作成し、古い状態の場所を知っているので、新しい場所を教えることができます:
TF_ADDRESS="https://gitlab.com/api/v4/projects/${PROJECT_ID}/terraform/state/new-state-name"
terraform 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
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.
yes
と入力すると、古い場所から新しい場所に状態がコピーされます。そして、GitLab CI/CDでの実行に戻ることができます。
GitLabバックエンドをリモートデータソースとして使う
GitLabが管理するTerraformのステートバックエンドをTerraformのデータソースとして使うことができます。
-
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" }
-
前のステップの値を上書きするには、
example.auto.tfvars
という名前のファイルを作成します。このファイルはプロジェクトのリポジトリにバージョン管理されていないはずです。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>"
-
.tf
、Terraformの入力変数を使ってデータソースを定義します: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>
。 -
username: データソースで認証するためのユーザ名。認証にパーソナルアクセストークンを使っている場合、この値はGitLabのユーザー名になります。GitLab CI/CDを使用している場合、この値は
'gitlab-ci-token'
。 -
password: データソースで認証するためのパスワード。認証にパーソナルアクセストークンを使用している場合、この値はトークンの値になります(トークンはAPIスコープを持っている必要があります)。GitLab CI/CDを使用している場合、この値は
${CI_JOB_TOKEN}
CI/CD変数の内容です。
-
アドレス:データソースとして使いたいリモート状態のバックエンドのURL。例えば、
データソースからの出力はdata.terraform_remote_state.example.outputs.<OUTPUT-NAME>
を使って Terraform リソースで参照できるようになりました。
ターゲットプロジェクトで Terraform の状態を読み込むには、少なくとも Developer ロールが必要です。
Terraform ステートファイルの管理
GitLab 13.8 で導入されました。
Terraformの状態ファイルを見るには:
- 左のサイドバーで「検索」または「移動」を選択してあなたのプロジェクトを検索します。
- オペレーション > Terraformの状態を選択します。
このUIの改善を追跡するエピックが存在します。
個々のTerraform状態のバージョンを管理
GitLab 13.4 で導入されました。
GitLab REST APIを使って、個々のステートのバージョンを管理することができます。
少なくとも開発者ロールを持っていれば、シリアル番号を使ってステートバージョンを取得することができます:
curl --header "Private-Token: <your_access_token>" "https://gitlab.example.com/api/v4/projects/<your_project_id>/terraform/state/<your_state_name>/versions/<version-serial>"
少なくともメンテナーのロールを持っていれば、シリアル番号を使ってステートバージョンを削除できます:
curl --header "Private-Token: <your_access_token>" --request DELETE "https://gitlab.example.com/api/v4/projects/<your_project_id>/terraform/state/<your_state_name>/versions/<version-serial>"
状態ファイルの削除
少なくともメンテナーのロールを持っていれば、状態ファイルを削除することができます。
- 左サイドバーで、Operate > Terraform statesを選択します。
- アクション]列で[アクション({ellipsis_v})]を選択し、[状態のファイルとバージョンを削除]を選択します。
APIを使用して状態ファイルを削除します。
状態ファイルを削除するには、REST API にリクエストします。例えば
curl --header "Private-Token: <your_access_token>" --request DELETE "https://gitlab.example.com/api/v4/projects/<your_project_id>/terraform/state/<your_state_name>"
GraphQL APIを使用することもできます。