Home โ€บ DevOps โ€บ Cloud Build: CI/CD Pipelines, Build Triggers, and Artifacts
Intermediate 5 min · July 12, 2026

Cloud Build: CI/CD Pipelines, Build Triggers, and Artifacts

A production-focused guide to Cloud Build: CI/CD Pipelines, Build Triggers, and Artifacts on Google Cloud Platform..

N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Everything here is grounded in real deployments.

Follow
Verified
production tested
July 12, 2026
last updated
2,073
articles · all by Naren
Before you start⏱ 25 min
  • Google Cloud account with billing enabled, gcloud CLI installed and configured, basic knowledge of Docker and CI/CD concepts, a source code repository (GitHub, GitLab, or Cloud Source Repositories), and permissions to create Cloud Build triggers and service accounts.
โœฆ Definition~90s read
What is Cloud Build (CI/CD)?

Cloud Build is a managed CI/CD service that automates building, testing, and deploying software on Google Cloud. It matters because it eliminates manual infrastructure management, scales automatically, and integrates natively with GCP services. Use it when you need a serverless, event-driven pipeline that triggers on code changes and produces deployable artifacts.

โ˜…
Cloud Build: CI/CD Pipelines, Build Triggers, and Artifacts is like having a specialized tool that handles cloud build so you don't have to build and manage it yourself โ€” it just works out of the box with Google Cloud's infrastructure.
Plain-English First

Cloud Build: CI/CD Pipelines, Build Triggers, and Artifacts is like having a specialized tool that handles cloud build so you don't have to build and manage it yourself โ€” it just works out of the box with Google Cloud's infrastructure.

⚙ Browser compatibility
Latest versions โ€” ✓ supported
ChromeFirefoxSafariEdge

Your production deployment just failed because the build pipeline silently skipped a failing test. The root cause? A misconfigured trigger that only ran on pushes to main, not on pull requests. Cloud Build promises simplicity, but without understanding its internals, you'll ship broken code. This isn't a tutorialโ€”it's a battle-tested guide to building CI/CD pipelines that don't lie. We'll cover triggers, artifact management, and the gotchas that cost teams hours of debugging. By the end, you'll know exactly how to set up a pipeline that catches failures before they hit production.

What Is Cloud Build?

Cloud Build is Google Cloud's managed CI/CD platform. It executes build steps in a containerized environment, pulling source from Cloud Source Repositories, GitHub, Bitbucket, or GitLab. Each step runs in a Docker container, and you define the pipeline in a cloudbuild.yaml file. Cloud Build is serverlessโ€”no VMs to manage, no cluster to scale. It integrates with Artifact Registry, Cloud Run, GKE, and other GCP services. Use it when you need a simple, event-driven pipeline that scales to zero when idle. But don't mistake simplicity for lack of depth: misconfigured triggers or missing artifacts can silently break your deployment.

cloudbuild.yamlYAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
steps:
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'us-central1-docker.pkg.dev/$PROJECT_ID/my-repo/my-image:$SHORT_SHA', '.']
- name: 'gcr.io/cloud-builders/docker'
  args: ['push', 'us-central1-docker.pkg.dev/$PROJECT_ID/my-repo/my-image:$SHORT_SHA']
- name: 'gcr.io/cloud-builders/kubectl'
  args: ['set', 'image', 'deployment/my-app', 'my-app=us-central1-docker.pkg.dev/$PROJECT_ID/my-repo/my-image:$SHORT_SHA']
  env:
  - 'CLOUDSDK_COMPUTE_ZONE=us-central1-a'
  - 'CLOUDSDK_CONTAINER_CLUSTER=my-cluster'
artifacts:
  objects:
    location: 'gs://my-bucket/build-artifacts/'
    paths: ['build-output/*']
Output
BUILD
Starting Step #0
Step #0: Already have image (with digest): gcr.io/cloud-builders/docker
Step #0: Step 1/3 : FROM node:18-alpine
Step #0: ---> abc123
Step #0: Successfully built def456
Step #0: Successfully tagged us-central1-docker.pkg.dev/my-project/my-repo/my-image:abc123
PUSH
Pushing us-central1-docker.pkg.dev/my-project/my-repo/my-image:abc123
...
๐Ÿ”ฅSubstitutions
Cloud Build provides built-in substitutions like $PROJECT_ID, $BUILD_ID, $SHORT_SHA. Use them to avoid hardcoding values.
๐Ÿ“Š Production Insight
Always pin your builder image versions (e.g., gcr.io/cloud-builders/docker:latest can break when Docker updates). Use a specific digest or version tag.
๐ŸŽฏ Key Takeaway
Cloud Build is a serverless CI/CD service that runs build steps in containers, defined in a cloudbuild.yaml file.
gcp-cloud-build THECODEFORGE.IO Cloud Build CI/CD Pipeline Flow Step-by-step automation from trigger to deployment Build Trigger Git push or PR event initiates pipeline Source Fetch Clone repository from Cloud Source Repositories Run Tests Execute unit and integration tests Build Docker Image Create container image with Cloud Build Push Artifact Store image in Artifact Registry Deploy to Cloud Run Deploy container to serverless platform โš  Missing build trigger configuration halts automation Always define triggers for each branch or tag pattern THECODEFORGE.IO
thecodeforge.io
Gcp Cloud Build

Build Triggers: Automating Your Pipeline

Build triggers automate pipeline execution based on events like pushes, pull requests, or tag creation. You can configure triggers via the Cloud Console, gcloud CLI, or Terraform. Each trigger points to a source repository and a cloudbuild.yaml file. Triggers support regex-based branch filtering, so you can run different pipelines for main vs. feature branches. A common mistake is forgetting to enable trigger on PRsโ€”without it, you won't catch failures until code is merged. Also, triggers can be paused or disabled, which is useful during maintenance but dangerous if forgotten.

create-trigger.shBASH
1
2
3
4
5
6
7
gcloud builds triggers create github \
  --name="my-app-trigger" \
  --repo-owner="my-org" \
  --repo-name="my-app" \
  --branch-pattern="^main$" \
  --build-config="cloudbuild.yaml" \
  --substitutions="_ENV=prod"
Output
Created trigger [my-app-trigger].
โš  Trigger on PRs
By default, triggers only run on pushes. To run on pull requests, add --pull-request-pattern="^main$" (or similar). Without it, PRs won't trigger builds.
๐Ÿ“Š Production Insight
We once had a trigger that only ran on pushes to main. A developer merged a PR with a failing test because the PR build was never triggered. Enable PR triggers with required status checks.
๐ŸŽฏ Key Takeaway
Build triggers automate pipeline execution based on source code events; configure them carefully to avoid silent failures.

Artifact Management: Storing Build Outputs

Artifacts are the outputs of your build processโ€”Docker images, compiled binaries, test reports, etc. Cloud Build can store artifacts in Cloud Storage or push images to Artifact Registry. Use the artifacts block in cloudbuild.yaml to specify which files to persist. Artifacts are essential for reproducibility: you can redeploy any past build by referencing its artifact. A common pitfall is not storing artifacts at all, making rollbacks impossible. Also, set lifecycle policies on your bucket to avoid runaway storage costs.

cloudbuild-artifacts.yamlYAML
1
2
3
4
5
6
7
8
9
steps:
- name: 'gcr.io/cloud-builders/go'
  args: ['build', '-o', 'build-output/myapp', '.']
artifacts:
  objects:
    location: 'gs://my-artifacts-bucket/$BUILD_ID/'
    paths: ['build-output/*']
  images:
  - 'us-central1-docker.pkg.dev/$PROJECT_ID/my-repo/my-image:$SHORT_SHA'
Output
BUILD
Step #0: go: downloading github.com/gorilla/mux v1.8.0
Step #0: go: downloading ...
Step #0: go: build completed
ARTIFACTS
Uploading build-output/myapp to gs://my-artifacts-bucket/abc123/build-output/myapp
Uploading image us-central1-docker.pkg.dev/my-project/my-repo/my-image:abc123
๐Ÿ’กLifecycle Policies
Set a lifecycle rule on your artifacts bucket to delete objects older than 30 days. This prevents cost bloat from forgotten builds.
๐Ÿ“Š Production Insight
We forgot to store artifacts for a critical build. When a deployment failed, we couldn't roll back to the previous version because the image was overwritten. Always push images with unique tags (e.g., commit SHA).
๐ŸŽฏ Key Takeaway
Artifacts store build outputs for reproducibility and rollback; always configure them and set lifecycle policies.
gcp-cloud-build THECODEFORGE.IO Cloud Build Architecture Layers Component hierarchy for CI/CD pipeline management Source Control Cloud Source Repositories | GitHub | Bitbucket Trigger Layer Push Trigger | PR Trigger | Schedule Trigger Build Service Cloud Build Worker | Build Config (cloudbuild.yaml) | Step Executor Artifact Storage Artifact Registry | Container Registry Deployment Targets Cloud Run | GKE | Compute Engine THECODEFORGE.IO
thecodeforge.io
Gcp Cloud Build

Building Docker Images Efficiently

Docker image builds are the most common Cloud Build step. To speed them up, use Docker layer caching. Cloud Build automatically caches layers from previous builds if you use the same builder image. However, the cache is per-host, and if your build runs on different hosts, you lose the cache. To mitigate, use Kaniko or build with --cache-from pointing to a previous image. Also, order your Dockerfile layers from least to most frequently changing to maximize cache hits. A typical mistake is installing dependencies before copying source, invalidating the cache on every change.

DockerfileDOCKERFILE
1
2
3
4
5
6
7
8
9
10
11
12
13
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/index.js"]
Output
Step 1/10 : FROM node:18-alpine AS builder
Step 2/10 : WORKDIR /app
Step 3/10 : COPY package*.json ./
Step 4/10 : RUN npm ci --only=production
---> Using cache
Step 5/10 : COPY . .
---> 123abc
Step 6/10 : RUN npm run build
---> Running in 456def
...
๐Ÿ’กMulti-stage Builds
Use multi-stage builds to keep final images small. The builder stage has all dev dependencies; the final stage only has runtime dependencies.
๐Ÿ“Š Production Insight
We had a Dockerfile that copied source before installing dependencies. Every code change invalidated the npm install cache, making builds 5 minutes longer. Reordering layers cut build time by 60%.
๐ŸŽฏ Key Takeaway
Optimize Docker builds by ordering layers correctly and leveraging caching; use multi-stage builds for smaller images.

Running Tests in the Pipeline

Tests should run as early as possible in your pipeline. Cloud Build supports running tests in parallel using step groups or by splitting steps across multiple containers. Use the waitFor field to control execution order. For unit tests, run them in a container that has your test framework. For integration tests, spin up a service (e.g., a test database) using a sidecar container. A common failure is not failing the build when tests failโ€”ensure your test command exits with a non-zero code. Also, store test reports as artifacts for debugging.

cloudbuild-test.yamlYAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
steps:
- name: 'node:18'
  entrypoint: 'npm'
  args: ['ci']
- name: 'node:18'
  entrypoint: 'npm'
  args: ['test']
  id: 'unit-tests'
- name: 'gcr.io/cloud-builders/docker'
  args: ['run', '-d', '--name=test-db', 'postgres:13']
  id: 'start-db'
- name: 'node:18'
  entrypoint: 'npm'
  args: ['run', 'test:integration']
  waitFor: ['unit-tests', 'start-db']
  env:
  - 'DATABASE_URL=postgres://user:pass@localhost:5432/test'
artifacts:
  objects:
    location: 'gs://my-artifacts-bucket/$BUILD_ID/'
    paths: ['test-results/*']
Output
Step #1: > my-app@1.0.0 test
Step #1: > jest
Step #1: PASS src/unit.test.js
Step #1: Tests: 1 passed, 1 total
Step #3: > my-app@1.0.0 test:integration
Step #3: PASS src/integration.test.js
Step #3: Tests: 1 passed, 1 total
โš  Exit Codes Matter
If your test runner exits with 0 even on failure (e.g., using --forceExit), Cloud Build won't fail. Always check that your test command returns non-zero on failure.
๐Ÿ“Š Production Insight
We once had a test that printed 'FAIL' but exited with 0 because of a misconfigured Jest reporter. The build passed, and broken code was deployed. Always verify exit codes.
๐ŸŽฏ Key Takeaway
Run tests early in the pipeline, fail the build on test failure, and store test reports as artifacts.

Deploying to Cloud Run

Cloud Run is a common deployment target for Cloud Build. After building and pushing a Docker image, use the gcloud builder to deploy. The deploy step requires the image URL and service name. Use substitutions to parameterize the service name and region. A common mistake is not specifying the region, causing the deployment to fail or deploy to the wrong region. Also, set concurrency and timeout flags to match your application needs. For zero-downtime deployments, Cloud Run handles traffic shifting automatically, but ensure your health checks pass.

cloudbuild-deploy.yamlYAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
steps:
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'us-central1-docker.pkg.dev/$PROJECT_ID/my-repo/my-image:$SHORT_SHA', '.']
- name: 'gcr.io/cloud-builders/docker'
  args: ['push', 'us-central1-docker.pkg.dev/$PROJECT_ID/my-repo/my-image:$SHORT_SHA']
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
  entrypoint: 'gcloud'
  args: ['run', 'deploy', 'my-service',
         '--image=us-central1-docker.pkg.dev/$PROJECT_ID/my-repo/my-image:$SHORT_SHA',
         '--region=us-central1',
         '--platform=managed',
         '--allow-unauthenticated',
         '--concurrency=80',
         '--timeout=300']
Output
Deploying container to Cloud Run service [my-service] in project [my-project] region [us-central1]
โœ“ Deploying... Done.
โœ“ Creating Revision... Revision deployment finished.
โœ“ Routing traffic...
โœ“ Setting IAM Policy...
Done.
Service [my-service] revision [my-service-00001] has been deployed and is serving 100 percent of traffic.
๐Ÿ”ฅTraffic Splitting
Cloud Run supports gradual traffic rollout. Use --no-traffic during deploy, then gcloud run services update-traffic to shift traffic gradually.
๐Ÿ“Š Production Insight
We once deployed without specifying --region, and gcloud defaulted to a different region. The service was unreachable for 10 minutes. Always explicitly set region.
๐ŸŽฏ Key Takeaway
Deploy to Cloud Run using the gcloud builder; parameterize region and service name, and ensure health checks pass.

Deploying to Google Kubernetes Engine (GKE)

For GKE deployments, Cloud Build can update a Kubernetes deployment using kubectl. You need to authenticate to the cluster using the gcloud container clusters get-credentials command. Then use kubectl set image to update the deployment. A common pitfall is not having the correct IAM permissionsโ€”the Cloud Build service account needs permissions to access the cluster. Also, consider using Helm or Kustomize for more complex deployments. For production, use a rolling update strategy to minimize downtime.

cloudbuild-gke.yamlYAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
steps:
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'us-central1-docker.pkg.dev/$PROJECT_ID/my-repo/my-image:$SHORT_SHA', '.']
- name: 'gcr.io/cloud-builders/docker'
  args: ['push', 'us-central1-docker.pkg.dev/$PROJECT_ID/my-repo/my-image:$SHORT_SHA']
- name: 'gcr.io/cloud-builders/kubectl'
  args:
  - 'set'
  - 'image'
  - 'deployment/my-app'
  - 'my-app=us-central1-docker.pkg.dev/$PROJECT_ID/my-repo/my-image:$SHORT_SHA'
  env:
  - 'CLOUDSDK_COMPUTE_ZONE=us-central1-a'
  - 'CLOUDSDK_CONTAINER_CLUSTER=my-cluster'
Output
deployment.apps/my-app image updated
โš  IAM Permissions
The Cloud Build service account (service-<PROJECT_NUMBER>@gcp-sa-cloudbuild.iam.gserviceaccount.com) needs roles/container.developer to update deployments. Grant it explicitly.
๐Ÿ“Š Production Insight
We forgot to grant the Cloud Build SA container.developer role. The deploy step failed silently because kubectl returned a permission error. Always test the deploy step in a non-prod cluster first.
๐ŸŽฏ Key Takeaway
Deploy to GKE by authenticating to the cluster and using kubectl; ensure proper IAM permissions and use rolling updates.

Secrets and Environment Variables

Never hardcode secrets in cloudbuild.yaml. Use Cloud Secret Manager to store sensitive data like API keys or database passwords. Access secrets via the availableSecrets block, which injects them as environment variables or volumes. For environment variables that are not secrets, use substitutions or the env field. A common mistake is using substitutions for secretsโ€”substitutions are visible in build logs. Always use Secret Manager for anything sensitive. Also, limit the scope of secrets to only the steps that need them.

cloudbuild-secrets.yamlYAML
1
2
3
4
5
6
7
8
9
10
11
12
steps:
- name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
    echo "$$DB_PASSWORD" > /tmp/db_password
  secretEnv: ['DB_PASSWORD']
availableSecrets:
  secretManager:
  - versionName: projects/$PROJECT_ID/secrets/DB_PASSWORD/versions/latest
    env: 'DB_PASSWORD'
Output
Step #0: (no output, secret is not printed)
โš  Substitutions Are Visible
Substitutions like $_PASSWORD are printed in build logs if used in args. Never use substitutions for secrets. Use Secret Manager instead.
๐Ÿ“Š Production Insight
A team used a substitution for a database password. The password appeared in build logs, which were accessible to all project members. They had to rotate credentials and switch to Secret Manager.
๐ŸŽฏ Key Takeaway
Use Cloud Secret Manager for secrets; never hardcode or use substitutions for sensitive data.

Parallelism and Step Dependencies

Cloud Build runs steps sequentially by default. To speed up pipelines, run independent steps in parallel using the waitFor field. Set waitFor: ['step-name'] to make a step wait for another. Use '-' to indicate no dependency (runs immediately). You can also use step groups (not natively supported, but you can simulate with multiple steps). A common mistake is not setting waitFor correctly, causing steps to run out of order. For example, tests should wait for the build step. Also, consider using build timeouts to prevent runaway builds.

cloudbuild-parallel.yamlYAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
steps:
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'my-image', '.']
  id: 'build'
- name: 'node:18'
  entrypoint: 'npm'
  args: ['test']
  waitFor: ['build']
  id: 'unit-tests'
- name: 'gcr.io/cloud-builders/docker'
  args: ['run', 'my-image', 'npm', 'run', 'test:integration']
  waitFor: ['build']
  id: 'integration-tests'
- name: 'gcr.io/cloud-builders/gcloud'
  args: ['run', 'deploy', 'my-service', '--image=my-image']
  waitFor: ['unit-tests', 'integration-tests']
Output
Step #0: build
Step #1: unit-tests (runs in parallel with integration-tests)
Step #2: integration-tests
Step #3: deploy (waits for both tests)
๐Ÿ’กTimeout
Set a global timeout in cloudbuild.yaml: timeout: '1200s'. This prevents builds from running indefinitely if a step hangs.
๐Ÿ“Š Production Insight
We had a pipeline that ran unit tests and integration tests sequentially, taking 15 minutes. By running them in parallel, we cut build time to 8 minutes. Faster feedback means faster iteration.
๐ŸŽฏ Key Takeaway
Use waitFor to run independent steps in parallel, reducing total build time.

Monitoring and Logging Builds

Cloud Build logs are automatically sent to Cloud Logging. You can view them in the Console or export to BigQuery for analysis. Set up alerts for build failures using Cloud Monitoring. A common mistake is not monitoring build durationโ€”if builds start taking longer, it could indicate a problem (e.g., cache invalidation). Also, use build status notifications via Pub/Sub to trigger downstream actions (e.g., notify Slack). For debugging, enable verbose logging by setting _CLOUD_BUILD_LOGGING=verbose substitution.

create-alert.shBASH
1
2
gcloud alpha monitoring policies create \
  --policy-from-file=build-failure-policy.yaml
Output
Created alert policy [projects/my-project/alertPolicies/123456].
๐Ÿ”ฅPub/Sub Notifications
Cloud Build can publish build status updates to a Pub/Sub topic. Use this to trigger Slack notifications or other automations.
๐Ÿ“Š Production Insight
We didn't monitor build duration. Over time, builds crept from 5 to 20 minutes due to cache misses. Setting up a dashboard alerted us to the regression, and we fixed the caching strategy.
๐ŸŽฏ Key Takeaway
Monitor build logs and set up alerts for failures; use Pub/Sub for notifications.

Cost Optimization

Cloud Build charges per build minute, with a free tier of 120 build-minutes per day. To optimize costs, use smaller machine types (e.g., e2-standard-2 instead of e2-standard-8) if your build doesn't need many cores. Also, cache aggressively to reduce build time. Use Kaniko for faster image builds. Set lifecycle policies on artifact buckets to delete old artifacts. A common mistake is leaving unused triggers activeโ€”they still incur costs if triggered. Disable or delete triggers for archived repositories.

cloudbuild-cost.yamlYAML
1
2
3
4
5
6
7
8
steps:
- name: 'gcr.io/kaniko-project/executor:latest'
  args:
  - --destination=us-central1-docker.pkg.dev/$PROJECT_ID/my-repo/my-image:$SHORT_SHA
  - --cache=true
  - --cache-ttl=24h
options:
  machineType: 'E2_HIGHCPU_8'
Output
INFO[0000] Resolved base name node:18-alpine to node:18-alpine
INFO[0000] Cached from previous build, skipping layer: abc123
...
๐Ÿ’กFree Tier
Each day you get 120 build-minutes free. For a typical 5-minute build, that's 24 builds per day. Monitor usage to avoid surprises.
๐Ÿ“Š Production Insight
We had a trigger on a repo that was archived but still active. It triggered on every push to a fork, costing $50/month. Delete or disable triggers for inactive repos.
๐ŸŽฏ Key Takeaway
Optimize costs by using smaller machines, caching, and cleaning up old artifacts and unused triggers.

Cloud Deploy Integration: From CI to CD Without the Gap

Cloud Build handles CI (build, test, package). Cloud Deploy handles CD (progressive delivery, promotion, rollback). Together they form a complete CI/CD pipeline. After a successful build, Cloud Build creates a Cloud Deploy release, specifying the image digest. Cloud Deploy then progresses the release through targets (dev -> staging -> prod) with promotion gates, approval requirements, and canary strategies. Cloud Deploy uses Skaffold under the hood to render Kubernetes manifests or Cloud Run YAML with the correct image digest. You define targets with optional approval requirements and deployment strategies (standard, canary with phased percentage rollouts, or blue-green). Promotion can be automated or require manual approval. A key advantage: the same artifact built once in Cloud Build is deployed to every environment, eliminating 'works on my machine' issues. For production, combine Cloud Deploy's canary deployment with Binary Authorization to ensure only attested images are deployed. In production, we use Cloud Build + Cloud Deploy for a 4-environment pipeline: dev (auto-promote), staging (auto-promote after tests), pre-prod (manual approval), prod (canary 25% -> 50% -> 100% with auto-rollback on failure).

clouddeploy.yamlYAML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
apiVersion: deploy.cloud.google.com/v1
kind: DeliveryPipeline
metadata:
  name: app-pipeline
serialPipeline:
  stages:
  - targetId: dev
    profiles: ["dev"]
    strategy:
      standard:
        verify: false
  - targetId: staging
    profiles: ["staging"]
    strategy:
      standard:
        verify: true
  - targetId: prod
    profiles: ["prod"]
    strategy:
      canary:
        canaryDeployment:
          percentages: [25, 50, 100]
          verify: true
---
apiVersion: deploy.cloud.google.com/v1
kind: Target
metadata:
  name: prod
description: production cluster
requireApproval: true
gke:
  cluster: projects/my-project/locations/us-central1/clusters/prod-cluster
Output
Delivery pipeline created with dev -> staging -> prod targets. Production requires approval and uses canary deployment.
๐Ÿ’กBuild Once, Deploy Everywhere
Pass the immutable image digest from Cloud Build to Cloud Deploy. Never rebuild for different environments โ€” this guarantees deployment consistency.
๐Ÿ“Š Production Insight
Our canary deployment caught a performance regression at 25% traffic โ€” the canary showed elevated p99 latency within 2 minutes. Cloud Deploy auto-rolled back before 100% of users were affected.
๐ŸŽฏ Key Takeaway
Cloud Build + Cloud Deploy form a complete CI/CD pipeline with progressive delivery, approval gates, and rollback.
Cloud Build vs Jenkins for CI/CD Trade-offs between managed and self-hosted pipelines Cloud Build Jenkins Setup Complexity Minimal, fully managed Requires server and plugin configuration Scaling Automatic, pay per use Manual scaling with agents Integration with GCP Native, seamless Requires plugins and custom scripts Customization Limited to build steps Highly extensible via plugins Cost Model Pay per build minute Server costs plus maintenance THECODEFORGE.IO
thecodeforge.io
Gcp Cloud Build

Private Pools and Approval Gates: Security for Enterprise Pipelines

By default, Cloud Build runs on shared Google-managed infrastructure. For compliance requirements (accessing private VPC resources, no public internet exposure, static IP for egress), use private pools. A private pool runs in your VPC, with worker VMs that can reach Cloud SQL, GKE clusters, or internal services without traversing the internet. Private pools also support static egress IPs for integrations that require IP allowlisting. Create a private pool with gcloud builds worker-pools create specifying the VPC network and subnet. Builds using the pool are billed at the pool's machine type rates. For additional security, Cloud Build supports approval gates on triggers: when enabled, triggered builds enter a PENDING_APPROVAL state until a user with cloudbuild.approver role explicitly approves or rejects them. This is useful for production deployments where you want a human in the loop without giving everyone trigger-edit permissions. In production, we use private pools for all builds that access private Artifact Registry or internal test databases, and approval gates on production deployment triggers.

private_pool.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Create a private pool in your VPC
gcloud builds worker-pools create my-private-pool \
  --region=us-central1 \
  --peered-network=projects/my-project/global/networks/default \
  --worker-machine-type=e2-standard-4 \
  --worker-disk-size=100

# Create a trigger that uses the private pool
gcloud builds triggers create github \
  --name="private-ci" \
  --repo-owner="my-org" \
  --repo-name="my-app" \
  --branch-pattern="^main$" \
  --build-config="cloudbuild.yaml" \
  --worker-pool=projects/my-project/locations/us-central1/workerPools/my-private-pool
Output
Created private pool [my-private-pool].
Created trigger [private-ci] using private pool.
โš  Private Pool Costs
Private pools charge for allocated workers even when idle. Use the '--min-workers=0' flag to scale to zero, but expect cold start delays when workers spin up.
๐Ÿ“Š Production Insight
We set up approval gates for production Cloud Run deployments. A junior engineer accidentally triggered a prod deploy from a feature branch โ€” but the build sat in PENDING_APPROVAL until we reviewed and rejected it. Saved a potential outage.
๐ŸŽฏ Key Takeaway
Private pools provide VPC access and static IP for enterprise compliance; approval gates add human-in-the-loop security.
⚙ Quick Reference
13 commands from this guide
FileCommand / CodePurpose
cloudbuild.yamlsteps:What Is Cloud Build?
create-trigger.shgcloud builds triggers create github \Build Triggers
cloudbuild-artifacts.yamlsteps:Artifact Management
DockerfileFROM node:18-alpine AS builderBuilding Docker Images Efficiently
cloudbuild-test.yamlsteps:Running Tests in the Pipeline
cloudbuild-deploy.yamlsteps:Deploying to Cloud Run
cloudbuild-gke.yamlsteps:Deploying to Google Kubernetes Engine (GKE)
cloudbuild-secrets.yamlsteps:Secrets and Environment Variables
cloudbuild-parallel.yamlsteps:Parallelism and Step Dependencies
create-alert.shgcloud alpha monitoring policies create \Monitoring and Logging Builds
cloudbuild-cost.yamlsteps:Cost Optimization
clouddeploy.yamlapiVersion: deploy.cloud.google.com/v1Cloud Deploy Integration
private_pool.shgcloud builds worker-pools create my-private-pool \Private Pools and Approval Gates

Key takeaways

1
Serverless CI/CD
Cloud Build is a managed, serverless CI/CD service that runs build steps in containers, defined in a cloudbuild.yaml file.
2
Triggers Matter
Build triggers automate pipeline execution; configure them for both pushes and pull requests to catch failures early.
3
Artifacts for Rollback
Always store build artifacts (images, binaries) with unique tags to enable rollbacks and reproducibility.
4
Secrets Management
Use Cloud Secret Manager for secrets; never hardcode or use substitutions for sensitive data.

Common mistakes to avoid

3 patterns
×

Ignoring gcp cloud build best practices

Symptom
Production incidents and unexpected behavior
Fix
Follow GCP documentation and implement proper monitoring and testing
×

Over-provisioning without rightsizing analysis

Symptom
Wasted cloud spend and poor resource utilization
Fix
Use committed use discounts and rightsize based on actual usage metrics
×

Skipping IAM least-privilege principles

Symptom
Security vulnerabilities and compliance violations
Fix
Implement custom roles with minimum required permissions and use conditions
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
What is Cloud Build: CI/CD Pipelines, Build Triggers, and Artifacts and ...
Q02SENIOR
How do you configure Cloud Build: CI/CD Pipelines, Build Triggers, and A...
Q03SENIOR
What are the cost optimization strategies for Cloud Build: CI/CD Pipelin...
Q01 of 03JUNIOR

What is Cloud Build: CI/CD Pipelines, Build Triggers, and Artifacts and when would you use it in production?

ANSWER
Cloud Build: CI/CD Pipelines, Build Triggers, and Artifacts is a Google Cloud service for managing infrastructure efficiently. It's ideal for organizations needing scalable, reliable cloud solutions. Use it when you need automated management and consistent performance across your GCP projects.
FAQ · 6 QUESTIONS

Frequently Asked Questions

01
How do I run a build locally for testing?
02
Can I use Cloud Build with GitLab or Bitbucket?
03
How do I pass variables between steps?
04
What is the difference between Cloud Build and Jenkins?
05
How do I handle secrets in Cloud Build?
06
Why is my build failing with 'permission denied'?
N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Everything here is grounded in real deployments.

Follow
Verified
production tested
July 12, 2026
last updated
2,073
articles · all by Naren
🔥

That's Google Cloud. Mark it forged?

5 min read · try the examples if you haven't

Previous
Organization Policies
43 / 55 · Google Cloud
Next
Artifact Registry