PracticeVideosBlogFlashcards

11.2 Cloud Build Workers and Step Dependencies

Key Takeaways

  • waitFor omitted means all preceding steps; waitFor with a dash starts without dependencies.

  • Fan-in steps must reference every required independent predecessor.

  • A private pool alone does not bridge a second service peering to a private GKE control plane.

Last updated: October 2026

Continuous Integration Pipelines with Cloud Build

Modern cloud-native software delivery requires automated, repeatable, and scalable continuous integration (CI) pipelines. Cloud Build is Google Cloud's serverless continuous integration and continuous delivery (CI/CD) platform that executes build steps natively inside container environments. It scales elastically to handle high-concurrency build spikes without requiring developers to provision, patch, or maintain build servers.

For the Google Cloud Professional Cloud Developer exam, you must master Cloud Build architecture, pipeline syntax (cloudbuild.yaml), parallel execution and dependency modeling (waitFor), worker pool networking, variable substitutions, trigger automations, and service account security boundaries.


Cloud Build Architecture & Worker Pools

At its core, Cloud Build treats every operation in your pipeline as a container execution. A build consists of a sequence of build steps, where each step is invoked inside a dedicated container image. Cloud Build mounts a shared workspace directory across all steps at /workspace, enabling subsequent steps to inspect, modify, and consume artifacts generated by earlier steps.

Default Public Worker Pools vs. Private Worker Pools

When a build is initiated, Cloud Build routes execution to a Worker Pool. Google Cloud provides two fundamentally different worker pool architectures:

Architectural DimensionDefault Public Worker PoolPrivate Worker Pools
Hosting ModelMulti-tenant Google-managed environmentSingle-tenant dedicated worker instances
Network PlacementGoogle-owned VPC with direct public internet egressPeered to customer Virtual Private Cloud (VPC) via Private Service Access (PSA)
Private Network AccessCannot access RFC 1918 internal IPs or private VPC servicesConfigured private routes; other service peerings are not transitively reachable
VPC Service ControlsNot compliant with strict VPC Service Controls perimetersFully supported within VPC Service Controls (VPC-SC) perimeters
Static Egress IPsDynamic public IP addresses; cannot be whitelistedStatic egress needs the documented private-pool network/NAT architecture; simple peering alone does not make Cloud NAT transitive
Compute SizingStandard machine types (e2-standard-2 through e2-standard-32)Custom machine types, custom disk sizes (up to 4,000 GB), and customizable concurrency
Billing ModelBilled per build-minute consumedUsage-based build-time pricing by selected machine resources; not a permanently allocated idle VM fleet

Private Worker Pools in Enterprise Topologies

In secure enterprise architectures, workloads such as private Google Kubernetes Engine (GKE) control planes, private Cloud SQL instances, or internal artifact repositories disable public IP access entirely. If a pipeline running on the default public worker pool attempts to run kubectl apply against a private GKE cluster control plane (172.16.0.2), the operation fails with a network timeout.

To resolve this, developers configure a Private Worker Pool:

  1. A dedicated Service Networking connection (VPC Network Peering) is established between the customer VPC and the Google Services VPC.
  2. The Private Worker Pool is allocated a reserved internal IP range (/24 CIDR block) within the customer network.
  3. Cloud Build workers spin up inside this isolated network slice, with access limited to routes and DNS deliberately made reachable. VPC peering is non-transitive: a private GKE control plane or Cloud SQL reached through another service peering may require the documented VPN/proxy or other supported connectivity design.
## Creating a Private Worker Pool peered to a custom VPC network
gcloud builds worker-pools create enterprise-pool \
    --project=my-project-id \
    --region=us-central1 \
    --peered-network=projects/my-project-id/global/networks/production-vpc \
    --worker-machine-type=e2-standard-8 \
    --worker-disk-size=200GB \
    --no-external-ip-address

Anatomy of cloudbuild.yaml

A Cloud Build configuration file is written in YAML or JSON and defines the exact state machine of your pipeline. The primary building blocks include:

  • steps: An ordered list of containerized actions to execute.
  • name: The container image used to execute the step (the "builder").
  • args: Arguments passed directly to the container entrypoint.
  • entrypoint: Overrides the default ENTRYPOINT defined in the builder container image.
  • env: Environment variables injected into the step container.
  • dir: Working directory inside the container, relative to /workspace.
  • id: An optional unique string identifier for the step, used for dependency tracking.
  • waitFor: Controls step execution order and parallelization.
  • timeout: Maximum execution time for an individual step or the overall build.
  • secretEnv: Secret environment variables extracted securely from Secret Manager.

Directed Acyclic Graphs (DAGs) and Parallel Execution

By default, Cloud Build executes steps serially in the order they are listed in the YAML file. However, modern CI pipelines must run unit tests, security linters, static code analysis, and asset minification concurrently to minimize build duration.

Cloud Build supports arbitrary Directed Acyclic Graph (DAG) orchestration through the waitFor field:

  1. Sequential Default: If waitFor is omitted, the step waits for all preceding steps to complete successfully.
  2. Parallel Start (waitFor: ['-']): Setting waitFor: ['-'] instructs Cloud Build that this step has no dependencies and should begin execution immediately upon build start, concurrently with any other zero-dependency steps.
  3. Explicit Fan-In (waitFor: ['step-a', 'step-b']): A step will pause execution until all referenced step IDs have finished successfully.

Concrete Example: Parallel CI/CD Pipeline

steps:
  # Step 1: Run unit tests immediately in parallel
  - name: 'golang:1.26-bookworm'
    id: 'run-unit-tests'
    entrypoint: 'go'
    args: ['test', '-v', '-race', './...']
    waitFor: ['-']

  # Step 2: Run security linter immediately in parallel
  - name: 'securego/gosec:v2.22.0'
    id: 'run-security-linter'
    args: ['-exclude-dir=vendor', './...']
    waitFor: ['-']

  # Step 3: Build container image only after tests and lint pass
  - name: 'gcr.io/cloud-builders/docker'
    id: 'build-image'
    args:
      - 'build'
      - '-t'
      - 'us-central1-docker.pkg.dev/$PROJECT_ID/app-repo/payment-service:$SHORT_SHA'
      - '-t'
      - 'us-central1-docker.pkg.dev/$PROJECT_ID/app-repo/payment-service:latest'
      - '.'
    waitFor: ['run-unit-tests', 'run-security-linter']

  # Step 4: Push the tagged image to Artifact Registry
  - name: 'gcr.io/cloud-builders/docker'
    id: 'push-image'
    args:
      - 'push'
      - '--all-tags'
      - 'us-central1-docker.pkg.dev/$PROJECT_ID/app-repo/payment-service'
    waitFor: ['build-image']

  # Step 5: Deploy to Cloud Run using Secret Manager credential
  - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
    id: 'deploy-cloud-run'
    entrypoint: 'gcloud'
    args:
      - 'run'
      - 'deploy'
      - 'payment-service'
      - '--image=us-central1-docker.pkg.dev/$PROJECT_ID/app-repo/payment-service:$SHORT_SHA'
      - '--region=us-central1'
      - '--platform=managed'
      - '--set-env-vars=ENVIRONMENT=$_ENVIRONMENT'
    waitFor: ['push-image']

substitutions:
  _ENVIRONMENT: 'staging'

options:
  substitutionOption: 'ALLOW_LOOSE'
  logging: 'CLOUD_LOGGING_ONLY'
timeout: '1200s'

Official references checked October 18, 2026: Google Cloud 1, Google Cloud 2.

Test Your Knowledge

A development team is configuring a Cloud Build pipeline to deploy application manifests to a Google Kubernetes Engine (GKE) cluster. The cluster was created as a private cluster with private endpoint enabled and public master endpoint access disabled. When the pipeline runs 'kubectl apply', the build step fails with a connection timeout error. What architectural change resolves this issue while maintaining the cluster's private security posture?

A

Use a private pool and the documented private-GKE connectivity design (including VPN/routing where peering would otherwise be transitive), then run the build there

B

Grant the default Cloud Build service account the roles/container.admin IAM role in the host project

C

Configure 'waitFor: ['-']' on the kubectl build step to bypass public routing queues during execution

D

Add the substitutionOption: 'ALLOW_LOOSE' setting to cloudbuild.yaml to permit private IP address resolution

Test Your Knowledge

A developer needs to optimize a Cloud Build pipeline that currently runs sequentially: code checkout, backend unit tests, frontend unit tests, container image build, and deployment. The backend and frontend unit tests are completely independent of each other. How should the developer configure 'waitFor' in cloudbuild.yaml to run both test suites concurrently immediately upon build launch?

A

Combine both test commands into a single build step using a composite bash command with a single ampersand background operator

B

Set 'waitFor: ['-']' on both the backend test step and frontend test step, and set the container build step to wait for both test step IDs

C

Set 'parallelExecution: true' at the root level of cloudbuild.yaml and omit the 'id' field from all test steps

D

Define a custom substitution variable '_CONCURRENCY: 2' in the Cloud Build trigger configuration settings

Sections you finish are checked off in the contents.