Skip to content

cloudflare_notification_policy: webhooks_integration ID format inconsistency causes persistent drift #6455

@d33psky

Description

@d33psky

cloudflare_notification_policy: webhooks_integration ID format inconsistency causes persistent drift

Summary

The webhooks_integration block in cloudflare_notification_policy shows persistent drift on every plan due to inconsistent UUID formatting between resource creation and API reads. The webhook ID is returned with hyphens during creation but without hyphens when referenced in notification policies, causing Terraform to detect a change even though the UUID is functionally identical.

Terraform and Provider Versions

  • Provider Version: 4.52.5
  • Terraform/OpenTofu Version: 1.8.0
  • OS: Linux (GitHub Actions Ubuntu runner)

Affected Resources

  • cloudflare_notification_policy_webhooks (creates ID with hyphens)
  • cloudflare_notification_policy (reads webhook ID without hyphens)

Terraform Configuration

resource "cloudflare_notification_policy_webhooks" "slack" {
  account_id = var.account_id
  name       = "Slack"
  url        = var.slack_webhook_url
  secret     = var.slack_webhook_secret
}

resource "cloudflare_notification_policy" "lb_pool_health" {
  account_id  = var.account_id
  name        = "LB Pool Health - lb.shapeways.com"
  description = "Alerts when load balancer pools become healthy or unhealthy"
  enabled     = true
  alert_type  = "load_balancing_health_alert"

  webhooks_integration {
    id = cloudflare_notification_policy_webhooks.slack.id
  }

  filters {
    pool_id = var.lb_pool_ids
    new_health = ["Unhealthy", "Healthy"]
  }
}

Steps to Reproduce

  1. Create a cloudflare_notification_policy_webhooks resource
  2. Reference it in a cloudflare_notification_policy resource via webhooks_integration.id
  3. Apply successfully (creates webhook ID: 0dd1a176-3adf-44dc-9ece-dec98a7cff6e)
  4. Run terraform plan again

Expected Behavior

After successful apply, subsequent plans should show "No changes" since the webhook integration hasn't changed.

Actual Behavior

Every plan shows a persistent drift:

  # cloudflare_notification_policy.lb_pool_health[0] will be updated in-place
  ~ resource "cloudflare_notification_policy" "lb_pool_health" {
        id          = "2ce704b6e10b49c0aa7626b31c818ded"
        name        = "LB Pool Health - lb.shapeways.com"
        # (6 unchanged attributes hidden)

      - webhooks_integration {
          - id   = "0dd1a1763adf44dc9ecedec98a7cff6e" -> null  # WITHOUT HYPHENS
          - name = "Slack" -> null
        }
      + webhooks_integration {
          + id = "0dd1a176-3adf-44dc-9ece-dec98a7cff6e"        # WITH HYPHENS
        }

        # (1 unchanged block hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

However, applying this plan doesn't actually change anything - the drift persists on the next plan.

Root Cause

The UUIDs are functionally identical:

  • With hyphens: 0dd1a176-3adf-44dc-9ece-dec98a7cff6e (from webhook resource)
  • Without hyphens: 0dd1a1763adf44dc9ecedec98a7cff6e (from API read)

CloudFlare's API appears to return webhook IDs inconsistently:

  • Webhook creation returns canonical UUID format (with hyphens)
  • Notification policy reads return UUID without hyphens

Impact

  • Every terraform plan shows unnecessary drift
  • Reduces confidence in plan output
  • Makes it harder to detect real configuration changes
  • No functional impact (notifications work correctly)

Workaround

Add lifecycle rule to ignore the cosmetic drift:

resource "cloudflare_notification_policy" "example" {
  # ... configuration ...

  lifecycle {
    ignore_changes = [webhooks_integration]
  }
}

Related Issues

Additional Context

This appears to be a normalization issue where the provider should canonicalize UUIDs to a consistent format (preferably with hyphens per RFC 4122) before comparing state.

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugCategorizes issue or PR as related to a bug.version/4Categorizes issue or PR as related to version 4 of the provider.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions