GitLabは5月16日にバージョン17.0をリリース予定です。この新バージョンは、複数のウィンドウを通じて段階的にロールアウトされます。詳細なスケジュールはこちらで確認できます。このロールアウトのため、本日予定されていた更新により、先週まで使用可能だった$CI_JOB_JWT_V2
が利用不可能となり、結果としてパイプラインが失敗しました。
$CI_JOB_JWT_V2
は、GitLab CI/CD環境で使用される環境変数の一つで、ジョブ実行中にGitLabから提供されるJWTを含んでいます。これまではGitLabとAWS間でIDフェデレーションを設定し、OpenID Connect(OIDC)を利用して一時的な認証情報を取得するのに$CI_JOB_JWT_V2
を使用していましたが、この変数の値が取得できなくなり、AWSのSTSコマンドに必要な--web-identity-token
も含まれなくなったために問題が発生しました。
OpenID Connect(OIDC)を利用して一時的な認証情報を取得する方法については、こちらの記事で詳しく解説されています。今回の検証では、AWS側でIDプロバイダの追加およびロールと信頼設定が完了していることが前提です。
今回の検証の詳細、既存のコード、問題発生時のエラー内容、トラブルシューティングと解決策のサンプルを以下に示します。
これまでの設定を用いて、一時的なクレデンシャルを取得することができていました
.assume_role: &assume_role
- STS=$(aws sts assume-role-with-web-identity --role-arn ${ROLE_ARN} --role-session-name "GitLabRunner-${CI_PROJECT_ID}-${CI_PIPELINE_ID}" --web-identity-token $CI_JOB_JWT_V2 --duration-seconds 3600)
- AWS_ACCESS_KEY_ID=$(echo "$STS" | jq -r ".Credentials.AccessKeyId")
- AWS_SECRET_ACCESS_KEY=$(echo "$STS" | jq -r ".Credentials.SecretAccessKey")
- AWS_SESSION_TOKEN=$(echo "$STS" | jq -r ".Credentials.SessionToken")
- export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
- export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
- export AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN
- export AWS_DEFAULT_REGION="ap-northeast-1"
- aws configure list
- AWS_ACCOUNT_ID=$(aws sts get-caller-identity | jq -r ".Account" )
resources_deploy:
stage: Mystage
variables:
<<: [*my_environments]
before_script:
- *common_script
script:
- *assume_role
- *common_resources_deploy
5月6日のロールアウト後、以下のエラーが原因でパイプラインが失敗するようになりました。
エラー内容に記載したとおり、aws sts assume-role-with-web-identity コマンドに必要な –web-identity-token の値が取得できていないことがわかります。
GitLabのドキュメントを確認したところ、既に関連するアラートが表示されていました。
https://docs.gitlab.com/ee/ci/yaml/index.html#id_tokensに記載されている指示に従って、パイプラインを変更しました。
.assume_role: &assume_role
- STS=$(aws sts assume-role-with-web-identity --role-arn ${ROLE_ARN} --role-session-name "GitLabRunner-${CI_PROJECT_ID}-${CI_PIPELINE_ID}" --web-identity-token ${GITLAB_OIDC_TOKEN} --duration-seconds 3600)
- AWS_ACCESS_KEY_ID=$(echo "$STS" | jq -r ".Credentials.AccessKeyId")
- AWS_SECRET_ACCESS_KEY=$(echo "$STS" | jq -r ".Credentials.SecretAccessKey")
- AWS_SESSION_TOKEN=$(echo "$STS" | jq -r ".Credentials.SessionToken")
- export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
- export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
- export AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN
- export AWS_DEFAULT_REGION="ap-northeast-1"
- aws configure list
- AWS_ACCOUNT_ID=$(aws sts get-caller-identity | jq -r ".Account" )
resources_deploy:
stage: Mystage
variables:
<<: [*my_environments]
id_tokens:
GITLAB_OIDC_TOKEN:
aud: https://gitlab.com
before_script:
- *common_script
script:
- *assume_role
- *common_resources_deploy
これで無事にパイプラインが成功しました。
まとめ
GitLabに限らず、定期的なアップデートをこまめに行うことで、今回のような問題を事前に防げたかもしれません。また、エラー発生後はエラーの内容をしっかりと確認することが迅速な解決につながります。