Skip to content

Add fxci-task-cost-attribution skill - #16

Open
jwmossmoz wants to merge 3 commits into
mainfrom
add-fxci-task-cost-attribution-skill
Open

jwmossmoz wants to merge 3 commits into
mainfrom
add-fxci-task-cost-attribution-skill

Conversation

@jwmossmoz

@jwmossmoz jwmossmoz commented May 5, 2026

Copy link
Copy Markdown
Collaborator

Summary

New skill that answers per-task and per-push FXCI cost questions across both clouds while the RELOPS-2330 production pipeline is still pending.

The workflow now uses a six-stage pipeline:

  1. GCP per-task rows from the existing task_run_costs_v1 path
  2. Azure per-VM-day cost rows from the Azure billing export
  3. Azure vm-* task runs from FXCI task tables
  4. Azure worker uptime from taskclusteretl.worker_metrics
  5. Local DuckDB join for Azure per-task rows
  6. DuckDB summaries across GCP + Azure

This is distinct from azure-cost-analysis, which is for pool/SKU-level Azure Cost Management rollups. This skill is for task, push, tree, kind, and label attribution.

Worker Metrics Update

Azure uptime now comes from generic-worker WORKER_METRICS lifecycle events in taskclusteretl.worker_metrics, rather than a first-task/last-task approximation from task_runs_v1.

That gives a better denominator without needing Azure Monitor. The docs still call out the remaining limitation: worker metrics are Taskcluster-side data and do not fully capture Azure VM lifetime after the worker has stopped but before the VM is deleted.

Public Data Cleanup

Removed the sample cost breakdowns and dollar figures from the public PR text and methodology docs. The skill documents the workflow and caveats without publishing internal cost totals.

Why Two Gcloud Accounts

Human IAM is split between moz-fx-data-shared-prod and moz-fx-data-billing-prod-9147. No single human principal can read both billing datasets, so the workflow runs the BigQuery halves separately and joins locally with DuckDB.

Structure

skills/fxci-task-cost-attribution/
├── SKILL.md
├── queries/
│   ├── README.md
│   ├── 01_gcp_per_task.sql
│   ├── 02_azure_vm_cost.sql
│   ├── 03_azure_task_runs_all.sql
│   ├── 04_azure_worker_metrics.sql
│   ├── 05_local_join.sql
│   └── 06_summary.sql
└── references/
    ├── README.md
    ├── auth-split.md
    ├── duckdb-local-join.md
    ├── methodology.md
    └── jira-context.md

Retires When

Once the RELOPS-2330 bigquery-etl pipeline lands and fxci_derived.task_run_costs_v1 covers Azure VMs end-to-end, most users can query that table directly. Until then, this skill is the local workaround.

Test Plan

  • Confirmed taskclusteretl.worker_metrics has Azure Windows generic-worker lifecycle events
  • Confirmed worker-metrics task durations line up with task_runs_v1
  • Confirmed the new worker-uptime query shape returns worker-day uptime rows through Redash
  • Confirmed public docs no longer include sample cost breakdowns or dollar figures
  • Internal @references/* and queries/* links updated for the six-stage workflow
  • No hardcoded user paths in skill files
  • Reviewer to validate command lines on a Windows host

jwmossmoz added 3 commits May 5, 2026 15:51
Per-task and per-push cost attribution for FXCI tasks across both clouds.
Implements the RELOPS-2330 reference query as a five-stage pipeline:
three BigQuery extracts (across two gcloud accounts, since human IAM is
split between moz-fx-data-shared-prod and moz-fx-data-billing-prod-9147)
plus a local DuckDB cross-cloud join.

The skill defaults to a `>=` filter with `LEAST(1.0, ratio)` cap on the
attribution formula. This deviates from the strict `>` in the original
RELOPS-2330 query: empirically it shrinks the unattributed Azure spend
gap from ~27% to ~12% by including single-task VMs (which are otherwise
excluded entirely). methodology.md documents the bucket decomposition
and how to flip back to strict `>` if exact ticket reproduction is
needed.

Cross-platform: install commands for macOS (Homebrew) and Windows
(Chocolatey) for both `gcloudsdk` and `duckdb`. PowerShell command
forms documented alongside bash where syntax diverges.

Distinct from the existing `azure-cost-analysis` skill, which queries
the Azure Cost Management REST API for pool/SKU rollups. This skill
joins BigQuery billing exports against `fxci_derived.task_runs_v1` and
`tasks_v2` for per-task granularity.

Retires when RELOPS-2330's bigquery-etl pipeline lands and
`fxci_derived.task_run_costs_v1` covers Azure VMs end-to-end.
The previous version of methodology.md only treated the uptime
approximation. Empirical decomposition of the Azure billing export shows
the `virtualMachines/vm-*` filter captures only 87.5% of total FXCI
Azure spend in a representative window. The remaining 12.5% is:

  - 4.7% non-`vm-*` VMs (management, image-build, persistent
    scriptworkers — correctly excluded from per-task attribution since
    they're not task workers)
  - 4.1% Virtual Network (NICs, public IPs)
  - 2.6% Storage (managed disks attached to VMs)
  - 1.1% Network egress
  - 0.0% misc (Automation, Key Vault)

Network, storage, and egress are real per-task costs in spirit but the
billing export attributes them per-resource, not per-VM. RELOPS-2330
doesn't cover this either.

Also documents the day-boundary effect (1-2% of tasks have odd ratios
when started near midnight UTC) and the marginal-vs-attributed
distinction (don't read per-tree numbers as "what we would save by
killing this tree" since pool overhead is largely fixed).

Per-tree totals from the skill should be read as VM-compute,
attributable share, +/-10-15%, with an additional ~12% systematic
understatement of total Azure cost if quoting full Azure spend.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant