TerraformとGitLabのインテグレーションに関するトラブルシューティング
TerraformとGitLabのインテグレーションを使用している場合、トラブルシューティングが必要なイシューが発生することがあります。
gitlab_group_share_groupリソースが、サブグループの状態が更新されたときに検出されない
GitLab Terraformプロバイダーは、「権限を持つユーザーがAPIからshare_with_groups取得できない」というイシューが原因で、既存の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は、両方のサブグループへの継承されたownerアクセスを持つparent-groupのメンバーです。
Terraformのステートファイルが更新されると、プロバイダーによって発行されたAPIクエリGET /groups/:subgroup-A_idは、shared_with_groups配列内のsubgroup-Bの詳細を返しません。これによりエラーが発生します。
この回避策として、次のいずれかの条件を適用してください:
terraform-userがすべてのサブグループリソースを作成します。subgroup-Bのterraform-userユーザーにメンテナーまたはオーナーロールを付与します。terraform-userはsubgroup-Bへのアクセスを継承し、subgroup-Bには少なくとも1つのプロジェクトが含まれています。
Terraformステートファイルのトラブルシューティング
前のジョブのプランでterraform applyのCIジョブでTerraformステートファイルをロックできません
terraform initに-backend-config=を渡すと、Terraformはこれらの値をプランキャッシュファイル内に保持します。これには、passwordの値が含まれます。
その結果、プランを作成し、後で別のCIジョブで同じプランを使用するには、-backend-config=password=$CI_JOB_TOKENを使用すると、エラーError: Error acquiring the state lockが発生する可能性があります。これは、$CI_JOB_TOKENの値が現在のジョブの期間中のみ有効であるために発生します。
回避策として、CIジョブでhttpバックエンド設定変数を使用します。これは、GitLab CIを使用した開始方法の手順に従うと、バックグラウンドで発生するものです。
エラー: "address": required field is not set
デフォルトでは、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_PASSWORDCI/CD変数を設定している場合は、次のいずれかを確認してください:TF_PASSWORDと同じ値を設定します- CI/CDジョブで明示的に使用しない場合は、
TF_HTTP_PASSWORD変数を削除します。
デベロッパーロールが破壊的なコマンドへのアクセスを有効にする
デベロッパーロールを持つユーザーが破壊的なコマンドを実行できるようにするには、回避策が必要です:
apiスコープでプロジェクトアクセストークンを作成します。TF_USERNAMEとTF_PASSWORDをCI/CD変数に追加します:TF_USERNAMEの値をプロジェクトアクセストークンのユーザー名に設定します。TF_PASSWORDの値をプロジェクトアクセストークンのパスワードに設定します。- オプション。変数を保護ブランチまたは保護タグで実行されるパイプラインでのみ利用可能にするには、変数を保護してください。
ステートファイル名にピリオドが含まれている場合、ステートファイルが見つかりません
GitLab 15.6以前は、ステートファイル名にピリオドが含まれており、Terraformがステートファイルのロックを試みると、404エラーを返していました。
-lock=falseをTerraformコマンドに追加することで、この制限を回避できました。GitLabバックエンドはリクエストを受け入れましたが、内部的にはピリオドとそれに続くすべての文字をステートファイル名から削除しました。たとえば、foo.barという名前のステートファイルは、fooとして保存されます。ただし、この回避策は推奨されておらず、ステートファイル名の衝突を引き起こす可能性さえありました。
GitLab 15.7以降では、ピリオドを含むステートファイル名がサポートされています。-lock=false回避策を使用し、GitLab 15.7以降にアップグレードすると、ジョブが失敗する可能性があります。この失敗は、GitLabバックエンドが完全なステートファイル名で新しいステートファイルを保存し、既存のステートファイル名と異なることが原因で発生します。
失敗するジョブを修正するには、ステートファイル名を変更して、ピリオドとそれに続く文字を除外します。
TF_HTTP_ADDRESS、TF_HTTP_LOCK_ADDRESS、およびTF_HTTP_UNLOCK_ADDRESSが設定されている場合は、そこにステートファイル名を必ず更新してください。
または、OpenTofuステートファイルを移行することもできます。
ステートファイルの保存エラー: HTTPエラー: 404
このエラーは、ステートファイル名にフォワードスラッシュ(/)文字が含まれている場合に発生する可能性があります。これを解決するには、ステートファイル名にフォワードスラッシュ(/)文字が含まれていないことを確認してください。