Available for day contractsFrom 21st September I have availability for day and half day contracts. Please contact for more information.

Contact →
mikepreston.org

Google Cloud Platform (GCP)

Essential gcloud CLI commands and GCP service patterns for compute, storage, networking, and serverless workloads.

Google Cloud Platform (GCP)

Essential gcloud CLI commands and GCP service patterns for compute, storage, networking, and serverless workloads.

Overview

Google Cloud Platform provides a suite of cloud computing services for infrastructure, platform, and serverless workloads. GCP excels in data analytics, machine learning, and Kubernetes-native services, with strong integration across its ecosystem.

GCP Core ServicesCI/CDIdentityNetworkingStorageComputeCloud BuildVPC NetworkCompute EngineGKECloud RunIAMCloud FunctionsService AccountsCloud StorageArtifact RegistryLoad BalancerCloud CDNPersistent DiskFilestoreGCP Core ServicesCI/CDIdentityNetworkingStorageComputeCloud BuildVPC NetworkCompute EngineGKECloud RunIAMCloud FunctionsService AccountsCloud StorageArtifact RegistryLoad BalancerCloud CDNPersistent DiskFilestore

gcloud CLI Essentials

The gcloud command-line tool is the primary interface for managing GCP resources.

Installation and Setup

# Install gcloud CLI (Debian/Ubuntu)
curl https://sdk.cloud.google.com | bash
exec -l $SHELL

# Initialise gcloud (interactive setup)
gcloud init

# Authenticate with your Google account
gcloud auth login

# Set application default credentials (for local development)
gcloud auth application-default login

Configuration Management

# View current configuration
gcloud config list

# Set default project
gcloud config set project my-project-id

# Set default region and zone
gcloud config set compute/region europe-west2
gcloud config set compute/zone europe-west2-a

# Create named configuration
gcloud config configurations create dev-config
gcloud config configurations activate dev-config

# List all configurations
gcloud config configurations list

# View specific property
gcloud config get-value project
gcloud config get-value compute/zone

Common gcloud Patterns

# List available projects
gcloud projects list

# Get current project
gcloud config get-value project

# Enable APIs
gcloud services enable compute.googleapis.com
gcloud services enable container.googleapis.com
gcloud services enable cloudfunctions.googleapis.com
gcloud services enable run.googleapis.com
gcloud services enable cloudbuild.googleapis.com

# List enabled APIs
gcloud services list --enabled

# Format output as JSON or table
gcloud compute instances list --format=json
gcloud compute instances list --format="table(name,zone,status)"

# Filter results
gcloud compute instances list --filter="status=RUNNING"
gcloud compute instances list --filter="zone:europe-west2-a"

Compute Engine

Virtual machines on Google's infrastructure with flexible machine types and configurations.

Creating Instances

# Create a basic VM instance
gcloud compute instances create my-vm \
    --zone=europe-west2-a \
    --machine-type=e2-medium \
    --image-family=debian-12 \
    --image-project=debian-cloud

# Create with specific boot disk size
gcloud compute instances create my-vm \
    --zone=europe-west2-a \
    --machine-type=e2-standard-4 \
    --boot-disk-size=50GB \
    --boot-disk-type=pd-ssd \
    --image-family=ubuntu-2204-lts \
    --image-project=ubuntu-os-cloud

# Create with startup script
gcloud compute instances create my-vm \
    --zone=europe-west2-a \
    --machine-type=e2-medium \
    --metadata-from-file=startup-script=startup.sh \
    --image-family=debian-12 \
    --image-project=debian-cloud

# Create with service account
gcloud compute instances create my-vm \
    --zone=europe-west2-a \
    --machine-type=e2-medium \
    --service-account=my-sa@my-project.iam.gserviceaccount.com \
    --scopes=cloud-platform \
    --image-family=debian-12 \
    --image-project=debian-cloud

# Create Spot instance for cost savings (Spot VMs supersede preemptible VMs)
gcloud compute instances create my-vm \
    --zone=europe-west2-a \
    --machine-type=e2-medium \
    --provisioning-model=SPOT \
    --instance-termination-action=STOP \
    --image-family=debian-12 \
    --image-project=debian-cloud

Machine Types

# List available machine types in a zone
gcloud compute machine-types list --zones=europe-west2-a

# Filter by specific family
gcloud compute machine-types list \
    --zones=europe-west2-a \
    --filter="name~^e2"

# Common machine type families:
# e2-*        - Cost-optimised, general purpose
# n2-*        - Balanced price/performance
# n2d-*      - AMD-based, cost-effective
# c2-*        - Compute-optimised
# m3-*, m4-*  - Memory-optimised (M1/M2 are older generations)
# a2-*        - GPU-attached (accelerator-optimised)

# Describe a specific machine type
gcloud compute machine-types describe e2-standard-4 \
    --zone=europe-west2-a

SSH and Instance Access

# SSH into an instance
gcloud compute ssh my-vm --zone=europe-west2-a

# SSH with specific user
gcloud compute ssh user@my-vm --zone=europe-west2-a

# SSH with port forwarding
gcloud compute ssh my-vm --zone=europe-west2-a \
    -- -L 8080:localhost:80

# SSH through IAP (Identity-Aware Proxy) tunnel
gcloud compute ssh my-vm --zone=europe-west2-a --tunnel-through-iap

# Copy files to instance
gcloud compute scp local-file.txt my-vm:~/remote-file.txt \
    --zone=europe-west2-a

# Copy files from instance
gcloud compute scp my-vm:~/remote-file.txt ./local-file.txt \
    --zone=europe-west2-a

# Copy directory recursively
gcloud compute scp --recurse local-dir my-vm:~/remote-dir \
    --zone=europe-west2-a

# Run command on instance
gcloud compute ssh my-vm --zone=europe-west2-a \
    --command="sudo apt-get update && sudo apt-get upgrade -y"

Managing Instances

# List all instances
gcloud compute instances list

# Describe an instance
gcloud compute instances describe my-vm --zone=europe-west2-a

# Stop an instance
gcloud compute instances stop my-vm --zone=europe-west2-a

# Start an instance
gcloud compute instances start my-vm --zone=europe-west2-a

# Delete an instance
gcloud compute instances delete my-vm --zone=europe-west2-a

# Resize machine type (requires stop first)
gcloud compute instances stop my-vm --zone=europe-west2-a
gcloud compute instances set-machine-type my-vm \
    --zone=europe-west2-a \
    --machine-type=e2-standard-4
gcloud compute instances start my-vm --zone=europe-west2-a

# Add metadata
gcloud compute instances add-metadata my-vm \
    --zone=europe-west2-a \
    --metadata=key=value

Snapshots and Images

# Create a snapshot of a disk
gcloud compute disks snapshot my-vm \
    --zone=europe-west2-a \
    --snapshot-names=my-vm-snapshot

# List snapshots
gcloud compute snapshots list

# Create disk from snapshot
gcloud compute disks create new-disk \
    --zone=europe-west2-a \
    --source-snapshot=my-vm-snapshot

# Create custom image from disk
gcloud compute images create my-image \
    --source-disk=my-vm \
    --source-disk-zone=europe-west2-a

# Create image from snapshot
gcloud compute images create my-image \
    --source-snapshot=my-vm-snapshot

# List custom images
gcloud compute images list --no-standard-images

# Delete a snapshot
gcloud compute snapshots delete my-vm-snapshot

Cloud Storage

Object storage for any amount of data with global edge caching.

gcloud storage Basics

gcloud storage is the recommended CLI for Cloud Storage; the older gsutil tool is legacy and only minimally maintained, though its commands map almost one-to-one (e.g. gsutil cp → gcloud storage cp).

# Create a bucket (names must be globally unique)
gcloud storage buckets create gs://my-unique-bucket-name

# Create bucket in specific location
gcloud storage buckets create gs://my-bucket --location=europe-west2

# Create bucket with storage class
gcloud storage buckets create gs://my-bucket \
    --location=europe-west2 \
    --default-storage-class=standard
# Storage classes: standard, nearline, coldline, archive

# List buckets
gcloud storage ls

# List objects in bucket
gcloud storage ls gs://my-bucket
gcloud storage ls -l gs://my-bucket  # Long listing with sizes
gcloud storage ls -r gs://my-bucket  # Recursive listing

Upload and Download

# Upload a file
gcloud storage cp local-file.txt gs://my-bucket/

# Upload with specific name
gcloud storage cp local-file.txt gs://my-bucket/remote-name.txt

# Upload directory recursively
gcloud storage cp -r local-dir gs://my-bucket/

# Uploads are parallelised automatically (no -m flag needed)

# Download a file
gcloud storage cp gs://my-bucket/file.txt ./

# Download directory
gcloud storage cp -r gs://my-bucket/folder ./

# Sync local directory to bucket
gcloud storage rsync -r local-dir gs://my-bucket/remote-dir

# Sync bucket to local directory
gcloud storage rsync -r gs://my-bucket/remote-dir local-dir

# Sync with delete (mirror)
gcloud storage rsync -r --delete-unmatched-destination-objects \
    local-dir gs://my-bucket/remote-dir

Object Management

# Copy between buckets
gcloud storage cp gs://source-bucket/file.txt gs://dest-bucket/

# Move/rename object
gcloud storage mv gs://my-bucket/old-name.txt gs://my-bucket/new-name.txt

# Delete object
gcloud storage rm gs://my-bucket/file.txt

# Delete all objects in a folder
gcloud storage rm -r gs://my-bucket/folder/

# Delete bucket (must be empty)
gcloud storage buckets delete gs://my-bucket

# Force delete bucket and contents
gcloud storage rm -r gs://my-bucket

# Get object metadata
gcloud storage objects describe gs://my-bucket/file.txt

# Set object metadata
gcloud storage objects update gs://my-bucket/file.txt \
    --content-type="text/plain"

Access Control

# Make object public (legacy ACLs; uniform bucket-level access is preferred)
gcloud storage objects update gs://my-bucket/file.txt \
    --add-acl-grant=entity=AllUsers,role=READER

# Make bucket public
gcloud storage buckets add-iam-policy-binding gs://my-bucket \
    --member=allUsers --role=roles/storage.objectViewer

# Remove public access
gcloud storage objects update gs://my-bucket/file.txt \
    --remove-acl-grant=AllUsers

# View bucket IAM policy
gcloud storage buckets get-iam-policy gs://my-bucket

# Grant user access to bucket
gcloud storage buckets add-iam-policy-binding gs://my-bucket \
    --member=user:user@example.com --role=roles/storage.objectViewer

# Generate signed URL (temporary access)
gcloud storage sign-url gs://my-bucket/file.txt \
    --private-key-file=key.json --duration=1h

Lifecycle Management

# Create lifecycle configuration file (lifecycle.json)
cat > lifecycle.json << 'EOF'
{
  "lifecycle": {
    "rule": [
      {
        "action": {"type": "Delete"},
        "condition": {"age": 30}
      },
      {
        "action": {"type": "SetStorageClass", "storageClass": "NEARLINE"},
        "condition": {"age": 7}
      }
    ]
  }
}
EOF

# Apply lifecycle policy
gcloud storage buckets update gs://my-bucket \
    --lifecycle-file=lifecycle.json

# View lifecycle policy
gcloud storage buckets describe gs://my-bucket \
    --format="default(lifecycle_config)"

IAM and Service Accounts

Identity and Access Management for controlling who can do what on GCP resources.

Role TypesBasic RolesOwner/Editor/ViewerPredefined Rolesroles/compute.adminCustom RolesProject-specificIAM StructureUser/GroupRoleService AccountPermissionsResourceRole TypesBasic RolesOwner/Editor/ViewerPredefined Rolesroles/compute.adminCustom RolesProject-specificIAM StructureUser/GroupRoleService AccountPermissionsResource

Service Account Management

# Create a service account
gcloud iam service-accounts create my-service-account \
    --display-name="My Service Account" \
    --description="Service account for my application"

# List service accounts
gcloud iam service-accounts list

# Describe a service account
gcloud iam service-accounts describe \
    my-service-account@my-project.iam.gserviceaccount.com

# Delete a service account
gcloud iam service-accounts delete \
    my-service-account@my-project.iam.gserviceaccount.com

Service Account Keys

# Create a key for a service account
gcloud iam service-accounts keys create key.json \
    --iam-account=my-sa@my-project.iam.gserviceaccount.com

# List keys for a service account
gcloud iam service-accounts keys list \
    --iam-account=my-sa@my-project.iam.gserviceaccount.com

# Delete a key
gcloud iam service-accounts keys delete KEY_ID \
    --iam-account=my-sa@my-project.iam.gserviceaccount.com

# Use key file for authentication
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/key.json"

Role Management

# List predefined roles
gcloud iam roles list

# Describe a role
gcloud iam roles describe roles/compute.admin

# List roles granted on a project
gcloud projects get-iam-policy my-project

# Grant role to user
gcloud projects add-iam-policy-binding my-project \
    --member="user:user@example.com" \
    --role="roles/compute.viewer"

# Grant role to service account
gcloud projects add-iam-policy-binding my-project \
    --member="serviceAccount:my-sa@my-project.iam.gserviceaccount.com" \
    --role="roles/storage.objectViewer"

# Remove role from user
gcloud projects remove-iam-policy-binding my-project \
    --member="user:user@example.com" \
    --role="roles/compute.viewer"

# Grant role on specific resource
gcloud storage buckets add-iam-policy-binding gs://my-bucket \
    --member="serviceAccount:my-sa@my-project.iam.gserviceaccount.com" \
    --role="roles/storage.objectAdmin"

Custom Roles

# Create custom role from YAML
cat > custom-role.yaml << 'EOF'
title: "Custom Storage Reader"
description: "Read-only access to specific storage operations"
stage: "GA"
includedPermissions:
- storage.buckets.get
- storage.objects.get
- storage.objects.list
EOF

gcloud iam roles create customStorageReader \
    --project=my-project \
    --file=custom-role.yaml

# Update custom role
gcloud iam roles update customStorageReader \
    --project=my-project \
    --add-permissions=storage.objects.create

# Delete custom role
gcloud iam roles delete customStorageReader --project=my-project

Impersonation

# Impersonate a service account for gcloud commands
gcloud config set auth/impersonate_service_account \
    my-sa@my-project.iam.gserviceaccount.com

# Run single command with impersonation
gcloud compute instances list \
    --impersonate-service-account=my-sa@my-project.iam.gserviceaccount.com

# Clear impersonation
gcloud config unset auth/impersonate_service_account

GKE (Google Kubernetes Engine)

Managed Kubernetes service with auto-scaling, auto-upgrade, and integrated GCP services.

Cluster Creation

# Create a basic cluster
gcloud container clusters create my-cluster \
    --zone=europe-west2-a \
    --num-nodes=3

# Create with specific machine type
gcloud container clusters create my-cluster \
    --zone=europe-west2-a \
    --machine-type=e2-standard-4 \
    --num-nodes=3

# Create regional cluster (high availability)
gcloud container clusters create my-cluster \
    --region=europe-west2 \
    --num-nodes=1  # Per zone, so 3 total

# Create with autoscaling
gcloud container clusters create my-cluster \
    --zone=europe-west2-a \
    --enable-autoscaling \
    --min-nodes=1 \
    --max-nodes=10

# Create Autopilot cluster (fully managed)
gcloud container clusters create-auto my-autopilot-cluster \
    --region=europe-west2

# Create private cluster
gcloud container clusters create my-cluster \
    --zone=europe-west2-a \
    --enable-private-nodes \
    --master-ipv4-cidr=172.16.0.0/28 \
    --enable-ip-alias

# Create with workload identity (recommended)
gcloud container clusters create my-cluster \
    --zone=europe-west2-a \
    --workload-pool=my-project.svc.id.goog

Connecting to Clusters

# Get credentials for kubectl
gcloud container clusters get-credentials my-cluster \
    --zone=europe-west2-a

# Get credentials for regional cluster
gcloud container clusters get-credentials my-cluster \
    --region=europe-west2

# View cluster info
gcloud container clusters describe my-cluster \
    --zone=europe-west2-a

# List clusters
gcloud container clusters list

# Verify kubectl connection
kubectl cluster-info
kubectl get nodes

Node Pool Management

# Create additional node pool
gcloud container node-pools create my-pool \
    --cluster=my-cluster \
    --zone=europe-west2-a \
    --machine-type=e2-standard-4 \
    --num-nodes=3

# Create node pool with autoscaling
gcloud container node-pools create autoscale-pool \
    --cluster=my-cluster \
    --zone=europe-west2-a \
    --enable-autoscaling \
    --min-nodes=1 \
    --max-nodes=5

# Create Spot node pool (cost savings; Spot supersedes preemptible)
gcloud container node-pools create spot-pool \
    --cluster=my-cluster \
    --zone=europe-west2-a \
    --spot \
    --num-nodes=3

# Create node pool with specific disk
gcloud container node-pools create ssd-pool \
    --cluster=my-cluster \
    --zone=europe-west2-a \
    --disk-type=pd-ssd \
    --disk-size=100GB

# List node pools
gcloud container node-pools list \
    --cluster=my-cluster \
    --zone=europe-west2-a

# Resize node pool
gcloud container clusters resize my-cluster \
    --zone=europe-west2-a \
    --node-pool=default-pool \
    --num-nodes=5

# Delete node pool
gcloud container node-pools delete my-pool \
    --cluster=my-cluster \
    --zone=europe-west2-a

Cluster Operations

# Upgrade cluster control plane
gcloud container clusters upgrade my-cluster \
    --zone=europe-west2-a \
    --master

# Upgrade node pool
gcloud container clusters upgrade my-cluster \
    --zone=europe-west2-a \
    --node-pool=default-pool

# Delete cluster
gcloud container clusters delete my-cluster \
    --zone=europe-west2-a

Cloud Run

Fully managed serverless platform for containerised applications.

Cloud Run ArchitectureRequestLoad BalancerCloud Run ServiceRevision 1Revision 2InstanceInstanceInstanceSecret ManagerCloud StorageCloud SQLCloud Run ArchitectureRequestLoad BalancerCloud Run ServiceRevision 1Revision 2InstanceInstanceInstanceSecret ManagerCloud StorageCloud SQL

Deploying Services

# Deploy from source code
gcloud run deploy my-service \
    --source=. \
    --region=europe-west2

# Deploy from container image (Artifact Registry; Container Registry
# gcr.io was shut down in March 2025)
gcloud run deploy my-service \
    --image=europe-west2-docker.pkg.dev/my-project/my-repo/my-image:v1 \
    --region=europe-west2

# Deploy with environment variables
gcloud run deploy my-service \
    --image=europe-west2-docker.pkg.dev/my-project/my-repo/my-image:v1 \
    --region=europe-west2 \
    --set-env-vars="KEY1=value1,KEY2=value2"

# Deploy with secrets
gcloud run deploy my-service \
    --image=europe-west2-docker.pkg.dev/my-project/my-repo/my-image:v1 \
    --region=europe-west2 \
    --set-secrets="DB_PASSWORD=db-password:latest"

# Deploy allowing unauthenticated access
gcloud run deploy my-service \
    --image=europe-west2-docker.pkg.dev/my-project/my-repo/my-image:v1 \
    --region=europe-west2 \
    --allow-unauthenticated

# Deploy with CPU and memory limits
gcloud run deploy my-service \
    --image=europe-west2-docker.pkg.dev/my-project/my-repo/my-image:v1 \
    --region=europe-west2 \
    --cpu=2 \
    --memory=2Gi

# Deploy with concurrency settings
gcloud run deploy my-service \
    --image=europe-west2-docker.pkg.dev/my-project/my-repo/my-image:v1 \
    --region=europe-west2 \
    --concurrency=80 \
    --min-instances=1 \
    --max-instances=100

Service Configuration

# Update service configuration
gcloud run services update my-service \
    --region=europe-west2 \
    --memory=1Gi

# Update environment variables
gcloud run services update my-service \
    --region=europe-west2 \
    --update-env-vars="NEW_VAR=value"

# Remove environment variable
gcloud run services update my-service \
    --region=europe-west2 \
    --remove-env-vars="OLD_VAR"

# Set service account
gcloud run services update my-service \
    --region=europe-west2 \
    --service-account=my-sa@my-project.iam.gserviceaccount.com

# Enable VPC connector
gcloud run services update my-service \
    --region=europe-west2 \
    --vpc-connector=my-connector

# List services
gcloud run services list --region=europe-west2

# Describe service
gcloud run services describe my-service --region=europe-west2

# Delete service
gcloud run services delete my-service --region=europe-west2

Traffic Management

# View revisions
gcloud run revisions list --service=my-service --region=europe-west2

# Split traffic between revisions
gcloud run services update-traffic my-service \
    --region=europe-west2 \
    --to-revisions=my-service-v1=50,my-service-v2=50

# Route all traffic to latest
gcloud run services update-traffic my-service \
    --region=europe-west2 \
    --to-latest

# Gradual rollout
gcloud run services update-traffic my-service \
    --region=europe-west2 \
    --to-revisions=my-service-new=10

Logs and Monitoring

# View service logs
gcloud run services logs read my-service --region=europe-west2

# Stream logs (beta track; requires the log-streaming component)
gcloud beta run services logs tail my-service --region=europe-west2

# View logs with filter
gcloud logging read "resource.type=cloud_run_revision AND \
    resource.labels.service_name=my-service" \
    --limit=50

Cloud Build

Serverless CI/CD platform for building, testing, and deploying applications.

Build Configuration

Create a cloudbuild.yaml file:

# Basic build configuration
# (images live in Artifact Registry; Container Registry was shut down in 2025.
# Builder images keep their gcr.io names, now served from Artifact Registry.)
steps:
  # Build Docker image
  - name: 'gcr.io/cloud-builders/docker'
    args: ['build', '-t', 'europe-west2-docker.pkg.dev/$PROJECT_ID/my-repo/my-app:$COMMIT_SHA', '.']

  # Push to Artifact Registry
  - name: 'gcr.io/cloud-builders/docker'
    args: ['push', 'europe-west2-docker.pkg.dev/$PROJECT_ID/my-repo/my-app:$COMMIT_SHA']

  # Deploy to Cloud Run
  - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
    entrypoint: gcloud
    args:
      - 'run'
      - 'deploy'
      - 'my-service'
      - '--image=europe-west2-docker.pkg.dev/$PROJECT_ID/my-repo/my-app:$COMMIT_SHA'
      - '--region=europe-west2'
      - '--platform=managed'

images:
  - 'europe-west2-docker.pkg.dev/$PROJECT_ID/my-repo/my-app:$COMMIT_SHA'

options:
  logging: CLOUD_LOGGING_ONLY

Running Builds

# Submit build from current directory
gcloud builds submit --config=cloudbuild.yaml .

# Submit with substitutions
gcloud builds submit --config=cloudbuild.yaml \
    --substitutions=_ENV=prod,_VERSION=1.0.0 .

# Submit build with tag
gcloud builds submit \
    --tag=europe-west2-docker.pkg.dev/my-project/my-repo/my-app:v1 .

# List builds
gcloud builds list

# Describe a build
gcloud builds describe BUILD_ID

# Stream build logs
gcloud builds log BUILD_ID --stream

# Cancel a build
gcloud builds cancel BUILD_ID

Build Triggers

# Create trigger for GitHub repository
gcloud builds triggers create github \
    --name=my-trigger \
    --repo-name=my-repo \
    --repo-owner=my-org \
    --branch-pattern="^main$" \
    --build-config=cloudbuild.yaml

# Create trigger for Cloud Source Repositories
gcloud builds triggers create cloud-source-repositories \
    --name=my-trigger \
    --repo=my-repo \
    --branch-pattern="^main$" \
    --build-config=cloudbuild.yaml

# Create trigger with substitutions
gcloud builds triggers create github \
    --name=prod-deploy \
    --repo-name=my-repo \
    --repo-owner=my-org \
    --tag-pattern="^v.*" \
    --build-config=cloudbuild.yaml \
    --substitutions=_ENV=prod

# List triggers
gcloud builds triggers list

# Run trigger manually
gcloud builds triggers run my-trigger --branch=main

# Delete trigger
gcloud builds triggers delete my-trigger

Substitutions

# cloudbuild.yaml with substitutions
steps:
  - name: 'gcr.io/cloud-builders/docker'
    args:
      - 'build'
      - '-t'
      - 'europe-west2-docker.pkg.dev/$PROJECT_ID/my-repo/my-app:${_VERSION}'
      - '--build-arg'
      - 'ENV=${_ENV}'
      - '.'

substitutions:
  _VERSION: latest
  _ENV: dev

# Built-in substitutions:
# $PROJECT_ID - GCP project ID
# $BUILD_ID - Build ID
# $COMMIT_SHA - Git commit SHA
# $BRANCH_NAME - Git branch name
# $TAG_NAME - Git tag name
# $REPO_NAME - Repository name
# $SHORT_SHA - First 7 characters of commit SHA

Cloud Functions

Event-driven serverless functions for lightweight compute tasks. Cloud Functions is now branded Cloud Run functions; new deployments use the 2nd gen (Cloud Run-based) environment by default, with 1st gen only available via the --no-gen2 flag.

Cloud Functions TriggersHTTP RequestPub/Sub MessageCloud Storage EventFirestore EventCloud SchedulerCloud FunctionResponse/ActionCloud Functions TriggersHTTP RequestPub/Sub MessageCloud Storage EventFirestore EventCloud SchedulerCloud FunctionResponse/Action

Deploying Functions

# Deploy HTTP function (Python)
gcloud functions deploy my-function \
    --runtime=python311 \
    --trigger-http \
    --entry-point=main \
    --region=europe-west2

# Deploy with public access
gcloud functions deploy my-function \
    --runtime=python311 \
    --trigger-http \
    --entry-point=main \
    --region=europe-west2 \
    --allow-unauthenticated

# Deploy Pub/Sub triggered function
gcloud functions deploy my-function \
    --runtime=python311 \
    --trigger-topic=my-topic \
    --entry-point=main \
    --region=europe-west2

# Deploy Cloud Storage triggered function
gcloud functions deploy my-function \
    --runtime=python311 \
    --trigger-bucket=my-bucket \
    --entry-point=main \
    --region=europe-west2

# Deploy with environment variables
gcloud functions deploy my-function \
    --runtime=python311 \
    --trigger-http \
    --entry-point=main \
    --region=europe-west2 \
    --set-env-vars="KEY=value"

# Deploy with secrets
gcloud functions deploy my-function \
    --runtime=python311 \
    --trigger-http \
    --entry-point=main \
    --region=europe-west2 \
    --set-secrets="API_KEY=api-key:latest"

# Deploy with memory and timeout
gcloud functions deploy my-function \
    --runtime=python311 \
    --trigger-http \
    --entry-point=main \
    --region=europe-west2 \
    --memory=512MB \
    --timeout=60s

# Pin a 1st gen function explicitly (legacy environment)
gcloud functions deploy my-function \
    --no-gen2 \
    --runtime=python311 \
    --trigger-http \
    --entry-point=main \
    --region=europe-west2

Function Code Examples

Python HTTP function (main.py):

import functions_framework

@functions_framework.http
def main(request):
    """HTTP Cloud Function."""
    request_json = request.get_json(silent=True)

    if request_json and 'name' in request_json:
        name = request_json['name']
    else:
        name = 'World'

    return f'Hello, {name}!'

Python Pub/Sub function:

import base64
import functions_framework

@functions_framework.cloud_event
def main(cloud_event):
    """Pub/Sub Cloud Function."""
    message = base64.b64decode(cloud_event.data["message"]["data"]).decode()
    print(f"Received message: {message}")

Invoking Functions

# Call HTTP function
gcloud functions call my-function \
    --region=europe-west2 \
    --data='{"name": "Claude"}'

# Get function URL (2nd gen; for 1st gen use httpsTrigger.url)
gcloud functions describe my-function \
    --region=europe-west2 \
    --format='value(url)'

# Call via curl
curl -X POST https://REGION-PROJECT.cloudfunctions.net/my-function \
    -H "Content-Type: application/json" \
    -d '{"name": "Claude"}'

# Call authenticated function
curl -X POST https://REGION-PROJECT.cloudfunctions.net/my-function \
    -H "Authorization: bearer $(gcloud auth print-identity-token)" \
    -H "Content-Type: application/json" \
    -d '{"name": "Claude"}'

Managing Functions

# List functions
gcloud functions list --region=europe-west2

# Describe function
gcloud functions describe my-function --region=europe-west2

# Delete function
gcloud functions delete my-function --region=europe-west2

# View function logs
gcloud functions logs read my-function --region=europe-west2

# Read recent logs with a limit
gcloud functions logs read my-function \
    --region=europe-west2 \
    --limit=50

VPC and Networking

Virtual Private Cloud for network isolation and connectivity.

VPC Networkus-central1europe-west2Subnet10.0.1.0/24VM InstanceVM InstanceSubnet10.0.2.0/24VM InstanceFirewall RulesCloud RouterCloud NATInternetVPC Networkus-central1europe-west2Subnet10.0.1.0/24VM InstanceVM InstanceSubnet10.0.2.0/24VM InstanceFirewall RulesCloud RouterCloud NATInternet

VPC Network Management

# Create custom VPC network
gcloud compute networks create my-vpc \
    --subnet-mode=custom

# Create subnet
gcloud compute networks subnets create my-subnet \
    --network=my-vpc \
    --region=europe-west2 \
    --range=10.0.1.0/24

# Create subnet with secondary ranges (for GKE)
gcloud compute networks subnets create gke-subnet \
    --network=my-vpc \
    --region=europe-west2 \
    --range=10.0.0.0/24 \
    --secondary-range=pods=10.1.0.0/16,services=10.2.0.0/20

# List networks
gcloud compute networks list

# List subnets
gcloud compute networks subnets list

# Describe network
gcloud compute networks describe my-vpc

# Delete network
gcloud compute networks delete my-vpc

Firewall Rules

# Create firewall rule to allow SSH
gcloud compute firewall-rules create allow-ssh \
    --network=my-vpc \
    --allow=tcp:22 \
    --source-ranges=0.0.0.0/0 \
    --target-tags=ssh-enabled

# Create firewall rule for HTTP/HTTPS
gcloud compute firewall-rules create allow-http \
    --network=my-vpc \
    --allow=tcp:80,tcp:443 \
    --source-ranges=0.0.0.0/0 \
    --target-tags=http-server

# Create internal communication rule
gcloud compute firewall-rules create allow-internal \
    --network=my-vpc \
    --allow=tcp,udp,icmp \
    --source-ranges=10.0.0.0/8

# Create rule with service account
gcloud compute firewall-rules create allow-app \
    --network=my-vpc \
    --allow=tcp:8080 \
    --source-ranges=0.0.0.0/0 \
    --target-service-accounts=my-sa@my-project.iam.gserviceaccount.com

# List firewall rules
gcloud compute firewall-rules list

# Delete firewall rule
gcloud compute firewall-rules delete allow-ssh

Cloud NAT

# Create Cloud Router
gcloud compute routers create my-router \
    --network=my-vpc \
    --region=europe-west2

# Create Cloud NAT
gcloud compute routers nats create my-nat \
    --router=my-router \
    --region=europe-west2 \
    --nat-all-subnet-ip-ranges \
    --auto-allocate-nat-external-ips

# Describe NAT configuration
gcloud compute routers nats describe my-nat \
    --router=my-router \
    --region=europe-west2

VPC Peering

# Create VPC peering connection
gcloud compute networks peerings create peer-to-other-vpc \
    --network=my-vpc \
    --peer-network=other-vpc \
    --peer-project=other-project

# List peering connections
gcloud compute networks peerings list --network=my-vpc

# Delete peering
gcloud compute networks peerings delete peer-to-other-vpc \
    --network=my-vpc

Static IP Addresses

# Reserve external static IP
gcloud compute addresses create my-static-ip \
    --region=europe-west2

# Reserve global static IP (for global load balancer)
gcloud compute addresses create my-global-ip \
    --global

# List addresses
gcloud compute addresses list

# Use static IP with VM
gcloud compute instances create my-vm \
    --zone=europe-west2-a \
    --address=my-static-ip \
    --image-family=debian-12 \
    --image-project=debian-cloud

Quick Reference

Essential gcloud Commands

Command Description
gcloud init Initialise gcloud configuration
gcloud auth login Authenticate with Google account
gcloud config set project PROJECT Set default project
gcloud config set compute/zone ZONE Set default zone
gcloud services enable SERVICE Enable an API
gcloud projects list List available projects

Compute Engine

Command Description
gcloud compute instances create NAME Create VM instance
gcloud compute instances list List all instances
gcloud compute ssh NAME SSH into instance
gcloud compute instances stop NAME Stop instance
gcloud compute instances start NAME Start instance
gcloud compute instances delete NAME Delete instance
gcloud compute disks snapshot DISK Create disk snapshot

Cloud Storage (gcloud storage)

Command Description
gcloud storage buckets create gs://BUCKET Create bucket
gcloud storage ls gs://BUCKET List bucket contents
gcloud storage cp FILE gs://BUCKET/ Upload file
gcloud storage cp gs://BUCKET/FILE ./ Download file
gcloud storage rsync -r LOCAL gs://BUCKET/ Sync directory
gcloud storage rm gs://BUCKET/FILE Delete object

GKE

Command Description
gcloud container clusters create NAME Create cluster
gcloud container clusters get-credentials NAME Configure kubectl
gcloud container clusters list List clusters
gcloud container node-pools create NAME Create node pool
gcloud container clusters delete NAME Delete cluster

Cloud Run

Command Description
gcloud run deploy SERVICE --image=IMAGE Deploy service
gcloud run services list List services
gcloud run services describe SERVICE Describe service
gcloud run services logs read SERVICE View logs
gcloud run services delete SERVICE Delete service

Cloud Functions

Command Description
gcloud functions deploy NAME --trigger-http Deploy HTTP function
gcloud functions call NAME Invoke function
gcloud functions list List functions
gcloud functions logs read NAME View logs
gcloud functions delete NAME Delete function

IAM

Command Description
gcloud iam service-accounts create NAME Create service account
gcloud iam service-accounts keys create FILE Create SA key
gcloud projects add-iam-policy-binding Grant role
gcloud projects get-iam-policy PROJECT View IAM policy

Common Issues and Solutions

Authentication Issues

Issue Solution
ERROR: (gcloud.auth.login) could not load Run gcloud components update
Your current project is not set Run gcloud config set project PROJECT_ID
Permission denied on service account Verify IAM roles and enable required APIs
Could not authenticate Run gcloud auth login or check key file path

Compute Engine Issues

Issue Solution
Quota exceeded Request quota increase in Console or use different zone
The resource already exists Choose different name or delete existing resource
SSH connection timeout Check firewall rules allow port 22, verify VM is running
Permission denied during SSH Ensure OS Login is configured or use project-wide SSH keys

Cloud Storage Issues

Issue Solution
AccessDeniedException: 403 Check IAM permissions on bucket
BucketAlreadyExists Bucket names are global; choose unique name
Slow uploads gcloud storage parallelises transfers automatically; check network and consider composite uploads for very large files
ResumableUploadException Increase threshold or check network stability

GKE Issues

Issue Solution
Unable to connect to the server Run gcloud container clusters get-credentials
Pods stuck in Pending Check node resources and quotas
Error from server (Forbidden) Check RBAC permissions and IAM roles
Node pool creation fails Verify subnet has available IP addresses

Cloud Run Issues

Issue Solution
Container failed to start Check logs, verify port binding to $PORT
Memory limit exceeded Increase memory allocation
Cold start latency Set --min-instances=1
Permission denied on dependent service Check service account roles

Cloud Functions Issues

Issue Solution
Function failed on loading user code Check entry point name matches function name
Timeout errors Increase timeout with --timeout flag
Memory limit exceeded Increase memory with --memory flag
Dependencies not found Ensure requirements.txt is in function directory

Networking Issues

Issue Solution
VM cannot reach internet Check Cloud NAT configuration or assign external IP
Services cannot communicate Verify firewall rules and network tags
VPC peering not working Ensure routes are exported and imported correctly
Load balancer health checks fail Check firewall allows health check ranges (35.191.0.0/16, 130.211.0.0/22)

Related Topics

To complement your GCP knowledge, consider exploring these related topics:

  1. Terraform - Infrastructure as Code for managing GCP resources declaratively with state management and modules
  2. Kubernetes - Container orchestration fundamentals that apply to GKE workloads
  3. AWS - Compare GCP services with AWS equivalents for multi-cloud strategies
  4. Prometheus/Grafana - Monitoring and observability stack that integrates well with GCP
  5. CI/CD Patterns - Best practices for pipelines that work with Cloud Build
  6. Container Security - Security scanning and policies for GKE workloads