GitLab Runner で OpenID Connect を使用して AWS にアクセスしてみた
概要
GitHub Actions が OpenID Connect をサポートしていますが、 GitLab でも同様にサポートしています。
AWS IAM OIDC Provider に gitlab を登録し、credentials を発行することなく aws にアクセスすることを検証します。
参考
https://docs.gitlab.com/ee/ci/cloud_services/aws/
やってみた
まず、AWS IAM OIDC Provider に gitlab を登録します。
Provider URL には https://gitlab.com
(最後のスラッシュはいりません!!!),
対象者 にも https://gitlab.com
(sts.amazonaws.com
ではありません!!!) を設定します。
AWSTemplateFormatVersion: "2010-09-09" Parameters: GitLabThumbprint: Type: String Resources: GitLabOIDCProvider: Type: AWS::IAM::OIDCProvider Properties: Url: https://gitlab.com ClientIdList: - https://gitlab.com ThumbprintList: - !Ref GitLabThumbprint
ID Provider を登録したあとは、そのプロバイダを信頼した Role を作成します。
例として s3 bucket にアクセスできる Role を作成する CloudFormation Template を用意しました。
ポイントは AssumeRole WithWebIdentity を許可すること, sub のフォーマットが github actions の repo:
とは違い project_path:
になっている点です。
AWSTemplateFormatVersion: "2010-09-09" Parameters: GitLabProject: Type: String Resources: GitLabRunnerRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Federated: !Sub arn:aws:iam::${AWS::AccountId}:oidc-provider/gitlab.com Action: sts:AssumeRoleWithWebIdentity Condition: StringEquals: gitlab.com:sub: !Sub project_path:${GitLabProject}:ref_type:branch:ref:main Policies: - PolicyName: s3access PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: s3:GetObject Resource: - !Sub arn:aws:s3:::${Bucket}/* - Effect: Allow Action: s3:ListBucket Resource: - !Sub arn:aws:s3:::${Bucket} Bucket: Type: AWS::S3::Bucket Outputs: GitLabRunnerRoleArn: Value: !GetAtt GitLabRunnerRole.Arn Bucket: Value: !Ref Bucket
では実際に動作を確認するため、gitlab-ci.yaml を用意します。
--- image: public.ecr.aws/sam/build-go1.x variables: AWS_DEFAULT_REGION: $AWS_DEFAULT_REGION AWS_IAM_ROLE: $AWS_IAM_ROLE AWS_S3_BUCKET: $AWS_S3_BUCKET deploy: stage: deploy environment: name: development script: - > STS=($(aws sts assume-role-with-web-identity --role-arn ${AWS_IAM_ROLE} --role-session-name "GitLabRunner-${CI_PROJECT_ID}-${CI_PIPELINE_ID}" --web-identity-token "${CI_JOB_JWT_V2}" --duration-seconds 3600 --query 'Credentials.[AccessKeyId,SecretAccessKey,SessionToken]' --output text)) - export AWS_ACCESS_KEY_ID="${STS[0]}" - export AWS_SECRET_ACCESS_KEY="${STS[1]}" - export AWS_SESSION_TOKEN="${STS[2]}" - aws s3 ls s3://${AWS_S3_BUCKET}/
AWS_IAM_ROLE, AWS_S3_BUCKET は variables 経由で設定するようにします。
web-identity-token 用の CI_JOB_JWT_V2 が発行されるので、こちらを利用します。
余談ですが、 gitlab は環境ごとに変数の値を設定できます。また、 protected branch のみ使用できる変数といった設定も可能です。
実行できました。