Photo by PJH on Unsplash

On this page

This chapter follows Google Cloud Storage. Cloud Build executes steps—each step runs in a container with your source workspace mounted. It fits the broader CI/CD picture: compile, test, image, deploy on every merge.

The series uses the file-api-deployer service account from IAM in Google Cloud.

How Cloud Build runs a build

Cloud Build reads cloudbuild.yaml (or inline config), pulls builder images (gcr.io/cloud-builders/docker, gcloud, custom), and runs steps sequentially unless you define waitFor.

Each build gets a build service account (default Compute Engine SA or a custom SA). That identity must push to Artifact Registry and deploy Cloud Run.

Grant the deployer account to act as Cloud Build’s runtime (project-level):

Terminal window
PROJECT_NUMBER=$(gcloud projects describe YOUR_PROJECT_ID --format='value(projectNumber)')
CLOUD_BUILD_SA="${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com"
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
--member="serviceAccount:${CLOUD_BUILD_SA}" \
--role="roles/artifactregistry.writer"
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
--member="serviceAccount:${CLOUD_BUILD_SA}" \
--role="roles/run.admin"
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
--member="serviceAccount:${CLOUD_BUILD_SA}" \
--role="roles/iam.serviceAccountUser"

Alternatively set serviceAccount on the build to file-api-deployer@... and grant that account the same roles.

cloudbuild.yaml for the series

cloudbuild.yaml
substitutions:
_REGION: europe-west1
_REPOSITORY: file-api
_SERVICE: file-api
_RUNTIME_SA: file-api-runtime@YOUR_PROJECT_ID.iam.gserviceaccount.com
steps:
- name: gcr.io/cloud-builders/docker
args:
- build
- -t
- ${_REGION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/app:$SHORT_SHA
- .
- name: gcr.io/cloud-builders/docker
args:
- push
- ${_REGION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/app:$SHORT_SHA
- name: gcr.io/google.com/cloudsdktool/cloud-sdk
entrypoint: gcloud
args:
- run
- deploy
- ${_SERVICE}
- --image=${_REGION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/app:$SHORT_SHA
- --region=${_REGION}
- --service-account=${_RUNTIME_SA}
- --platform=managed
- --quiet
images:
- ${_REGION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/app:$SHORT_SHA
options:
logging: CLOUD_LOGGING_ONLY

Run manually from the repo root:

Terminal window
gcloud builds submit --config=cloudbuild.yaml .

$PROJECT_ID and $SHORT_SHA are built-in substitutions.

Substitutions and secrets

User-defined substitutions start with _ (for example _REGION). Override at submit time:

Terminal window
gcloud builds submit --config=cloudbuild.yaml \
--substitutions=_REGION=europe-west1 .

Store sensitive values in Secret Manager and expose them to steps with availableSecrets—never commit API keys to cloudbuild.yaml.

Triggers and GitHub

Connect a repository in the Console (Cloud Build → Triggers) or with gcloud beta builds triggers create github. A push to main runs the same config as gcloud builds submit.

Use Workload Identity Federation for GitHub Actions instead of JSON keys when you outgrow native triggers—the IAM chapter outlines the pattern.

Logs, approvals, and failures

Build logs stream to Cloud Logging (logging: CLOUD_LOGGING_ONLY). Failed docker or gcloud steps exit non-zero and mark the build failed; fix IAM or image URLs first when push or deploy steps break.

Pin builder digests in regulated environments so builds do not pull moving tags unexpectedly.

Next: VPC networks in Google Cloud adds private networking and egress controls around Cloud Run.

Check your understanding

Question 1 of 5

0 of 5 checked

  1. 1. What file does Cloud Build normally read to define steps?

Search articles

Type a word to search published articles.

Open the search page