TerraformとGitLabのインテグレーションに関するトラブルシューティング
TerraformとGitLabのインテグレーションを使っていると、トラブルシューティングが必要なイシューに遭遇することがあります。
gitlab_group_share_group
サブグループの状態が更新されたときにリソースが検出されない
GitLab Terraformプロバイダは、“User with permissions cannot retrieveshare_with_groups
from the API” というイシューのために、既存のgitlab_group_share_group
リソースの検出に失敗することがあります。この結果、Terraformが既存のリソースを再作成しようとするため、terraform apply
を実行するとエラーになります。
例えば、以下のようなグループ/サブグループの設定を考えてみましょう:
parent-group
├── subgroup-A
└── subgroup-B
どこに:
- ユーザー
user-1
はparent-group
、subgroup-A
、subgroup-B
を作成します。 -
subgroup-A
はsubgroup-B
と共有されます。 - ユーザー
terraform-user
はparent-group
のメンバーで、両方のサブグループへのアクセス権はowner
に継承されます。
Terraform の状態がリフレッシュされると、プロバイダが発行した API クエリGET /groups/:subgroup-A_id
はshared_with_groups
配列内のsubgroup-B
の詳細を返しません。これはエラーにつながります。
このイシューを回避するには、以下のいずれかの条件を適用してください:
-
terraform-user
がすべてのサブグループリソースを作成します。 -
subgroup-B
のterraform-user
ユーザーにメンテナーまたはオーナーのロールを付与します。 -
terraform-user
は、少なくとも1つのプロジェクトへのアクセスを継承subgroup-B
し、subgroup-B
プロジェクトを含んでいます。
ベーステンプレート使用時に無効なCI/CD構文エラー
Terraformテンプレートを使用する際にCI/CD構文エラーが発生することがあります:
- GitLab 14.2 以降では、
latest
テンプレートを使用します。 - GitLab 15.0以降では、どのバージョンのテンプレートでも使用できます。
使用例:
include:
# On 14.2 and later, when using either of the following:
- template: Terraform/Base.latest.gitlab-ci.yml
- template: Terraform.latest.gitlab-ci.yml
# On 15.0 and later, the following templates have also been updated:
- template: Terraform/Base.gitlab-ci.yml
- template: Terraform.gitlab-ci.yml
my-terraform-job:
extends: .apply
エラーの原因は3つあります:
- の場合、
.init
initステージとジョブがテンプレートから削除さ.init
れた.init
ためにエラーが発生.init
します。.init
構文エラーを解決するには、.NET Frameworkを拡張するジョブを安全に削除して.init
ください。 -
他のすべてのジョブの場合、失敗の原因は基本ジョブの名前が変更されたことです:すべてのジョブ名に
.terraform:
という接頭辞が追加されています。例えば、.apply
は.terraform:apply
になりました。このエラーを修正するには、基本ジョブ名を更新してください。例えばmy-terraform-job: - extends: .apply + extends: .terraform:apply
- GitLab 15.0 では、テンプレートは
only/except
の代わりにrules
の構文を使用します。.gitlab-ci.yml
ファイルの構文が両方を含んでいないことを確認してください。
古いバージョンのテンプレートを使う
メジャーリリースの際には、変更が加えられることがあります。変更に遭遇したり、古いバージョンのテンプレートを使用したい場合は、.gitlab-ci.yml
を更新して古いテンプレートを参照することができます。例えば
include:
remote: https://gitlab.com/gitlab-org/configure/template-archive/-/raw/main/14-10/Terraform.gitlab-ci.yml
template-archiveを見て、利用可能なテンプレートを確認してください。
Terraform状態のトラブルシューティング
terraform apply
の CI ジョブで、以前のジョブで作成されたプランを使用して Terraform の状態ファイルをロックできません。
-backend-config=
をterraform init
に渡すと、Terraform はこれらの値をプランキャッシュファイル内部に永続化します。これにはpassword
の値も含まれます。
その結果、プランを作成し、後で別の CI ジョブで同じプランを使用する場合、-backend-config=password=$CI_JOB_TOKEN
を使用すると、Error: Error acquiring the state lock
エラーが発生する可能性があります。これは、$CI_JOB_TOKEN
の値が現在のジョブの間だけ有効であるために起こります。
回避策として、CIジョブでhttpバックエンド設定変数を使います。これは、GitLab CIを使い始めるの説明に従っているときに裏で起こっていることです。
エラー:”address”: 必須フィールドが設定されていません。
デフォルトでは、TF_ADDRESS
に${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/${TF_STATE_NAME}
を設定しています。ジョブでTF_STATE_NAME
またはTF_ADDRESS
を設定していない場合、エラーメッセージError: "address": required field is not set
が表示されてジョブが失敗します。
これを解決するには、エラーを返したジョブでTF_ADDRESS
またはTF_STATE_NAME
のいずれかにアクセスできるようにしてください:
- ジョブのCI/CD環境スコープを設定してください。
- 前のステップで設定した環境スコープに合わせて、ジョブの環境を設定します。
状態の更新エラー:HTTPリモート状態のエンドポイントは認証が必要です
これを解決するには
- 使用するアクセストークンのスコープが
api
。 -
TF_HTTP_PASSWORD
CI/CD変数を設定した場合は、以下のいずれかを確認してください:- と同じ値を設定してください。
TF_PASSWORD
- CI/CD ジョブで明示的に使用しない場合は
TF_HTTP_PASSWORD
変数を削除してください。
- と同じ値を設定してください。
開発者ロールが破壊的コマンドにアクセスできるようにします。
Developerロールを持つユーザーに破壊的コマンドの実行を許可するには、回避策が必要です:
-
api
、プロジェクトアクセストークンを作成してください。 - CI/CD 変数に
TF_USERNAME
とTF_PASSWORD
を追加します:-
TF_USERNAME
の値をプロジェクトのアクセストークンのユーザー名に設定します。 -
TF_PASSWORD
の値をプロジェクトのアクセストークンのパスワードに設定します。 - オプション。保護されたブランチまたは保護されたタグで実行されるパイプラインでのみ使用できるように、変数を保護します。
-
状態名にピリオドが含まれる場合、状態が見つかりません。
GitLab 15.6以前では、ステート名にピリオドが含まれている場合にTerraformがステートをロックしようとすると404エラーを返していました。
Terraformコマンドに-lock=false
。GitLabバックエンドはリクエストを受け入れましたが、内部でピリオドとそれに続く文字をステート名から取り除きました。例えば、foo.bar
という名前のステートはfoo
という名前で保存されます。しかし、この回避策は推奨されておらず、ステート名の衝突を引き起こす可能性もあります。
GitLab 15.7以降では、ピリオドを含むステート名がサポートされています。-lock=false
の回避策を使い、GitLab 15.7 以降にアップグレードすると、ジョブが失敗する可能性があります。この失敗は、GitLabバックエンドが既存のステート名と異なる完全なステート名で新しいステートを保存することが原因です。
失敗するジョブを修正するには、ピリオドとそれに続く文字を除いたステート名に変更してください。例えば、Terraformテンプレートを使用する場合:
include:
- template: Terraform.gitlab-ci.yml
variables:
TF_STATE_NAME: foo
TF_HTTP_ADDRESS
、TF_HTTP_LOCK_ADDRESS
、TF_HTTP_UNLOCK_ADDRESS
が設定されている場合は、状態名を更新してください。
あるいは、Terraformの状態をマイグレーションすることもできます。