Gitlab CI 透過 GCP Workload Identity Federation 進行部署
GCP Workload Identity Federation
本篇情境為使用 Gitlab CI 透過 GCP workload identity
以 service account 身份使用 gcloud command 操作 cloud storage
使用 console 設定 Workload Identity Pool / Provider
Pool就不多說,名稱、ID、敘述即可建立
而 Provider (Identity Provider) 則是都建立在這個 Pool 底下
Provider 基本設定(ref)
這邊可參考 Gitlab 提供的文件
Provider attribute 設定(ref)
這邊稍微複雜
簡單來說就是把 Gitlab OIDC token claim 設定
跟 GCP Workload Identity 做好 mapping
以供後續做條件限制設定(attribute condition)
一開始可以設定簡單一點
- google.subject <-> assertion.sub
- attribute.project_path <-> assertion.project_path
後續如果要做更複雜的設定
可以參考 Gitlab OIDC 提供的 custom claims
後面限制就可以指定 namespace / ref / 指定 user 來操作
- attribute.namespace_path <-> assertion.namespace_path
- attribute.ref <-> assertion.ref
- attibute.user_email <-> assertion.user_email
Provider attribute condition 設定(ref)
像這樣設定就可以限制只有指定的 project 才能操作 service account
這邊使用的是 Google 規範的 CEL expression
assertion.project_path in ['ciao-lab/workload-identity-demo']
建立完成就會長這樣
允許 workload identity pool 存取 service account (ref)
存取權管理方式有很多種
可加入單一身份、整個 group 等許多方式
我這邊只綁進單一 service account 示範
讓 workload identity provider principal 可使用 roles/iam.workloadIdentityUser role 存取 service account
principal 格式可參考上方文件中的 principal type
這邊使用格式為 principalSet://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/${LOCATION}/workloadIdentityPools/${POOL_ID}/*
設定 service account 可存取 GCP 資源的權限
這邊單純只是要測試是否有權限可代表 service account 操作 GCP 資源
因此我就很簡單的建立一個 bucket 名稱為 ciao-sandbox-bucket
並在裡面放幾個測試檔案
接著讓 service account 可讀取這個 bucket 內的檔案 (storage object viewer role)
方便待會在 gitlab ci 測試用
Gitlab CI 測試存取(ref)
在 gitlab ci 中使用 gcloud auth login --cred-file command 以 service account 身份
並執行簡單的 gcloud 操作(查看指定 bucket 內的 objects)
stages:
- deploy
workload-identity:
stage: deploy
image: google/cloud-sdk:slim
id_tokens:
GITLAB_OIDC_TOKEN:
aud: https://gitlab.com
variables:
GCP_PROJECT_ID: your-project-name
GCP_PROJECT_NUMBER: your-project-number
POOL_ID: web-service-deployment-pool
PROVIDER_ID: gitlab
SERVICE_ACCOUNT_EMAIL: gcs-readonly-sa@example.iam.gserviceaccount.com
WORKLOAD_IDENTITY_PROVIDER: projects/$GCP_PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$PROVIDER_ID
script:
- echo $WORKLOAD_IDENTITY_PROVIDER
- echo "$GITLAB_OIDC_TOKEN" > .gitlab_oidc_token_file
- |
cat > .gcp_temp_cred.json <<JSON
{
"type":"external_account",
"audience":"//iam.googleapis.com/projects/$GCP_PROJECT_NUMBER/locations/global/workloadIdentityPools/$POOL_ID/providers/$PROVIDER_ID",
"subject_token_type":"urn:ietf:params:oauth:token-type:jwt",
"token_url":"https://sts.googleapis.com/v1/token",
"service_account_impersonation_url":"https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/$SERVICE_ACCOUNT_EMAIL:generateAccessToken",
"credential_source":{"file":".gitlab_oidc_token_file"}
}
JSON
- cat .gcp_temp_cred.json
- gcloud auth login --cred-file=$(pwd)/.gcp_temp_cred.json --project=$GCP_PROJECT_ID
- gcloud auth list
- rm -f .gcp_temp_cred.json
- gcloud storage ls --recursive gs://ciao-sandbox-bucket
相關資訊
- [Gitlab 文件] Workload Identity OIDC 設定
- [Gitlab 文件] OIDC custom claims
- [GCP 文件] 設定外部 IdP (Gitlab SaaS)
- [GCP 文件] 配合 AWS EC2 使用
參考影片