Skip to content

monitoring: fix alert_policy mime_type permadiff on imported policies (#25127)#69

Open
jbbqqf wants to merge 11 commits into
mainfrom
feat/25127-monitoring-alert-policy-mime-type-permadiff
Open

monitoring: fix alert_policy mime_type permadiff on imported policies (#25127)#69
jbbqqf wants to merge 11 commits into
mainfrom
feat/25127-monitoring-alert-policy-mime-type-permadiff

Conversation

@jbbqqf

@jbbqqf jbbqqf commented May 9, 2026

Copy link
Copy Markdown
Owner

Summary

Replace default_value: "text/markdown" with default_from_api: true on google_monitoring_alert_policy.documentation.mime_type, so that imported alert policies (or policies whose API response omits mime_type) stop showing a permanent diff to add mime_type = "text/markdown".

Fixes hashicorp/terraform-provider-google#25127 — see hashicorp/terraform-provider-google#25127

Why

The OP and a second reporter (dale-c-anderson) both confirm the bug only triggers on imported alert policies. The plan after terraform import consistently shows:

~ documentation {
    + mime_type = "text/markdown"
      # (2 unchanged attributes hidden)
}

What is happening:

  1. default_value: "text/markdown" in the mmv1 YAML lowers to Default: "text/markdown" on the Terraform schema (see resource_monitoring_alert_policy.go:1218).
  2. terraform import calls Read, which calls the flatten path. For an alert policy whose documentation has only a subject (or only links), the API response often omits mime_type entirely. The flatten therefore stores nil/empty in state.
  3. On the next plan, the schema's Default re-injects "text/markdown" because nothing is set, and the framework reports a diff against the empty state value. Hence the perpetual + mime_type = "text/markdown".

The reverse (creating from scratch) doesn't hit this because the API echoes the mime_type back during create, so state is populated.

default_from_api: true is the standard mmv1 idiom for "let the API decide": the schema becomes Optional + Computed (no schema-side Default), so when the API doesn't return mime_type the state stays empty and the planner doesn't try to fill it back in.

GCP API reference: https://cloud.google.com/monitoring/api/ref_v3/rest/v3/projects.alertPolicies#DocumentationmimeType is documented as defaulting to "text/markdown" server-side.

What changed

mmv1/products/monitoring/AlertPolicy.yaml | 2 +-

One YAML line changed: default_value: "text/markdown"default_from_api: true.

Edge cases tested

# Scenario Expected Verified by
1 Imported alert policy with documentation { subject = "x" } (no content) API omits mime_type from the response. State stays empty. Plan: no diff. Static — default_from_api: true produces Optional+Computed (and no Default); when state is empty and config is empty, no diff.
2 New alert policy with documentation { content = "x" mime_type = "text/markdown" } API echoes mime_type = "text/markdown". State and config match → no diff. Static — same flow as today, just without the redundant schema default.
3 New alert policy with documentation { content = "x" } (no mime_type) API stores the server default "text/markdown". Read populates state. Subsequent plans see Optional+Computed field with state value matching API → no diff. Static — server default behavior documented in the linked API ref.
4 User changes mime_type from "text/markdown" to a different value Real change — should show diff and apply. Static — Optional is unchanged; the planner still detects user-set value differences.

Test protocol

Test Result Notes
YAML lint / mmv1 generation n/a in this PR Will be exercised by mmv1 CI. The change is a 1-line attribute swap; both default_value and default_from_api are well-trodden fields.
Live BEFORE/AFTER smoke not run Reproducing the bug requires (a) creating an alert policy via gcloud or the console, (b) running terraform import, (c) running plan twice — that's 4 GCP operations gated on a separately-created resource and not friendly to the smoke harness's apply→destroy model. The fix is structurally complete: default_from_api: true is the documented idiom for exactly this scenario, and the same swap was the resolution to several similar permadiff issues in mmv1 history (e.g. beyondcorp, storagecontrol).

Resources

Disclosure

This PR was implemented with assistance from Claude Code as part of a focused contribution batch. The diff is one YAML line; it was reviewed manually against the generated Go schema and the mmv1 doctrine (default_value injects a Default: clause that fights with API omissions, while default_from_api: true makes the schema Optional+Computed).

jcromanu and others added 11 commits May 8, 2026 16:43
…ion (#25127)

Replace default_value: "text/markdown" with default_from_api: true on
documentation.mime_type. The schema Default was producing a permadiff
on imported alert_policy resources whose API response did not echo back
the mime_type (typically when documentation has subject/links but no
content). With default_from_api the schema becomes Optional+Computed,
so the field is read from the API and not re-injected by the schema at
plan time.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.

google_monitoring_alert_policy always wants to add mime_type to documentation (even after applying that exact change)

8 participants