GCP for DevOps — Billing & Budgets

3 minute read

Billing & Budgets

GCP billing is managed through billing accounts that are linked to projects. Understanding the billing hierarchy, setting up budgets, and configuring alerts are essential for controlling costs in any DevOps environment.

Billing Hierarchy

Billing Hierarchy:
┌─────────────────────────────────────────────────┐
│             Organization                         │
│  ┌───────────────────────────────────────────┐  │
│  │         Billing Account                    │  │
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐    │  │
│  │  │Project A│ │Project B│ │Project C│    │  │
│  │  │ $150/mo │ │ $800/mo │ │ $50/mo  │    │  │
│  │  └─────────┘ └─────────┘ └─────────┘    │  │
│  │                                           │  │
│  │  Budget: $1,200/month                     │  │
│  │  Alerts: 50%, 75%, 90%, 100%              │  │
│  └───────────────────────────────────────────┘  │
└─────────────────────────────────────────────────┘

View Billing Account Information

$ gcloud billing accounts list
ACCOUNT_ID            NAME                OPEN  MASTER_ACCOUNT_ID
01ABCD-EFGH56-789012  My Billing Account  True

$ gcloud billing projects list --billing-account=01ABCD-EFGH56-789012
PROJECT_ID       BILLING_ACCOUNT_ID        BILLING_ENABLED
my-project-dev   01ABCD-EFGH56-789012      True
my-project-prod  01ABCD-EFGH56-789012      True
$ gcloud billing projects link my-project-dev \
    --billing-account=01ABCD-EFGH56-789012
billingAccountName: billingAccounts/01ABCD-EFGH56-789012
billingEnabled: true
projectId: my-project-dev

Create a Budget

Use the Console or the gcloud CLI with the Billing Budgets API:

# Enable the billing budgets API
$ gcloud services enable billingbudgets.googleapis.com

# Create a budget via REST (using gcloud for auth)
$ curl -X POST \
    "https://billingbudgets.googleapis.com/v1/billingAccounts/01ABCD-EFGH56-789012/budgets" \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json" \
    -d '{
      "displayName": "Monthly Budget - Dev",
      "budgetFilter": {
        "projects": ["projects/123456789"]
      },
      "amount": {
        "specifiedAmount": {
          "currencyCode": "USD",
          "units": "500"
        }
      },
      "thresholdRules": [
        {"thresholdPercent": 0.5, "spendBasis": "CURRENT_SPEND"},
        {"thresholdPercent": 0.75, "spendBasis": "CURRENT_SPEND"},
        {"thresholdPercent": 0.9, "spendBasis": "CURRENT_SPEND"},
        {"thresholdPercent": 1.0, "spendBasis": "CURRENT_SPEND"}
      ],
      "notificationsRule": {
        "pubsubTopic": "projects/my-project-dev/topics/billing-alerts",
        "schemaVersion": "1.0"
      }
    }'

Budget Alert Thresholds

Threshold Action Description
50% Email notification Early warning for cost trending
75% Email + Pub/Sub Review and investigate spend
90% Pub/Sub → Cloud Function Automated cost controls
100% Pub/Sub → Disable billing Emergency stop (optional)

Automate Budget Responses with Cloud Functions

# Create a Pub/Sub topic for billing alerts
$ gcloud pubsub topics create billing-alerts \
    --project=my-project-dev
Created topic [projects/my-project-dev/topics/billing-alerts].

# Deploy a Cloud Function to respond to budget alerts
$ gcloud functions deploy budget-enforcer \
    --runtime=python312 \
    --trigger-topic=billing-alerts \
    --entry-point=enforce_budget \
    --source=./budget-function/ \
    --region=us-central1
Deploying function...done.

Example Cloud Function to disable billing when budget is exceeded:

import base64
import json
from googleapiclient import discovery

def enforce_budget(event, context):
    """Respond to billing budget alert."""
    pubsub_data = base64.b64decode(event['data']).decode('utf-8')
    budget_data = json.loads(pubsub_data)
    
    cost_amount = budget_data['costAmount']
    budget_amount = budget_data['budgetAmount']
    
    if cost_amount >= budget_amount:
        print(f"Budget exceeded: ${cost_amount} >= ${budget_amount}")
        # Add enforcement logic here

Billing Export to BigQuery

Export billing data to BigQuery for detailed analysis:

# Create a dataset for billing data
$ gcloud bq datasets create billing_export \
    --project=my-analytics-project \
    --location=US
Dataset 'my-analytics-project:billing_export' successfully created.

Then configure billing export in the Console:

  1. Navigate to Billing → Billing export
  2. Select the BigQuery Export tab
  3. Choose the dataset and enable Detailed usage cost export

Query Billing Data in BigQuery

-- Top 10 most expensive services this month
SELECT
  service.description AS service,
  ROUND(SUM(cost), 2) AS total_cost,
  ROUND(SUM(cost) / (SELECT SUM(cost) FROM billing_export.gcp_billing_export
    WHERE invoice.month = FORMAT_DATE('%Y%m', CURRENT_DATE())) * 100, 1) AS pct
FROM billing_export.gcp_billing_export
WHERE invoice.month = FORMAT_DATE('%Y%m', CURRENT_DATE())
GROUP BY service.description
ORDER BY total_cost DESC
LIMIT 10;

Labels for Cost Allocation

Labels help you track costs by team, environment, or application:

# Add labels to a Compute Engine instance
$ gcloud compute instances update web-server-1 \
    --zone=us-central1-a \
    --update-labels=team=platform,env=prod,app=web-api
Updated [https://www.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/instances/web-server-1].

# Add labels to a GKE cluster
$ gcloud container clusters update production \
    --zone=us-central1-a \
    --update-labels=team=platform,cost-center=eng-1234
Updating production...done.

# Query costs by label in BigQuery
# SELECT labels.value, SUM(cost) FROM ...
# WHERE labels.key = 'team'
# GROUP BY labels.value

Cost Allocation Best Practices

Practice Implementation Impact
Consistent labeling Enforce via org policies Accurate cost attribution
Per-env billing accounts Separate dev/staging/prod Clear environment costs
Project-based allocation One service = one project Granular cost visibility
Automated cleanup Scheduled Cloud Functions Eliminate waste
Budget alerts per project Alert at 50/75/90/100% Early cost warnings

Common Mistakes

Mistake Impact Fix
No budget alerts set Surprise bills at month end Set alerts at 50%, 75%, 90%
Missing labels on resources Cannot attribute costs to teams Enforce labeling via org policy
Billing export not enabled No historical cost analysis Enable BigQuery export immediately
Single billing account for all Hard to isolate costs Separate billing per business unit

Quick Reference

Task Command
List billing accounts gcloud billing accounts list
Link project to billing gcloud billing projects link PROJECT --billing-account=ACCOUNT
Create Pub/Sub for alerts gcloud pubsub topics create billing-alerts
Add labels to VM gcloud compute instances update VM --update-labels=KEY=VALUE
Enable billing export Console → Billing → Billing export → BigQuery

Next → Rightsizing & Recommenders

Updated: