Home • Blog • Article

Solving the Blind Spot in GCP Billing with Browser Automation: A Practical Guide

By Fathima Nourin TM • •

Problem Statement & Impact

Managing cloud infrastructure efficiently requires rigorous financial visibility, particularly when utilizing Committed Use Discounts (CUDs) on Google Cloud Platform (GCP). Organizations commit to one- or three-year usage terms in exchange for substantial discounts on compute, memory, and database resources. However, a major architectural limitation exists within GCP’s cost management ecosystem: while raw cost and usage data are exportable to BigQuery for deep analytics and programmatic reporting, CUD allocation, utilization metrics, and expiration timelines remain sequestered within the GCP Console user interface.

This architectural blind spot affects engineering, platform, and finance teams operating enterprise multi-account environments. The absence of native API endpoints, command-line interface parameters, or BigQuery schema support for detailed CUD line items creates severe operational hurdles:

  • Incomplete Cost Attribution: FinOps dashboards cannot accurately calculate net effective rates per microservice or team because discount application data is detached from actual resource consumption logs.
  • Expiration Blindness: Teams frequently miss CUD expiration windows, leading to sudden, unbudgeted spikes when resources automatically revert to on-demand pricing rates.
  • Underutilization Waste: Organizations routinely over-provision commitments without granular tracking of daily commitment utilization percentages, paying for compute capacity that sits idle.

Mitigating this financial risk requires bridging the gap between proprietary console data and automated data pipelines. Without a programmatic extraction mechanism, organizations are forced to rely on manual web navigation, introducing human error, delayed auditing, and degraded cost governance.

🚨 Facing an active site error or malware warning?

Chat with an engineer on WhatsApp within 15 minutes.

💬 Chat on WhatsApp

Root Cause Analysis & Architecture

The core technical challenge stems from how Google Cloud exposes billing metadata. While standard billing exports populate BigQuery datasets with hourly or daily usage items tagged with SKU IDs, project IDs, and labels, commitment-specific attributes—such as flexible vs. resource-based commitments, hourly commitment amounts, and remaining duration blocks—are rendered dynamically via internal UI endpoints tied to the Google Cloud Billing console frontend.

Because these frontend components consume internal, undocumented RPCs or require authenticated session tokens managed through complex OAuth flows, traditional programmatic tools like Google Cloud SDK (`gcloud`), direct API requests using service account keys, or standard BigQuery SQL queries cannot access the data. Service accounts lack the IAM permissions required to execute internal billing console rendering pipelines, which are strictly bound to user identities with specific billing account roles (such as Billing Account Administrator or Billing Account Viewer).

To overcome this architectural limitation, the remediation pipeline must emulate a legitimate user session via headless browser automation. The architecture relies on an isolated Python execution environment utilizing Selenium WebDriver coupled with undetected-chromedriver or Chromium binaries running in a secure, containerized orchestration layer. This setup performs the following lifecycle tasks:

  1. Spawns a headless browser instance with randomized user-agent profiles to bypass automated bot detection mechanisms implemented by Google Identity Services.
  2. Executes an authenticated login sequence using secure credentials retrieved from an encrypted secrets manager.
  3. Handles multi-factor authentication (MFA) challenges by intercepting verification vectors or routing through pre-authenticated session state tokens (cookies).
  4. Navigates directly to the target billing account’s Committed Use Discounts sub-route.
  5. Triggers DOM interactions to download CSV export payloads generated asynchronously by the console.
  6. Ingests, transforms, and pushes the extracted datasets into an internal Google Cloud Storage (GCS) bucket for downstream BigQuery ingestion and alerting.

Step-by-Step Implementation & Remediation Guide

Implementing this browser automation workflow requires a robust, production-ready Python script capable of handling headless navigation, element waiting states, and secure credential handling. The following implementation uses Selenium WebDriver and Google Cloud client libraries.

1 – Environment Setup and Dependencies

Deploy the automation script inside a dedicated Python virtual environment. Install the required dependencies using pip:

python3 -m venv venv
source venv/bin/activate
pip install selenium google-cloud-storage pandas webdriver-manager

2 – Core Python Automation Script

Create a script named gcp_cud_extractor.py. This script initializes the headless browser, handles authentication, navigates the billing console, downloads the reports, and uploads them to Google Cloud Storage.

import os
import time
import pandas as pd
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
from google.cloud import storage

def init_driver(download_dir):
    options = webdriver.ChromeOptions()
    options.add_argument("--headless=new")
    options.add_argument("--no-sandbox")
    options.add_argument("--disable-dev-shm-usage")
    options.add_argument("--disable-gpu")
    options.add_argument("--window-size=1920,1080")
    
    prefs = {
        "download.default_directory": download_dir,
        "download.prompt_for_download": False,
        "download.directory_upgrade": True,
        "safebrowsing.enabled": True
    }
    options.add_experimental_option("prefs", prefs)
    
    driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)
    return driver

def authenticate_gcp(driver, email, password):
    driver.get("https://accounts.google.com/")
    
    # Enter Email
    email_field = WebDriverWait(driver, 15).until(
        EC.presence_of_element_located((By.ID, "identifierId"))
    )
    email_field.send_keys(email)
    driver.find_element(By.ID, "identifierNext").click()
    
    # Enter Password
    password_field = WebDriverWait(driver, 15).until(
        EC.presence_of_element_located((By.NAME, "Passwd"))
    )
    password_field.send_keys(password)
    driver.find_element(By.ID, "passwordNext").click()
    
    # Wait for post-login redirect to complete
    time.sleep(10)

def download_cud_reports(driver, billing_account_id, download_dir):
    cud_url = f"https://console.cloud.google.com/billing/{billing_account_id}/commitments"
    driver.get(cud_url)
    
    # Wait for the dashboard grid to render
    WebDriverWait(driver, 20).until(
        EC.presence_of_element_located((By.CSS_SELECTOR, "material-button.export-button"))
    )
    
    # Locate and click export/download button
    export_buttons = driver.find_elements(By.CSS_SELECTOR, "material-button.export-button")
    for btn in export_buttons:
        if "CSV" in btn.text or "Download" in btn.text:
            btn.click()
            time.sleep(5)
            break

def upload_to_gcs(bucket_name, source_file_path, destination_blob_name):
    storage_client = storage.Client()
    bucket = storage_client.bucket(bucket_name)
    blob = bucket.blob(destination_blob_name)
    blob.upload_from_filename(source_file_path)
    print(f"File {source_file_path} uploaded to gs://{bucket_name}/{destination_blob_name}.")

if __name__ == "__main__":
    BILLING_ACCOUNT_ID = os.environ.get("GCP_BILLING_ACCOUNT_ID")
    GCS_BUCKET = os.environ.get("GCP_CUD_BUCKET_NAME")
    GCP_USER = os.environ.get("GCP_AUTOMATION_EMAIL")
    GCP_PASS = os.environ.get("GCP_AUTOMATION_PASSWORD")
    DOWNLOAD_DIR = "/tmp/gcp_cud_downloads"
    
    os.makedirs(DOWNLOAD_DIR, exist_ok=True)
    
    driver = init_driver(DOWNLOAD_DIR)
    try:
        authenticate_gcp(driver, GCP_USER, GCP_PASS)
        download_cud_reports(driver, BILLING_ACCOUNT_ID, DOWNLOAD_DIR)
        
        # Find latest downloaded file
        files = [os.path.join(DOWNLOAD_DIR, f) for f in os.listdir(DOWNLOAD_DIR) if f.endswith('.csv')]
        latest_file = max(files, key=os.path.getctime)
        
        destination_name = f"raw_cud_reports/{time.strftime('%Y-%m-%d')}_cud_report.csv"
        upload_to_gcs(GCS_BUCKET, latest_file, destination_name)
    finally:
        driver.quit()

Production Hardening & Edge Cases

Running browser automation workflows in enterprise production environments requires addressing several operational hurdles, security implications, and edge cases:

  • MFA Constraints: Google Identity Services frequently trigger advanced bot detection, CAPTCHAs, or hardware-token MFA challenges when detecting automated Selenium instances. To resolve this, pre-authenticate a designated automation service account via a standard browser, extract the session cookies (_ga, SID, HSID, SSID, etc.), and inject them directly into the WebDriver session headers rather than performing raw username/password form submissions.
  • DOM Drift and Selector Resilience: Google updates the Cloud Console UI frequently, altering CSS selectors and class names. Avoid using brittle class-based locators. Instead, target elements via accessibility attributes, aria-labels, or robust XPath queries (e.g., `//button[contains(., ‘Download’)]`).
  • Concurrency and Rate Limiting: Executing parallel extraction jobs across dozens of billing accounts simultaneously will trigger IP rate limiting or account lockouts. Implement strict serialization queues or randomized execution delays (jitter) between account processing runs.
  • Secret Management: Never hardcode credentials within the codebase. Inject credentials via secure environment variables managed by platforms such as HashiCorp Vault, AWS Secrets Manager, or GCP Secret Manager.

Diagnostic Verification & Checklist

Use the following validation matrix to verify pipeline health, inspect execution states, and confirm correct data ingestion into Google Cloud Storage and downstream analytics systems.

Verification Phase Diagnostic Action Expected Outcome / Success Criteria
Authentication Inspect headless browser logs or debug screenshots taken upon login failure. Headless browser bypasses the consent screen and lands on the Billing Console home route without hitting a CAPTCHA wall.
DOM Rendering Check for TimeoutException errors during element wait phases. All dynamic dashboard elements, including commitment tables and filter buttons, load within the 20-second threshold.
File Extraction Verify local file system contents in DOWNLOAD_DIR. A valid `.csv` file containing commitment names, SKUs, and utilization metrics appears in the directory.
Cloud Ingestion Run CLI verification for GCS object creation:
gsutil ls gs://[BUCKET_NAME]/raw_cud_reports/
The timestamped CSV blob is successfully created in the destination bucket with non-zero byte size.
Pipeline Alerting Monitor exit codes in the orchestration runner (e.g., Kubernetes CronJob or Cloud Run Job). Script exits with status code 0 on success, or triggers an operational alert webhook on failure.
Follow SiteSuraksha on Google
Add us to your preferred sources for verified WordPress & hosting guides.
FREE 30-SECOND DIAGNOSTIC

Is Your Website Fast & Secure?

Run an instant scan for security vulnerabilities, bloated plugins, and TTFB latency.

🔍 Test Your Site Now →
Map Your Issue to Guaranteed IT Care
Security & Malware
Hacks, 0-day exploits & backup failures
Pro Care (₹5,420/mo) →
Speed & Cloud Bills
Slow checkout, high TTFB & cloud waste
Pro Care (₹5,420/mo) →
ERP & Automation
GST pipelines, RPA & AI support agents
Enterprise (₹14,999/mo) →
EXPERT WORDPRESS CARE

Need Help Securing or Speeding Up Your Site?

Get 24/7 proactive security WAF, daily cloud backups, and sub-second speed optimization from ₹3,470/mo.

💬 Chat on WhatsApp Explore Plans
← Back to All Articles