NOTE : For privacy purposes, I changed the project name to "xxx" in this post.
I am working on a Github Actions workflow to deploy a NuxtJS app to Google App Engine, that fails on this command :
Running: gcloud app deploy --quiet --format json app.dev.yaml --project xxx --promote
It fails with the following error : Failed to create cloud build: IAM authority does not have the permission 'cloudbuild.builds.create' required for action CreateBuild on resource 'projects/xxx' followed by an "explanation" that doesn't make much sense (see full log below).
Before that, a build job is working fine and creates the .output folders with all files as expected and uploads them as artifacts, ready to be downloaded.
Here is the deploy job in the Github Actions workflow YAML file that causes the error :
# Build job
...
# App Engine deploy
deploy:
if: github.ref == 'refs/heads/staging' || github.ref == 'refs/heads/master'
name: App Engine Deploy
needs: [build]
runs-on: ubuntu-latest
permissions:
contents: read
packages: read
id-token: write
steps:
- uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: front-build-artifacts
# STAGING App engine deploy
- name: Authenticate with Google Cloud on dev environment
if: github.ref == 'refs/heads/staging'
uses: 'google-github-actions/auth@v2' # https://github.com/google-github-actions/auth
with:
credentials_json: ${{ secrets.GCP_DEV_KEY }}
- name: App engine deploy on dev environment
if: github.ref == 'refs/heads/staging'
uses: google-github-actions/deploy-appengine@v2 # https://github.com/marketplace/actions/deploy-to-app-engine
with:
project_id: xxx
deliverables: 'app.dev.yaml'
Run google-github-actions/deploy-appengine@v2
with:
project_id: xxx
deliverables: app.dev.yaml
promote: true
env:
CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE: /home/runner/work/XXX-front/XXX-front/gha-creds-6ada118c927f2f3a.json
GOOGLE_APPLICATION_CREDENTIALS: /home/runner/work/XXX-front/XXX-front/gha-creds-6ada118c927f2f3a.json
GOOGLE_GHA_CREDS_PATH: /home/runner/work/XXX-front/XXX-front/gha-creds-6ada118c927f2f3a.json
CLOUDSDK_CORE_PROJECT: xxx
CLOUDSDK_PROJECT: xxx
GCLOUD_PROJECT: xxx
GCP_PROJECT: xxx
GOOGLE_CLOUD_PROJECT: xxx
/usr/bin/tar xz --warning=no-unknown-keyword --overwrite -C /home/runner/work/_temp/11678d2d-0405-4945-b890-f883e482c60e -f /home/runner/work/_temp/8b9fb6d2-eb23-4081-96f2-f65cd470c180
Successfully authenticated
Running: gcloud app deploy --quiet --format json app.dev.yaml --project xxx --promote
Error: google-github-actions/deploy-appengine failed with: failed to execute gcloud command `gcloud app deploy --quiet --format json app.dev.yaml --project xxx --promote`: Services to deploy:
descriptor: [/home/runner/work/XXX-front/XXX-front/app.dev.yaml]
source: [/home/runner/work/XXX-front/XXX-front]
target project: [xxx]
target service: [default]
target version: [20240208t163840]
target url: [https://xxx.ew.r.appspot.com]
target service account: [[email protected]]
Beginning deployment of service [default]...
╔════════════════════════════════════════════════════════════╗
╠═ Uploading 623 files to Google Cloud Storage ═╣
╚════════════════════════════════════════════════════════════╝
File upload done.
Updating service [default]...
..................................failed.
ERROR: (gcloud.app.deploy) Error Response: [7] Failed to create cloud build: IAM authority does not have the permission 'cloudbuild.builds.create' required for action CreateBuild on resource 'projects/xxx'. Explanation: Security Context: RecordingSecurityContext{delegate=ValidatedSecurityContextWithSystemAuthorizationPolicy{delegate=ValidatedSecurityContextWithRegistryHandle{delegate=ValidatedSecurityContextWithObligations{delegate=ContextWithGaiaMintToken{delegate=ValidatedIamSecurityContext{user=gaiauser/0xXXXXXXXX, creds=EndUserCreds{loggable_credential { type: GAIA_MINT loggable_gaia_mint { } } loggable_credential { type: SERVICE_CONTROL_TOKEN }}, peer=protocol=loas;psp_version=0;level=strong_privacy_and_integrity;host=whfw5.prod.google.com;is_authenticated_host=false;role=cloud-build-api;user=app-engine-zeus-worker;is_delegated=true;jobname_chosen_by_user=prod-europe-west1.cloud-build-api, InternalIAMIdentity{log=data_access_reason { manual_reason: "Acquiring DAT for long-lived Admin API procedures." } originator { scope: GAIA_USER gaia_user { user_id: XXXXXXXXXX } }}}}}}}}
com.google.apps.framework.auth.IamPermissionDeniedException: IAM authority does not have the permission 'cloudbuild.builds.create' required for action CreateBuild on resource 'projects/xxx'. Explanation: Security Context: RecordingSecurityContext{delegate=ValidatedSecurityContextWithSystemAuthorizationPolicy{delegate=ValidatedSecurityContextWithRegistryHandle{delegate=ValidatedSecurityContextWithObligations{delegate=ContextWithGaiaMintToken{delegate=ValidatedIamSecurityContext{user=gaiauser/0xXXXXXXXX, creds=EndUserCreds{loggable_credential { type: GAIA_MINT loggable_gaia_mint { } } loggable_credential { type: SERVICE_CONTROL_TOKEN }}, peer=protocol=loas;psp_version=0;level=strong_privacy_and_integrity;host=whfw5.prod.google.com;is_authenticated_host=false;role=cloud-build-api;user=app-engine-zeus-worker;is_delegated=true;jobname_chosen_by_user=prod-europe-west1.cloud-build-api, InternalIAMIdentity{log=data_access_reason { manual_reason: "Acquiring DAT for long-lived Admin API procedures." } originator { scope: GAIA_USER gaia_user { user_id: XXXXXXXXXX} }}}}}}}}.
The Google Cloud authentication using the env credentials_json: ${{ secrets.GCP_DEV_KEY }} works fine, it does authenticate as a Service Account that has the following roles :
- App Engine Standard Environment Service Agent
- Cloud Build Service Agent
- Cloud Functions Service Agent
- Editor
- Firebase Extensions API Service Agent
- Firebase Service Management Service Agent
- Owner
- Service Account Token Creator
- Service Account User
It seems to me that it's a permission issue with that service account, but I don't understand which roles could be missing.
Additionally, if anyone can explain better what the "Explanation: Security Context" part of the logs mean, I'd be glad to know !