Skip to content

[datadog_service_level_objective] Add ignore_tag_keys to monitors and SLOs (SDKv2)#3835

Open
j10czar wants to merge 9 commits into
masterfrom
jason.tenczar/apir-2522-ignore-tags
Open

[datadog_service_level_objective] Add ignore_tag_keys to monitors and SLOs (SDKv2)#3835
j10czar wants to merge 9 commits into
masterfrom
jason.tenczar/apir-2522-ignore-tags

Conversation

@j10czar
Copy link
Copy Markdown

@j10czar j10czar commented May 29, 2026

[datadog_monitor, datadog_service_level_objective] Add ignore_tag_keys (SDKv2)

APIR-2522

Summary

Adds an ignore_tag_keys attribute to the SDKv2 datadog_monitor and datadog_service_level_objective resources. It lets users keep specific tag keys managed outside Terraform (e.g. set in the Datadog UI or by a tagging service) without terraform plan reporting perpetual drift on every run. All other tags are managed normally.

Motivation: customers manage some tags out-of-band on monitors/SLOs and currently see Terraform fight those tags on every apply. ignore_tag_keys lets them opt specific keys out of Terraform's control without giving up management of the rest.

How it works

The logic is centralized, not per-resource:

  • utils.StripIgnoredTags(planTags, stateTags, ignoreKeys) (datadog/internal/utils/tags.go) — an SDK-agnostic helper. For any key in ignore_tag_keys, it keeps the value from state (i.e. what's really on the resource) instead of the planned/config value; all non-ignored tags pass through unchanged. Normalization/casing is handled via a tagKey helper so matching is consistent.
  • tagDiff (datadog/provider.go) — the existing provider-wide CustomizeDiff hook. When a resource declares ignore_tag_keys, tagDiff calls StripIgnoredTags and writes the result back with d.SetNew("tags", …). This runs before the default_tags merge, so a default value can never re-introduce drift on an ignored key.

Because the filter lives in the shared tagDiff, the per-resource change is just declaring the schema attribute.

Usage

Monitor:

resource "datadog_monitor" "example" {
  name    = "[example] cpu"
  type    = "metric alert"
  query   = "avg(last_5m):avg:system.cpu.user{*} > 90"
  message = "CPU high"

  tags            = ["team:api-reliability", "env:prod", "domain:engineering"]
  ignore_tag_keys = ["domain"]   # `domain` is managed outside Terraform — ignore its drift
}

SLO:

resource "datadog_service_level_objective" "example" {
  name = "[example] availability"
  type = "metric"

  query {
    numerator   = "sum:requests.success{*}.as_count()"
    denominator = "sum:requests.total{*}.as_count()"
  }
  thresholds {
    timeframe = "7d"
    target    = 99.9
  }

  tags            = ["team:api-reliability", "domain:engineering"]
  ignore_tag_keys = ["domain"]
}

With ignore_tag_keys = ["domain"], changing the domain tag in the Datadog UI no longer shows as drift, and Terraform won't strip it on apply. Multi-valued keys (e.g. team:a, team:b) are preserved together. ignore_tag_keys takes precedence over default_tags for the same key.

Extending to other SDKv2 resources (easy, by design)

Adding ignore_tag_keys to another SDKv2 resource is a 2-line schema change, no new logic:

  1. Make sure tagDiff is in the resource's CustomizeDiff (most taggable resources already have it for default_tags).
  2. Declare the ignore_tag_keys attribute in the resource schema.

tagDiff is a no-op for resources that don't declare the attribute (d.GetOk("ignore_tag_keys") returns false), so this is fully backward-compatible — existing resources are unaffected. All the filtering/normalization/ordering behavior is inherited from the shared tagDiff + StripIgnoredTags, so new opt-ins get correct behavior for free.

Framework status (intentionally out of scope)

The Plugin Framework version of these resources is not included here — it turned out to be a much larger change than SDKv2, and is parked on a separate branch (jason.tenczar/apir-2522-ignore-tags-framework)

Short version of why: the framework enforces a strict plan-consistency rule that SDKv2 doesn't. For an Optional + Computed attribute, the provider may only plan the config value or the attribute's own prior state value — not a value pulled from elsewhere. The framework monitor deliberately separates tags (user config) from effective_tags (API truth), so the real value of an ignored key lives in effective_tags state, not tags state. Planning it onto tags produces a hard Provider produced invalid plan error. Making it work would require turning tags into a full API mirror (refresh-from-API on read, subtracting default_tags) — a behavior change for every user of the resource, plus a first-plan chicken-and-egg. SDKv2 sidesteps all of this because its tags already mirrors the API and old SDKv2 resources get a legacy plan-consistency relaxation the framework removed.

Testing

  • Unit tests (make test) — TestStripIgnoredTagsNormalization (15 sub-cases) + TestTagNormalization pass. Covers empty-ignore short-circuit, create (no state), single- and multi-valued ignored keys, bare keys, mixed-case/normalization, ignored-key-absent, and "non-ignored key still surfaces drift."
  • Manual staging end-to-end (ddstaging, monitor + SLO):
    • Drift on an ignored key → No changes (suppressed).
    • Drift on a non-ignored key → diff shown for only that key (control).
    • default_tags + ignored key on the same key → default does not clobber the ignored value.
    • Adding ignore_tag_keys after drift already exists → handled with no error.
    • tags = [] with ignore_tag_keys → non-ignored tags clear, ignored key preserved; without ignore_tag_keys, everything clears (control).
  • Acceptance testTestAccDatadogMonitor_IgnoreTagKeys running in CI with recorded cassettes.

pr description assisted by claude code

@j10czar j10czar requested review from a team as code owners May 29, 2026 18:44
@datadog-prod-us1-4

This comment has been minimized.

@j10czar j10czar changed the title [datadog_monitor, datadog_service_level_objective] Add ignore_tag_keys (SDKv2) [datadog_service_level_objective] Add ignore_tag_keys to monitors and SLOs (SDKv2) May 29, 2026
@DataDog DataDog deleted a comment from datadog-prod-us1-4 Bot May 29, 2026
@urseberry urseberry self-assigned this May 29, 2026
Comment thread docs/resources/service_level_objective.md Outdated
Comment thread docs/resources/monitor.md Outdated
Comment thread datadog/provider.go
Copy link
Copy Markdown
Member

@Supam Supam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One comment, but the PR otherwise looks good.

j10czar and others added 4 commits June 1, 2026 09:40
Co-authored-by: Ursula Chen <58821586+urseberry@users.noreply.github.com>
Co-authored-by: Ursula Chen <58821586+urseberry@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants