Bitbucket Pipeline × Google Cloud Workload Identity連携
概要
BitBcuket PilpelineとGoogle CloudのWorkload Identity連携でサービスアカウントの発行無しで、Pipelineの連携を行う手順を備忘録として記載します。
操作は、Console画面から実施します。
手順
1. OIDC(OpenID Connect)でIdentityプロバイダを確認
bitbucketの「Pipeline > OpenID Connect」のURLとAudienceの情報を確認し、メモしておきます。
2. Workload Identityプールでプロバイダの設定
Google Cloudの「IAM > Workload Identity 連携」でプロバイダとプールを作成します。
項目 | 設定値 |
---|---|
プール名 | test-bitbucket |
プロバイダの選択 | OpenID Cpnnect |
プロバイダ名 | test-bitbucket |
プロバイダID | test-bitbucket |
URL | <1.で確認したURL> (https://api.bitbucket.org...) |
オーディエンス | ✅許可するオーディエンス <1.で確認したAudience> (ari:cloud:bitbucket...) |
プロバイダの属性1 : google.subject | assertion.sub |
プロバイダの属性2(追加) : attribute.workspace_uuid | assertion.workspaceUuid |
今回、属性条件(IDのサブセットのみ認証を制限する)は指定しません。
作成が完了すると以下のような「IAMプリンシパル」が生成されます。
principal://iam.googleapis.com/projects/<project_id>/locations/global/workloadIdentityPools/test-bitbucket/subject/SUBJECT_ATTRIBUTE_VALUE
サービスアカウントへのアクセスを許可するには、SUBJECT_ATTRIBUTE_VALUE を Workload Identity プール内の特定のサブジェクトに置き換え、そのプリンシパルにサービスアカウントに対する Workload Identity ユーザーロールを付与します。
また、プリンシパルのIDは任意の属性に一致するIDを指定することが可能なので、今回はATTRIBUTE_VALUEでBitBuket Pipeline上のWorkspace UUIDと一致するプリンシパルを用意します。
- principalSetの指定:
principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/attribute.ATTRIBUTE_NAME/ATTRIBUTE_VALUE
- Sample:
principalSet://iam.googleapis.com/projects/<project_id>/locations/global/workloadIdentityPools/<pool_id>/attribute.workspace_uuid/<Workspace UUID:{3fa48120-66b0...>
3. IAM権限の設定と構成ファイルの取得
上記のプリンシパルをIAMで登録します。今回は、Pipelineの動作確認のため cloud storageのバケット一覧を確認するため、roles/storage.admin
を上記プリンシパルに付与します。
設定の順序は特に関係ありませんが、ファイルパスに /tmp/oidc-token.txt
を指定し構成をダウンロードします。
4. Pipelineの設定
ダウンロードした構成ファイルをBitbucketのDeploymentの任意の環境でBITBUCKET_STEP_OIDC_TOKEN
の環境変数を上記の構成ファイルのJSON文字列をコピー&ペーストして設定します。
Pipeline上で環境変数で指定したJSONを
echo -n "${BITBUCKET_STEP_OIDC_TOKEN}" > /tmp/oidc-token.txt
で出力し、対象のOIDCの構成ファイルを元に
gcloud iam workload-identity-pools create-cred-config <対象のプリンシパル> <構成ファイル> <出力ファイル>
として認証情報を発行し、GOOGLE_APPLICATION_CREDENTIALS(GAC)に指定する事でデフォルトの認証情報として以降の処理を実行するようにします。
pipelines:
default:
- step:
name: test
oidc: true
image: google/cloud-sdk:alpine
script:
- export GCP_PROJECT_NUMBER=<project_id>
- export PROJECT_NAME=<project_name>
- export workload_identity_pool_id='test-bitbucket'
- export workload_identity_pool_provider_id='test-bitbucket'
- echo -n "${BITBUCKET_STEP_OIDC_TOKEN}" > /tmp/oidc-token.out
- gcloud iam workload-identity-pools create-cred-config "projects/${GCP_PROJECT_NUMBER}/locations/global/workloadIdentityPools/${workload_identity_pool_id}/providers/${workload_identity_pool_provider_id}" --credential-source-file=/tmp/oidc-token.out --output-file=creds.json
- export GOOGLE_APPLICATION_CREDENTIALS=`pwd`/creds.json
- gcloud auth login --cred-file=`pwd`/creds.json
- CLOUDSDK_CORE_DISABLE_PROMPTS=1 gcloud components install alpha
- gcloud --project "${PROJECT_NAME}" storage ls
4. 結果
上記のPipelineを実行することによって、サービスアカウントは発行せずに、バケットの一覧が取得でき、アクセストークンの交換の結果が指標として表示されました。
gs://gcf-.../
gs://...
備考
principalSubjectとWorkspace UUIDが一致しない場合
IAMで管理しているプリンシパルのUUIDを変更してPipelineを実行してみます
principalSet://iam.googleapis.com/projects/<project_id>/locations/global/workloadIdentityPools/test-bitbucket/attribute.workspace_uuid/{3fa_test}
Unique identifiersと一致しないため、権限が無く失敗しました。
参考
- https://cloud.google.com/iam/docs/workload-identity-federation?hl=ja
- https://cloud.google.com/iam/docs/principal-identifiers
- https://jira.atlassian.com/browse/BCLOUD-21138
- https://community.atlassian.com/t5/Bitbucket-questions/How-set-up-bitbucket-pipeline-using-a-gcp-private-image-via-OIDC/qaq-p/1792393
Discussion