This chapter covers Cloud Build, Google Cloud's fully managed CI/CD platform, and its role in automating software delivery on GCP. For the ACE exam, this topic appears in roughly 5-8% of questions, primarily in the 'Deploy and Implement' domain (Objective 3.2). You will be tested on Cloud Build triggers, build configurations, integration with source repositories, and deployment to GCP services like GKE, Cloud Run, and Compute Engine. Mastery of Cloud Build is essential for automating pipelines and ensuring repeatable, auditable deployments.
Jump to a section
Imagine a car manufacturing plant. The plant manager (Cloud Build) receives an order (a code commit) to build a specific car model (your application). The order includes a blueprint (cloudbuild.yaml) that lists every step: weld the chassis (compile code), paint the body (run tests), install the engine (package artifacts), and test the brakes (deploy to staging). Each station on the assembly line is a build step, and the entire line is a build pipeline. The manager can trigger the line automatically whenever a new order arrives (GitHub push trigger), or manually for a special prototype (manual invocation). If a station fails (test failure), the line stops and the manager sends an alert (Cloud Build notification). The plant has a warehouse (Container Registry) where finished cars (Docker images) are stored. The manager can also run multiple lines in parallel for different models (build parallelism). Just as a car plant uses standardized tools and robots, Cloud Build uses pre-built or custom builder images to execute steps in a consistent environment. The manager tracks each car's build history (logs and artifacts) and can rerun a specific build from a previous step (build retry).
What is Cloud Build?
Cloud Build is a fully managed continuous integration and continuous delivery (CI/CD) platform on Google Cloud. It executes build steps in a series of isolated, containerized environments. Each build step runs inside a Docker container, and you can use pre-built images (e.g., gcr.io/cloud-builders/gcloud, gcr.io/cloud-builders/docker) or custom images from any registry. Cloud Build can import source code from Cloud Storage, Cloud Source Repositories, GitHub, Bitbucket, or GitLab. It can produce artifacts such as Docker images, Java JARs, or arbitrary files, and store them in Container Registry, Artifact Registry, or Cloud Storage.
How Cloud Build Works Internally
When you submit a build, Cloud Build performs the following steps:
1. Source Fetching: Cloud Build downloads the source code from the specified repository or storage location. For GitHub or Bitbucket, you can configure a trigger that automatically starts a build when code is pushed or a pull request is created.
2. Build Execution: Cloud Build reads the build configuration file (by default cloudbuild.yaml or cloudbuild.json) and executes each step sequentially in a dedicated, ephemeral Docker container. Each step can specify:
- name: The container image to use (e.g., gcr.io/cloud-builders/gcloud).
- entrypoint: Override the container's default entrypoint.
- args: Arguments to pass to the entrypoint.
- env: Environment variables.
- dir: Working directory relative to /workspace.
- id: A unique identifier for the step.
- waitFor: A list of step IDs that must complete before this step runs (default: previous step). Use ['-'] to run in parallel.
3. Artifact Storage: After the build steps complete, Cloud Build can store artifacts (e.g., built binaries, Docker images) in Container Registry, Artifact Registry, or Cloud Storage. You can also push Docker images automatically using docker push or the gcr.io/cloud-builders/docker builder.
4. Logging and Notifications: Cloud Build streams logs to Cloud Logging and can send notifications via Pub/Sub, Cloud Functions, or Slack webhooks. Build status can be viewed in the Console or via gcloud builds describe.
Build Configuration File Structure
The cloudbuild.yaml file has the following key sections:
- steps: Required. An array of build step objects.
- images: Optional. A list of Docker image names to build and push (e.g., ['gcr.io/$PROJECT_ID/my-image']). Cloud Build will execute docker build and docker push automatically if this is provided, but you can also do it manually in a step.
- artifacts: Optional. Specify objects to store in Cloud Storage after the build.
- options: Optional. Configure logging, machine type, substitution variables, etc.
- timeout: Optional. Maximum build duration (default 10 minutes, max 24 hours).
- tags: Optional. Labels for the build.
- substitutions: Optional. Define custom variable substitutions.
Key Features for the ACE Exam
Triggers: You can create build triggers that automatically start a build when code is pushed to a branch, a tag is created, or a pull request is opened. Triggers are configured per repository and can filter by branch/tag regex. They support GitHub, Bitbucket, GitLab, and Cloud Source Repositories.
Substitution Variables: Use built-in variables like $PROJECT_ID, $BUILD_ID, $REPO_NAME, $BRANCH_NAME, $TAG_NAME, $COMMIT_SHA, $SHORT_SHA. You can define custom variables in the trigger or in the build config.
Parallel Steps: Use waitFor: ['-'] to run steps in parallel. By default, steps run sequentially, each waiting for the previous step to complete.
Custom Builders: You can create custom builder images to run tools not available in the default set. Publish them to Container Registry and reference them in steps.
Private Pools: For builds that need to access VPC resources, use private pools to run builds in a specific VPC network. This allows Cloud Build to reach private IP addresses (e.g., on-premises resources, private GKE clusters). Private pools are provisioned with a specific machine type (e.g., e2-standard-2) and scale to zero when idle.
IAM Roles: Key roles include cloudbuild.builds.builder (allows submitting builds), cloudbuild.builds.viewer (view builds), and cloudbuild.builds.approver (approve builds requiring approval). For triggers, use cloudbuild.triggers.create, cloudbuild.triggers.update, etc.
Build Approvals: You can require manual approval before a build can proceed. This is configured in the trigger settings. A user with cloudbuild.builds.approver role must approve the build via Console or gcloud builds approve.
Common Commands
- gcloud builds submit: Submit a build from the current directory or a specified source. Example:
gcloud builds submit --tag gcr.io/$PROJECT_ID/my-image This command uploads the source, executes the build steps defined in cloudbuild.yaml (or uses a default Docker build if no config is found), and pushes the image.
- gcloud builds list: List recent builds.
- gcloud builds describe BUILD_ID: Get details of a specific build.
- gcloud builds log BUILD_ID: Stream logs for a build.
- gcloud builds triggers create ...: Create a trigger (e.g., for GitHub, Bitbucket, Cloud Source Repositories).
- gcloud builds triggers list: List triggers.
- gcloud builds triggers run TRIGGER_ID --branch=BRANCH: Manually run a trigger.
Integration with Other GCP Services
- Cloud Run: Deploy a container image built by Cloud Build directly to Cloud Run using the gcr.io/cloud-builders/gcloud builder:
steps:
- name: 'gcr.io/cloud-builders/gcloud'
args: ['run', 'deploy', 'my-service', '--image=gcr.io/$PROJECT_ID/my-image', '--region=us-central1', '--platform=managed']GKE: Deploy to a GKE cluster using kubectl or the gcr.io/cloud-builders/kubectl builder. You must ensure the Cloud Build service account has the necessary IAM permissions to access the cluster.
Compute Engine: Deploy by copying artifacts to a VM via SSH or using gcloud compute ssh.
Firebase: Use the gcr.io/cloud-builders/firebase builder to deploy to Firebase Hosting or Cloud Functions.
Cloud Functions: Use gcloud functions deploy in a build step.
Default Values and Timers
Default timeout: 10 minutes. Max 24 hours.
Default machine type: e2-standard-2 for standard builds, n1-highcpu-8 for larger builds. Private pools can use different machine types.
Logs bucket: Build logs are stored in Cloud Storage at gs://PROJECT_ID.cloudbuild-logs.googleusercontent.com/.
Source size limit: 50 GB per build.
Concurrent builds: By default, up to 10 builds per region per project (can be increased via quota request).
Create a cloudbuild.yaml File
Define the build steps in a YAML or JSON file. Each step specifies a container image, entrypoint, and arguments. Use the `steps` array to list sequential or parallel steps. Include optional `images` and `artifacts` sections. The file must be in the root of your source directory or specified with `--config` in the `gcloud builds submit` command.
Submit the Build to Cloud Build
Use `gcloud builds submit` to upload the source code and trigger the build. Cloud Build compresses the source (excluding files listed in `.gcloudignore`), uploads it to Cloud Storage, and then executes the steps. You can also submit a build manually via the Console or using a trigger.
Execute Build Steps Sequentially
Cloud Build runs each step in a separate Docker container. The working directory is `/workspace`, which is shared across all steps. Steps run in order unless `waitFor` is used to run in parallel. Each step can access environment variables, including built-in substitutions like `$PROJECT_ID` and `$BUILD_ID`.
Store Artifacts and Push Images
After the build steps, Cloud Build can automatically push Docker images to Container Registry or Artifact Registry if specified in the `images` section. It can also upload arbitrary files to Cloud Storage using the `artifacts` section. You can also explicitly run `docker push` or `gsutil cp` in a step.
View Build Logs and Status
Build logs are streamed to Cloud Logging and stored in Cloud Storage. You can view them in the Console under Cloud Build > History, or use `gcloud builds log BUILD_ID`. Build status can be checked with `gcloud builds describe BUILD_ID`. Notifications can be sent via Pub/Sub or webhooks.
Enterprise Scenario 1: Multi-Environment Microservices Deployment
A large e-commerce company uses Cloud Build to deploy over 50 microservices to Google Kubernetes Engine (GKE) across dev, staging, and production environments. Each service has its own cloudbuild.yaml that builds a Docker image, runs unit and integration tests, and then deploys to the appropriate GKE cluster using the gcr.io/cloud-builders/kubectl builder. They use Cloud Build triggers connected to a GitHub repository; pushes to main trigger a build that deploys to staging, while tags like v* trigger production deployments. To manage secrets (e.g., database passwords), they use Cloud KMS encryption and decrypt them in build steps using the gcr.io/cloud-builders/gcloud builder with the kms decrypt command. A common pitfall is forgetting to grant the Cloud Build service account the container.deployer role on the GKE cluster, causing deployment failures. They also set up Pub/Sub notifications to send build status to a Slack channel for real-time visibility.
Enterprise Scenario 2: Cross-Project CI/CD with Artifact Registry
A financial services firm uses Cloud Build to build and deploy applications across multiple GCP projects (one per environment). They use Artifact Registry for storing Docker images centrally in a shared project. The build pipeline compiles Java code, runs SonarQube analysis, builds a Docker image, pushes it to Artifact Registry, and then deploys to Cloud Run in the target project. They use Cloud Build's --substitutions flag to pass environment-specific variables (e.g., _ENV=prod). A key challenge is managing IAM permissions: the Cloud Build service account in the source project must have artifactregistry.writer on the registry, and the deployment project must allow the service account to invoke Cloud Run services. They also use Cloud Build's private pools to access a VPC-hosted SonarQube server, avoiding public internet exposure. A common misconfiguration is setting the private pool network incorrectly, causing build steps to fail with network timeouts.
Scenario 3: Serverless CI/CD for Cloud Functions
A startup uses Cloud Build to deploy Python Cloud Functions triggered by Cloud Storage events. Their cloudbuild.yaml runs linting, unit tests, and then deploys using gcloud functions deploy. They use a trigger on a Cloud Source Repository; any commit to the functions branch triggers a build. They discovered that the default Cloud Build service account lacks cloudfunctions.functions.create permission, so they had to grant it explicitly. They also use Cloud Build's --timeout flag to set a 30-minute timeout because some deployments involve large dependencies. A common mistake is not using a .gcloudignore file, causing large node_modules or __pycache__ directories to be uploaded, slowing the build and exceeding the 50 GB source limit.
What the ACE Exam Tests on Cloud Build
The ACE exam (Objective 3.2) focuses on your ability to set up and manage CI/CD pipelines using Cloud Build. Key areas include:
- Build Configuration: Understanding the structure of cloudbuild.yaml, including steps, images, artifacts, timeout, and options. You may be asked to identify the correct syntax or spot errors.
- Triggers: Creating triggers for GitHub, Bitbucket, and Cloud Source Repositories. Know how to filter by branch or tag using regex.
- IAM Roles: The difference between cloudbuild.builds.builder, cloudbuild.builds.viewer, and cloudbuild.builds.approver. The exam often tests which role is needed to submit a build vs. view logs.
- Integration with GCP Services: Deploying to Cloud Run, GKE, Compute Engine, and Cloud Functions. You must know the correct builder images and commands (e.g., gcloud run deploy, kubectl apply).
- Substitution Variables: Built-in variables like $PROJECT_ID, $BUILD_ID, $BRANCH_NAME, $COMMIT_SHA, $SHORT_SHA. The exam may ask which variable to use for a unique build identifier.
- Private Pools: When to use private pools (e.g., to access VPC resources) and how to configure them.
- Build Approvals: How manual approval works and which role is required.
Common Wrong Answers and Traps
Wrong: Cloud Build can only build Docker images. Reality: Cloud Build can run arbitrary build steps using any container image. It is not limited to Docker builds; you can compile code, run tests, or deploy using any tool.
Wrong: The `images` section automatically pushes images to Container Registry. Reality: The images section only specifies image names; you must still run docker build in a step (or use the default builder). Cloud Build will then automatically push the images if the build succeeds.
Wrong: You must use `gcloud builds submit` to trigger a build from a trigger. Reality: Triggers automatically start builds based on repository events. gcloud builds submit is for manual builds.
Wrong: Cloud Build can only access public repositories. Reality: Cloud Build can access private GitHub, Bitbucket, and GitLab repositories by connecting via OAuth or using SSH keys.
Wrong: Build logs are stored indefinitely. Reality: Build logs are stored in Cloud Storage and have a retention period (default 30 days). You can change the retention policy.
Specific Numbers and Values
Default timeout: 10 minutes
Max timeout: 24 hours
Default machine type: e2-standard-2
Source size limit: 50 GB
Concurrent builds per region: 10 (default)
Built-in substitution variables: $PROJECT_ID, $BUILD_ID, $REPO_NAME, $BRANCH_NAME, $TAG_NAME, $COMMIT_SHA, $SHORT_SHA
Default log bucket: gs://PROJECT_ID.cloudbuild-logs.googleusercontent.com/
Edge Cases
Build cancellation: If a build is cancelled, partial artifacts are not pushed. Logs up to the cancellation point are retained.
Parallel step failure: If one step in a parallel group fails, Cloud Build does not automatically cancel other steps in the same group.
Substitutions in step names: Substitution variables are resolved before step execution, so you can use them in args, env, and dir.
`.gcloudignore`: If you don't include a .gcloudignore file, Cloud Build will upload all files in the source directory, which might include large unnecessary files. The default .gcloudignore excludes common patterns like .git, node_modules, and .pyc.
Cloud Build is a fully managed CI/CD platform that executes build steps in containerized environments.
Build configuration is defined in `cloudbuild.yaml` with `steps`, `images`, `artifacts`, and `timeout`.
Default build timeout is 10 minutes; maximum is 24 hours.
Triggers automatically start builds on code push to GitHub, Bitbucket, GitLab, or Cloud Source Repositories.
Use built-in substitution variables like `$PROJECT_ID`, `$BUILD_ID`, `$BRANCH_NAME`, and `$SHORT_SHA`.
Cloud Build integrates with Cloud Run, GKE, Compute Engine, Cloud Functions, and Firebase.
Private pools allow builds to access VPC resources; they scale to zero when idle.
IAM roles: `cloudbuild.builds.builder` to submit builds, `cloudbuild.builds.viewer` to view, and `cloudbuild.builds.approver` to approve builds.
Build logs are stored in Cloud Storage at `gs://PROJECT_ID.cloudbuild-logs.googleusercontent.com/` with 30-day retention.
Parallel steps can be defined using `waitFor: ['-']` in the step configuration.
These come up on the exam all the time. Here's how to tell them apart.
Cloud Build
Fully managed, no infrastructure to maintain
Automatic scaling and high availability
Integrated with GCP services natively (Artifact Registry, Cloud Run, GKE)
Pay per build minute; no cost when idle
Limited to 10 concurrent builds by default (can increase)
Jenkins on Compute Engine
Self-managed, requires VM and storage provisioning
Manual scaling; can be complex to achieve HA
Requires plugins for GCP integration
Pay for VM 24/7 regardless of build usage
Highly customizable with plugins and shared libraries
Cloud Build with Cloud Run
Simpler deployment: `gcloud run deploy`
No cluster management; automatically scales to zero
Ideal for stateless HTTP services
Limited to container-based applications
Supports traffic splitting and revisions
Cloud Build with GKE
More complex: requires kubectl and cluster credentials
Full control over Kubernetes features (e.g., StatefulSets, CronJobs)
Can run stateful workloads with persistent volumes
Supports any containerized application
Requires cluster management and node scaling
Mistake
Cloud Build only works with Docker containers.
Correct
Cloud Build can execute any build step inside a container, but the steps themselves can run any command (e.g., compile C++, run shell scripts). The output can be any artifact, not just Docker images.
Mistake
The `images` field in cloudbuild.yaml automatically builds the Docker image.
Correct
The `images` field only specifies which images to push. You must still include a step that runs `docker build` (or use the implicit Docker build when no config file is provided).
Mistake
Cloud Build triggers can only be created for Cloud Source Repositories.
Correct
Triggers support GitHub, Bitbucket, GitLab, and Cloud Source Repositories. You can connect any of these by using the Cloud Build app or mirrored repositories.
Mistake
Build steps always run sequentially.
Correct
By default, steps run sequentially, but you can use `waitFor: ['-']` to run steps in parallel. You can also specify custom dependencies with `waitFor: ['step-id']`.
Mistake
Cloud Build service account has all necessary permissions by default.
Correct
The default Cloud Build service account (`[PROJECT_NUMBER]@cloudbuild.gserviceaccount.com`) has limited permissions. You must grant additional IAM roles (e.g., `container.deployer`, `run.admin`) for deployment steps.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
Use the `gcr.io/cloud-builders/gcloud` builder in a step with the `run deploy` command. For example: `steps: - name: 'gcr.io/cloud-builders/gcloud' args: ['run', 'deploy', 'my-service', '--image=gcr.io/$PROJECT_ID/my-image', '--region=us-central1', '--platform=managed']`. Ensure the Cloud Build service account has the `run.admin` IAM role on the project.
Yes. You can connect Cloud Build to a private GitHub repository by installing the Google Cloud Build app in your GitHub account or by mirroring the repository to Cloud Source Repositories. For the app method, you authorize Cloud Build to access your GitHub account and select specific repositories. Cloud Build will then create a webhook that triggers builds on push events.
`gcloud builds submit` is a manual command that uploads source code from your local machine or a Cloud Storage bucket and starts a build immediately. A trigger is a configuration that automatically starts a build when an event occurs in a connected repository (e.g., push to a branch, creation of a tag). Triggers are ideal for automation; `gcloud builds submit` is used for one-off builds or testing.
Use the `env` field in the step definition. Example: `steps: - name: 'gcr.io/cloud-builders/gcloud' env: - 'MY_VAR=hello' args: ['echo', '$MY_VAR']`. You can also use substitution variables like `$PROJECT_ID` directly in args. For sensitive data, use Cloud KMS to encrypt and decrypt the variable in a step.
The Cloud Build service account (`[PROJECT_NUMBER]@cloudbuild.gserviceaccount.com`) needs the `container.developer` IAM role on the GKE cluster to deploy resources. Grant this role via the GKE cluster's IAM page or using `gcloud projects add-iam-policy-binding`. Also ensure the service account has `container.cluster.getCredentials` permission to fetch the kubeconfig.
A private pool is a set of worker machines that run in your VPC network, allowing build steps to access private IP resources (e.g., on-premises databases, private GKE clusters). Use private pools when your build needs to interact with resources that are not publicly accessible. Private pools scale to zero when idle and can be configured with specific machine types and network settings.
Use the `artifacts` section in your `cloudbuild.yaml`. Example: `artifacts: objects: location: 'gs://my-bucket/artifacts/' paths: ['build/output/*.jar']`. This will upload files matching the paths to the specified Cloud Storage location after the build succeeds. You can also use `gsutil cp` in a step for more control.
You've just covered Cloud Build and CI/CD on GCP — now see how well it sticks with free ACE practice questions. Full explanations included, no account needed.
Done with this chapter?