我有一个应用程序,已使用
gcloud app deploy
从本地工作站成功部署。
我现在正在尝试设置 GitHub Action 以在推送时执行此操作。
我正在做的事情的参考资料是以下两个 GitHub 操作: https://github.com/google-github-actions/deploy-appengine https://github.com/google-github-actions/auth
我希望按照(首选)直接工作负载身份联合部分进行授权: https://github.com/google-github-actions/auth?tab=readme-ov-file#preferred-direct-workload-identity-federation
设置工作负载身份池和提供程序似乎相对简单。
我认为失败的部分是配置“根据需要,允许从工作负载身份池到 Google Cloud 资源进行身份验证。”
设置我已经完成的工作负载身份池和提供程序:
gcloud iam workload-identity-pools create "${WIF_POOL_NAME}" \
--project="${GCP_PROJECT_ID}" \
--location="global" \
--display-name="GitHub Actions Pool"
gcloud iam workload-identity-pools providers create-oidc "${WIF_PROVIDER_NAME}" \
--project="${GCP_PROJECT_ID}" \
--location="global" \
--workload-identity-pool="${WIF_POOL_NAME}" \
--display-name="My GitHub repo Provider" \
--attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository,attribute.repository_owner=assertion.repository_owner" \
--attribute-condition="assertion.repository_owner=='${GITHUB_ORG}' && assertion.ref=='refs/heads/main'" \
--issuer-uri="https://token.actions.githubusercontent.com"
设置我已经完成的 iam 策略绑定:
export WORKLOAD_IDENTITY_POOL_ID=$(gcloud iam workload-identity-pools describe "${WIF_POOL_NAME}" \
--project="${GCP_PROJECT_ID}" \
--location="global" \
--format="value(name)" 2>&1)
export WORKLOAD_IDENTITY_PROVIDER=$(gcloud iam workload-identity-pools providers describe "${WIF_PROVIDER_NAME}" \
--project="${GCP_PROJECT_ID}" \
--location="global" \
--workload-identity-pool="$WIF_POOL_NAME" \
--format="value(name)" 2>&1)
export GCP_PROJECT_NUMBER=$(gcloud projects describe \
$(gcloud config get-value core/project) \
--format="value(projectNumber)" 2>&1)
echo "project_id: '${GCP_PROJECT_ID}'"
echo "workload_identity_provider: '${WORKLOAD_IDENTITY_PROVIDER}'"
gcloud iam service-accounts add-iam-policy-binding "${GCP_PROJECT_ID}@appspot.gserviceaccount.com" \
--member=serviceAccount:SERVICE_AGENT_EMAIL \
--role=roles/iam.serviceAccountTokenCreator
gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
--project="${PROJECT_ID}" \
--role="roles/appengine.deployer" \
--member="principalSet://iam.googleapis.com/${WORKLOAD_IDENTITY_POOL_ID}/attribute.repository/${REPO}"
gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
--project="${PROJECT_ID}" \
--role="roles/appengine.deployer" \
--member="serviceAccount:${GCP_PROJECT_ID}@appspot.gserviceaccount.com"
gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
--project="${PROJECT_ID}" \
--role="roles/iam.workloadIdentityUser" \
--member="principalSet://iam.googleapis.com/${WORKLOAD_IDENTITY_POOL_ID}/attribute.repository/${REPO}"
gcloud iam service-accounts add-iam-policy-binding "${GCP_PROJECT_ID}@appspot.gserviceaccount.com" \
--project="${GCP_PROJECT_ID}" \
--role="roles/iam.serviceAccountUser" \
--member="principalSet://iam.googleapis.com/${WORKLOAD_IDENTITY_POOL_ID}/attribute.repository/${REPO}"
GitHub actions 报告的错误是:
Running: gcloud app deploy --quiet --format json app.yaml --promote
Error: google-github-actions/deploy-appengine failed with: failed to execute gcloud command `gcloud app deploy --quiet --format json app.yaml --promote`:
ERROR: (gcloud.app.deploy) Permissions error fetching application [apps/appspot].
Please make sure that you have permission to view applications on the project and that *** has the App Engine Deployer (roles/appengine.deployer) role.
这是我正在使用的 GitHub 操作文件:
name: Deployment
on:
push:
branches:
- main
jobs:
job_id:
name: Deploy to App Engine
runs-on: ubuntu-latest
permissions:
contents: 'read'
id-token: 'write'
steps:
- id: 'checkout'
uses: 'actions/checkout@v4'
- id: 'auth'
uses: 'google-github-actions/auth@v2'
with:
service_account: '${{ secrets.GCP_SA }}'
workload_identity_provider: '${{ secrets.WIF_PROVIDER }}'
- id: 'deploy'
uses: 'google-github-actions/deploy-appengine@v2'
我现在可以使用这个了。我通过创建一个执行部署的新服务帐户稍微改变了策略。然后,工作负载身份提供程序使用该服务帐户进行部署。
这样做的好处是,它允许我在从 GitHub Actions 切换到工作负载身份提供程序之前在本地使用常规用户帐户测试服务帐户。
第一件事是创建新的服务帐户:
gcloud iam service-accounts create $GCP_SVC_ACC \
--description="For deploying app engine" \
--display-name="app deploy bot"
然后为该服务帐户提供部署应用程序引擎所需的角色:
gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
--member="serviceAccount:${GCP_SVC_ACC}@${GCP_PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/appengine.deployer"
gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
--member="serviceAccount:${GCP_SVC_ACC}@${GCP_PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/cloudbuild.builds.editor"
gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
--member="serviceAccount:${GCP_SVC_ACC}@${GCP_PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/storage.objectAdmin"
gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
--member="serviceAccount:${GCP_SVC_ACC}@${GCP_PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/appengine.serviceAdmin"
然后向部署服务帐户授予对 App Engine 默认服务帐户的访问权限。
gcloud iam service-accounts add-iam-policy-binding "${GCP_PROJECT_ID}@appspot.gserviceaccount.com" \
--member="serviceAccount:${GCP_SVC_ACC}@${GCP_PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/iam.serviceAccountUser"
为了测试服务帐户是否可以被模拟并用于部署应用程序引擎,我授予用户为服务帐户创建令牌的权限,然后使用服务帐户:
gcloud iam service-accounts add-iam-policy-binding "${GCP_SVC_ACC}@${GCP_PROJECT_ID}.iam.gserviceaccount.com" \
--member="user:${GCP_USER_EMAIL}" \
--role="roles/iam.serviceAccountTokenCreator"
gcloud iam service-accounts add-iam-policy-binding "${GCP_SVC_ACC}@${GCP_PROJECT_ID}.iam.gserviceaccount.com" \
--member="user:${GCP_USER_EMAIL}" \
--role="roles/iam.serviceAccountUser"
然后我可以使用以下命令从本地计算机测试部署服务帐户:
gcloud app deploy --impersonate-service-account="${GCP_SVC_ACC}@${GCP_PROJECT_ID}.iam.gserviceaccount.com"
一旦工作正常,创建工作负载身份池:
gcloud iam workload-identity-pools create "${WIF_POOL_NAME}" \
--project="${GCP_PROJECT_ID}" \
--location="global" \
--display-name="GitHub Actions Pool"
接下来,创建工作负载身份提供者:
gcloud iam workload-identity-pools providers create-oidc "${GCP_PROVIDER_NAME}" \
--project="${GCP_PROJECT_ID}" \
--location="global" \
--workload-identity-pool="${WIF_POOL_NAME}" \
--display-name="My GitHub repo Provider" \
--attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository,attribute.repository_owner=assertion.repository_owner" \
--attribute-condition="assertion.repository_owner=='${GITHUB_ORG}' && assertion.ref=='refs/heads/main'" \
--issuer-uri="https://token.actions.githubusercontent.com"
允许工作负载提供商创建用于模拟部署服务帐户的令牌并使用它:
gcloud iam service-accounts add-iam-policy-binding "${GCP_SVC_ACC}@${GCP_PROJECT_ID}.iam.gserviceaccount.com" \
--member="principalSet://iam.googleapis.com/${WORKLOAD_IDENTITY_POOL_ID}/attribute.repository/${GITHUB_ORGREPO}" \
--role="roles/iam.serviceAccountTokenCreator"
gcloud iam service-accounts add-iam-policy-binding "${GCP_SVC_ACC}@${GCP_PROJECT_ID}.iam.gserviceaccount.com" \
--member="principalSet://iam.googleapis.com/${WORKLOAD_IDENTITY_POOL_ID}/attribute.repository/${GITHUB_ORGREPO}" \
--role="roles/iam.serviceAccountUser"
接下来,获取 GitHub Actions YAML 文件所需的信息:
export WORKLOAD_IDENTITY_POOL_ID=$(gcloud iam workload-identity-pools describe "${WIF_POOL_NAME}" \
--project="${GCP_PROJECT_ID}" \
--location="global" \
--format="value(name)" 2>&1)
export WORKLOAD_IDENTITY_PROVIDER=$(gcloud iam workload-identity-pools providers describe "${GCP_PROVIDER_NAME}" \
--project="${GCP_PROJECT_ID}" \
--location="global" \
--workload-identity-pool="$WIF_POOL_NAME" \
--format="value(name)" 2>&1)
# Information for GitHub Actions yaml file
echo "workload_identity_provider: '${WORKLOAD_IDENTITY_PROVIDER}'"
echo "service_account: '${GCP_SVC_ACC}@${GCP_PROJECT_ID}.iam.gserviceaccount.com'"
我的最终工作流程文件是:
name: Deployment
on:
workflow_dispatch:
push:
branches:
- main
jobs:
job_id:
name: Deploy to App Engine
runs-on: ubuntu-latest
permissions:
contents: 'read'
id-token: 'write'
steps:
- uses: 'actions/checkout@v4'
- id: 'auth'
uses: 'google-github-actions/auth@v2'
with:
workload_identity_provider: '${{ secrets.GCP_IDENTITY_PROVIDER }}'
service_account: '${{ secrets.GCP_SVC_ACC }}'
- id: 'deploy'
uses: 'google-github-actions/deploy-appengine@v2'