Chapter 8: Identity & Access on GCP
Topic 55

Labels, Tags, and Network Tags

MetadataComparison

GCP has three unrelated systems that all sound like "tags," and engineers conflate them constantly — with real consequences when the wrong one is used for IAM or firewalls. Labels are key/value metadata for billing breakdowns and organization. Resource Manager tags (google_tags_tag_key, _value, _binding) are a separate, governed system whose values can be targeted by IAM conditions and org policies. Network tags are plain strings stamped on a VM that firewall rules and routes match against.

They are not interchangeable. Using a label where a tag is required — or a network tag where a Resource Manager tag is — silently fails to do what you wanted, with no error to tell you. An AWS engineer arrives expecting one unified tag system that does cost, IAM conditions, and grouping at once; on GCP that one job is split across three mechanisms with different APIs and different Terraform resources. Knowing which is which is the whole topic.

Labels — Billing and Organization

Labels are free-form key/value pairs on most resources — labels = { team = "data", env = "prod" } — surfaced in billing exports and resource filters. They organize resources and attribute cost, and that is all. Nothing keys IAM off a label, and no firewall rule matches one. A label carries no access-control or policy meaning whatsoever; it is metadata for humans and cost reports.

The provider's default_labels stamps a consistent set across everything it manages, which is the practical way to get team, env, and cost-center onto every resource without repeating them. Use labels for billing attribution and filtering — and stop there, because the moment you expect a label to gate access you have reached for the wrong system.

Labels — billing and organization only, no access meaning
resource "google_storage_bucket" "raw" {
  name     = "hatch-events-raw"
  location = "US"
  labels = {
    team = "data"      # shows up in billing export and filters
    env  = "prod"      # invisible to IAM conditions and firewalls
  }
}

Resource Manager Tags — Governed and IAM-Aware

google_tags_tag_key, google_tags_tag_value, and google_tags_tag_binding define a controlled vocabulary — a key environment with values prod and staging — and bind a value to a resource. Their distinguishing power is that IAM conditions and org policies can target them: you can grant a role only on resources tagged environment=prod, or write an org policy that keys off the tag. The tag values themselves have IAM controlling who may apply them, so the classification is governed, not free-form.

This is the system to reach for when a resource's classification must drive access control. The configuration below defines the key and value, then binds the value to a project — after which an IAM condition can reference that tag. Where a label is invisible to IAM, a Resource Manager tag is exactly what an IAM condition or org policy is built to target.

Resource Manager tags — a governed vocabulary IAM can target
resource "google_tags_tag_key" "environment" {
  parent     = "organizations/123456789012"
  short_name = "environment"
}

resource "google_tags_tag_value" "prod" {
  parent     = google_tags_tag_key.environment.id
  short_name = "prod"
}

resource "google_tags_tag_binding" "app_prod" {
  parent    = "//cloudresourcemanager.googleapis.com/projects/hatch-app-prod"
  tag_value = google_tags_tag_value.prod.id   # IAM conditions can key off this
}

Network Tags — Firewall and Route Targeting

Network tags are plain strings in a VM's tags list — ["web", "ssh-allowed"] — and they have nothing to do with the other two systems. A firewall rule's target_tags and source_tags, and a route's tags, match these strings to decide which traffic reaches which VMs. There is no key, no governance, no billing role — just a label a firewall rule looks for. A network tag never appears in a cost report and is invisible to IAM.

There is a security caveat: anyone who can edit an instance's tags can pull it into a permissive firewall rule by adding the right string. For sensitive VMs, service-account-based firewall targeting is the tighter alternative — a firewall rule that matches the VM's service account cannot be subverted by editing a free-form tag list. Use network tags for ordinary targeting, but do not make them the sole gate in front of sensitive workloads.

Three systems, one word — pick by what it must drive
Labels
Free-form key/value (labels = {}) for billing breakdowns and organization; invisible to IAM and firewalls.
Resource Manager tags
A governed vocabulary (google_tags_tag_key / _value / _binding) that IAM conditions and org policies can target.
Network tags
Plain strings in a VM's tags = [] that firewall rules and routes match; no billing or IAM meaning.

Why They Get Confused

All three are colloquially "tags," which is the root of the confusion, and the AWS mental model makes it worse. AWS tags are one system that spans cost allocation, IAM Condition keys, and grouping all at once. The AWS engineer reaches for "tags" expecting that unified behavior and gets one of three GCP systems that each do only a slice of it. A label that does not gate IAM, a network tag that does not show in billing, a Resource Manager tag that a firewall rule ignores — each is "working as designed," just not the design the AWS habit assumed.

Choosing the Right One

The rule is short. Use labels to attribute cost and group resources. Use Resource Manager tags when you need IAM conditions or org policies to target a resource's classification. Use network tags only to wire VMs to firewall rules and routes. And never expect a label to gate access or a network tag to show up in billing — those are the two crossings that silently do nothing, and they are the ones engineers reach for most.

The Three "Tag" Systems

Labels (labels = {}) — free-form key/value for billing and organization, with no access or firewall meaning. Use for cost attribution and filtering.

Resource Manager tags (google_tags_tag_key / _value / _binding) — a governed key/value vocabulary that IAM conditions and org policies can target. Use when a classification must drive access control.

Network tags (a VM's tags = [] strings) — plain labels that firewall rules and routes match. Use only to target network traffic to VMs, and prefer service-account targeting for sensitive ones.

Common Mistakes
  • Expecting a label (env = "prod") to gate IAM — labels are invisible to IAM conditions; you need a Resource Manager tag for a condition or org policy to target the resource.
  • Putting a string in a VM's network tags and expecting it in the billing export, or putting a billing label on a VM and expecting a firewall rule to match it — the two systems never see each other.
  • Using google_tags_tag_binding (the governed tag) where a simple network tag was needed to target a firewall rule, or the reverse — the firewall rule matches network-tag strings, not Resource Manager tags.
  • Leaving network tags as the sole firewall-targeting mechanism for sensitive VMs — anyone who can edit an instance's tags can pull it into a permissive rule; service-account-based targeting is the tighter alternative.
  • Treating GCP labels as AWS tags that "do everything" — cost, access, and grouping are three separate GCP systems, and assuming one unifies them leads to grants and rules that silently do nothing.
Best Practices
  • Stamp labels consistently (team, env, cost-center) — via the provider's default_labels for breadth — and use them for billing attribution and filtering only.
  • Use Resource Manager tags (google_tags_tag_key / _value / _binding) when a resource's classification must drive an IAM condition or an org policy, and control who may apply each tag value.
  • Use network tags strictly for firewall and route targeting on VMs, and prefer service-account-based firewall targeting for sensitive workloads since network tags are editable by anyone who can edit the instance.
  • Document which of the three systems your org uses for which purpose, so nobody reaches for a label expecting access control or a network tag expecting billing.
  • Reference tag and value IDs from their Terraform resources rather than hardcoding them, so a renamed key or value never silently breaks a binding.
Comparable models AWS tags a single system spanning cost allocation, IAM Condition keys, and grouping — the source of the confusion, since GCP splits that job across three Azure tags the partial analog gcloud resource-manager tags · gcloud compute instances add-tags the two distinct imperative forms

Knowledge Check

Which "tag" system can an IAM condition or org policy target to drive access control?

  • Resource Manager tags (google_tags_tag_key / _value / _binding)
  • Labels (labels = {})
  • Network tags (a VM's tags = [] strings)
  • All three, since labels, network tags, and Resource Manager tags are interchangeable metadata that IAM reads

You set labels = { env = "prod" } on a bucket and write an IAM condition expecting it to scope a grant. What happens?

  • Nothing scopes — labels are invisible to IAM conditions, so the condition cannot see the label and the intended tightening never applies
  • The grant is correctly scoped to only the prod-labelled buckets, since labels and Resource Manager tags share the same underlying metadata system
  • The apply errors out at plan time, refusing to let a CEL condition reference a label that IAM cannot resolve
  • The label is automatically converted into a Resource Manager tag

A firewall rule needs to target a set of VMs. Which system does its target_tags match against?

  • Network tags — the plain strings in a VM's tags list
  • Labels on the VM resource, matched by their key and value
  • Resource Manager tag bindings attached to the VM resource
  • The VM's billing cost-center label attached for chargeback

Why is service-account-based firewall targeting preferred over network tags for sensitive VMs?

  • Anyone who can edit an instance's tags can add a string that pulls it into a permissive rule; a service account cannot be subverted that way
  • Network tags are written into the BigQuery billing export and leak the VM's intended purpose to anyone who can read the organization's cost reports
  • Service-account targeting is faster to evaluate at the packet level, so the firewall adds less latency per connection
  • Network tags can only target up to two VMs per rule

You got correct