Cost Tags
Use costTags to declare which cloud resources belong to a service. Each entry is a
match rule: a discovered cloud resource is attributed to the service when one of its
tags matches a rule's key and value exactly.
Cost tags feed the billing views — cost summary, resource list, and spend trend — for the service they are declared on.
Config shape
service:
name: Booking Service
category: Backend
description: Handles booking lifecycle and availability
repository:
provider: github
url: https://github.com/company/booking-service
ownership:
team: platform
costTags:
- key: team
value: checkout
- key: Service
value: booking-api
- key: env
value: production
The section is a declarative set
This is the part worth reading twice. The CLI treats costTags as the full,
authoritative set of rules for the service:
| Config | Effect on sync |
|---|---|
costTags omitted entirely | Not managed by the CLI. Existing rules are left alone. |
costTags with entries | This file owns the set. Rules listed here are created; any rule in UIGraph that is not listed here is deleted. |
costTags: [] | An empty but present set. Every rule on the service is deleted. |
So a rule added by hand in the UI on a service whose .uigraph.yaml declares
costTags will disappear on the next sync. Manage the tags in one place: either the
config file or the UI, not both.
Field reference
| Field | Type | Required | Description |
|---|---|---|---|
key | string | yes | Cloud resource tag key. Matched exactly, case-sensitive. |
value | string | yes | Cloud resource tag value. Matched exactly, case-sensitive. |
Rules:
-
keyandvaluemust both be non-empty. -
The
key/valuepair must be unique within the list. Two entries with the same key and the same value fail validation:costTags[2]: duplicate key/value pair "team=checkout" -
The same
keymay appear more than once with different values — that is how you attribute a service that spans several tag values. -
A
serviceblock is required. A config without a service cannot sync cost tags:service is required to sync costTags; configs without a service may only sync maps and frames
How matching works
A resource is linked to the service when at least one rule matches. Matching is on
the exact tag key and the exact tag value, so env=production does not match a
resource tagged env=Production, and Service=booking-api does not match a resource
tagged service=booking-api. Copy the tag keys exactly as your cloud provider reports
them.
Multiple rules are OR-ed together. The three rules in the example above attribute every
resource tagged team:checkout, plus every resource tagged Service:booking-api, plus
every resource tagged env:production.
Sync output
Cost tags are synced as their own step. The summary at the end of a run reports the reconciliation:
Cost Tags: 3 (1 created, 1 deleted, 2 unchanged)
--dry-run prints the tags that would be sent under a === DRY RUN: Cost Tags ===
header and sends nothing.
Token scope
The service-account token needs billing:write to create and delete tag rules. A token
without it gets a 403 on this step and the CLI stops there with exit code 2, leaving
the later steps of the sync unapplied. Reading cost summaries requires billing:read.