GCP Cloud Build and CI/CD
Cloud Build is GCP's fully managed CI/CD (Continuous Integration and Continuous Deployment) service. It automatically builds, tests, and deploys application code whenever a change is pushed to a source repository. Cloud Build eliminates manual deployment steps and ensures every code change is tested before reaching production.
Imagine a car factory assembly line. A worker places raw materials at one end (code commit). The line automatically welds, paints, checks quality, and produces a finished car (deployed application) at the other end — without anyone manually running each step. Cloud Build is that assembly line for software.
CI/CD Concepts
| Term | Definition | Example |
|---|---|---|
| Continuous Integration (CI) | Automatically build and test code on every commit | Run unit tests when a developer pushes code |
| Continuous Delivery (CD) | Automatically prepare code for deployment after CI passes | Build a container image after tests pass |
| Continuous Deployment | Automatically deploy to production after CD passes | Push container to Cloud Run automatically |
Cloud Build Architecture
Developer pushes code to GitHub / Cloud Source Repositories
│
▼
Cloud Build Trigger fires
│
▼
Cloud Build (runs steps defined in cloudbuild.yaml)
│
├── Step 1: Install dependencies (npm install / pip install)
├── Step 2: Run unit tests
├── Step 3: Build container image (docker build)
├── Step 4: Push image to Artifact Registry
└── Step 5: Deploy to Cloud Run / GKE / App Engine
│
▼
Application is live in production ✓
The cloudbuild.yaml File
Every Cloud Build pipeline is defined by a cloudbuild.yaml file in the root of the repository. Each step in the file runs a Docker container to execute a command.
Example – Python App: Test, Build, Deploy to Cloud Run
# cloudbuild.yaml
steps:
# Step 1 — Run unit tests
- name: 'python:3.11'
entrypoint: 'bash'
args:
- '-c'
- |
pip install -r requirements.txt
python -m pytest tests/ -v
# Step 2 — Build the Docker container image
- name: 'gcr.io/cloud-builders/docker'
args:
- 'build'
- '-t'
- 'us-central1-docker.pkg.dev/my-project/my-repo/my-app:$COMMIT_SHA'
- '.'
# Step 3 — Push image to Artifact Registry
- name: 'gcr.io/cloud-builders/docker'
args:
- 'push'
- 'us-central1-docker.pkg.dev/my-project/my-repo/my-app:$COMMIT_SHA'
# Step 4 — Deploy to Cloud Run
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
args:
- 'gcloud'
- 'run'
- 'deploy'
- 'my-app'
- '--image=us-central1-docker.pkg.dev/my-project/my-repo/my-app:$COMMIT_SHA'
- '--region=us-central1'
- '--allow-unauthenticated'
# Store the built image in Artifact Registry
images:
- 'us-central1-docker.pkg.dev/my-project/my-repo/my-app:$COMMIT_SHA'
Built-in substitution variables available in every build:
| Variable | Value |
|---|---|
| $PROJECT_ID | The GCP project ID |
| $COMMIT_SHA | The Git commit hash (first 7 characters) |
| $BRANCH_NAME | The Git branch name |
| $SHORT_SHA | Short version of the commit hash |
| $REPO_NAME | The source repository name |
Cloud Build Triggers
A trigger automatically starts a build when specific events happen in a source repository.
# Create a trigger that runs on every push to the main branch gcloud builds triggers create github \ --repo-name=my-app \ --repo-owner=my-github-username \ --branch-pattern="^main$" \ --build-config=cloudbuild.yaml
Common trigger configurations:
- Push to branch: Build runs when code is pushed to a specific branch (e.g.,
main,production) - Push to any branch: Build runs on every push to any branch
- Pull request: Build runs when a pull request is opened or updated (for testing before merge)
- Tag push: Build runs when a Git tag is pushed (e.g.,
v1.0.0for releases)
Artifact Registry
Artifact Registry is GCP's managed repository for storing build artifacts — container images, Maven packages, npm packages, and Python wheels. It replaces the older Container Registry.
# Create a Docker repository in Artifact Registry gcloud artifacts repositories create my-repo \ --repository-format=docker \ --location=us-central1 # Configure Docker to authenticate with Artifact Registry gcloud auth configure-docker us-central1-docker.pkg.dev # Push an image docker push us-central1-docker.pkg.dev/my-project/my-repo/my-app:latest # Pull an image docker pull us-central1-docker.pkg.dev/my-project/my-repo/my-app:latest
Multi-Environment Pipeline
A professional CI/CD setup typically deploys to multiple environments based on the Git branch:
Git Branches and Environments: ┌─────────────────────────────────────────────────────────┐ │ │ │ feature/* branch │ │ → Build + Test only (no deployment) │ │ │ │ develop branch │ │ → Build + Test + Deploy to DEV environment │ │ │ │ staging branch │ │ → Build + Test + Deploy to STAGING environment │ │ │ │ main/production branch │ │ → Build + Test + Deploy to PRODUCTION environment │ │ │ └─────────────────────────────────────────────────────────┘
Branch-Based Deployment in cloudbuild.yaml
steps:
- name: 'python:3.11'
entrypoint: bash
args: ['-c', 'pip install -r requirements.txt && pytest tests/']
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/$PROJECT_ID/my-app:$COMMIT_SHA', '.']
# Deploy to staging (only on the staging branch)
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
entrypoint: bash
args:
- '-c'
- |
if [[ "$BRANCH_NAME" == "staging" ]]; then
gcloud run deploy my-app-staging \
--image=gcr.io/$PROJECT_ID/my-app:$COMMIT_SHA \
--region=us-central1
fi
# Deploy to production (only on the main branch)
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
entrypoint: bash
args:
- '-c'
- |
if [[ "$BRANCH_NAME" == "main" ]]; then
gcloud run deploy my-app-prod \
--image=gcr.io/$PROJECT_ID/my-app:$COMMIT_SHA \
--region=us-central1
fi
Running a Build Manually
# Trigger a build manually from the current directory gcloud builds submit --config=cloudbuild.yaml . # Trigger a build with custom substitutions gcloud builds submit --config=cloudbuild.yaml \ --substitutions=_ENV=staging,_VERSION=1.2.0 .
Key Takeaways
- Cloud Build automates building, testing, and deploying applications on every code commit.
- The
cloudbuild.yamlfile defines the pipeline steps — each step runs in a Docker container. - Triggers connect a Git repository event (push, pull request) to a build pipeline.
- Artifact Registry stores container images and other build outputs securely.
- Multi-environment pipelines use Git branches to control which environment receives a deployment.
- Built-in variables like
$COMMIT_SHAenable traceable, versioned deployments.
