# Job Missing Cost-Allocation Tags

> Jobs spend in bursts: each run spins up a job cluster, bills DBUs plus VMs, and vanishes minutes later. Tags on the job definition are what stitch those ephemeral runs back to an owner, so ZopNight checks every job for the 3 keys: team, environment, and cost-center.

Source: https://zop.dev/integrations/databricks/recommendations/job-missing-cost-allocation-tags
Updated: 2026-08-19

---

## Attribution per run, not per machine

A job's cost profile is the inverse of a cluster's. There is no long-lived machine to
point at. Each scheduled run provisions a job cluster, burns DBUs and VM-hours for
its duration, and tears itself down. By the time anyone reviews the bill, the compute
that generated it no longer exists. The only durable object in that lifecycle is the
job definition itself, which is why the definition is where the cost-allocation keys
have to live: tags set there ride along to every run.

## Definitions never sleep, so the check never gates

ZopNight's cluster and warehouse tag rules skip stopped resources because stopped
compute is not current spend. Jobs get no such gate, deliberately. A job definition
has no power state, and a job that is untagged today will produce untagged spend at
its next scheduled fire whether that is in an hour or a month. Every job is checked,
every time, for the same 3 keys the rest of the platform uses: `team`, `environment`,
and `cost-center`. Any one of them missing produces the finding, naming exactly which
keys are absent. A tag blob that fails to parse yields no finding rather than a
guessed one.

## Dump job tags across the workspace

```bash
databricks api get '/api/2.1/jobs/list?limit=25&expand_tasks=false' | jq '
  .jobs[]
  | {job_id, name: .settings.name,
     missing: (["team", "environment", "cost-center"]
               - ((.settings.tags // {}) | keys))}
  | select(.missing | length > 0)'
```

Page through with the returned `next_page_token` on workspaces with more than 25 jobs.

## Where the tags travel

Tags on a job propagate to the job clusters launched for its runs, and from there to
the underlying cloud VMs, so a correctly tagged job produces per-run spend that both
Databricks system tables and the cloud provider's cost tools can group by team. That
chain is what makes the job key set worth enforcing: one field on the definition
labels every future run's infrastructure.

## Closing the gap for good

Backfill the missing keys on the jobs this finding lists, then make tagging part of
how jobs are born: deployment pipelines that create jobs via the API should refuse
specs without the 3 keys, and job clusters can additionally be bound to policies that
require them. Definitions created by hand in the UI are the leak to watch.
