一時的な認証情報を取得するためのAWSでのOpenID Connectの設定

caution
CI_JOB_JWT_V2GitLab 15.9で非推奨となり、GitLab 16.5で削除される予定です。代わりにIDトークンを使用してください。

このチュートリアルでは、GitLab CI/CD ジョブに JSON web token(JWT) を使って、シークレットを保存することなく AWS から一時的な認証情報を取得する方法を紹介します。これを行うには、GitLabとAWS間のIDフェデレーションのためにOpenID Connect(OIDC) を設定する必要があります。OIDCを使用してGitLabをインテグレーションするための背景と要件については、クラウドサービスへの接続を参照してください。

このチュートリアルを完了するには

  1. ID プロバイダの追加
  2. ロールと信頼の設定
  3. 一時的なクレデンシャルの取得

ID プロバイダの追加

以下の手順に従って、AWSにIAM OIDCプロバイダとしてGitLabを作成します。

以下の情報を含めてください:

  • プロバイダの URLhttps://gitlab.comhttp://gitlab.example.com など、GitLab インスタンスのアドレス。
  • オーディエンスhttps://gitlab.comhttp://gitlab.example.com のような GitLab インスタンスのアドレス。
    • アドレスにはhttps:// を含める必要があります。
    • 末尾のスラッシュは含めないでください。

ロールと信頼の設定

ID プロバイダを作成したら、GitLab リソースへのアクセスを制限するための条件を持つWeb ID ロールを設定します。一時的な認証情報はAWS Security Token Serviceを使って取得するので、Actionsts:AssumeRoleWithWebIdentity に設定します。

特定のグループ、プロジェクト、ブランチ、タグに権限を制限するために、ロールのカスタム信頼ポリシーを作成することができます。サポートされているフィルタリングタイプの完全なリストについては、クラウドサービスへの接続を参照してください。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::AWS_ACCOUNT:oidc-provider/gitlab.example.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "gitlab.example.com:sub": "project_path:mygroup/myproject:ref_type:branch:ref:main"
        }
      }
    }
  ]
}

ロールを作成したら、AWSサービス(S3、EC2、シークレットマネージャー)への権限を定義するポリシーをアタッチします。

一時的な認証情報の取得

OIDCとロールを設定した後、GitLab CI/CDジョブはAWS Security Token Service(STS) から一時的なクレデンシャルを取得することができます。

assume role:
  id_tokens:
    GITLAB_OIDC_TOKEN:
      aud: https://gitlab.example.com
  script:
    - >
      export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s"
      $(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
      --query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]'
      --output text))
    - aws sts get-caller-identity

動作例

Terraform を使って AWS に OIDC をプロビジョニングするための参考プロジェクトと、一時的な認証情報を取得するためのサンプルスクリプトをご覧ください。

トラブルシューティング

An error occurred (AccessDenied) when calling the AssumeRoleWithWebIdentity operation: Not authorized to perform sts:AssumeRoleWithWebIdentity

このエラーは複数の理由で発生する可能性があります:

  • クラウド管理者が GitLab で OIDC を使用するようにプロジェクトを設定していません。
  • ロールがブランチまたはタグ上で実行されることが制限されています。条件付きロールの設定を参照してください。
  • StringEquals はワイルドカード条件を使用する場合、StringLike の代わりに使用されます。関連するイシューを参照してください。