cloudflare / terraform-provider-cloudflare

Cloudflare Terraform Provider
https://registry.terraform.io/providers/cloudflare/cloudflare
Mozilla Public License 2.0
805 stars 620 forks source link

Modifying imported Page Rules fails - Plugin did not respond #3318

Open liran19 opened 6 months ago

liran19 commented 6 months ago

Confirmation

Terraform and Cloudflare provider version

Terraform v1.3.10 provider registry.terraform.io/cloudflare/cloudflare v4.32.0 (tried with 4.33.0 - the latest - as well)

Affected resource(s)

cloudflare_page_rule

Terraform configuration files

Module -
terraform {
  required_providers {
    cloudflare = {
      source  = "cloudflare/cloudflare"
      version = "~> 4.0"
    }
  }
}

terraform {
  required_version = ">= 1.3.0"
}

resource "cloudflare_page_rule" "page_rule" {
  for_each = {
    for k in var.cloudflare_page_rule : k.target => k
  }
  target   = each.value.target
  zone_id  = each.value.zone_id
  priority = each.value.priority
  status   = each.value.status != null ? each.value.status : "active"

  actions {
    always_use_https            = lookup(each.value.actions, "always_use_https", false)
    automatic_https_rewrites    = lookup(each.value.actions, "automatic_https_rewrites")
    browser_cache_ttl           = lookup(each.value.actions, "browser_cache_ttl")
    browser_check               = lookup(each.value.actions, "browser_check")
    bypass_cache_on_cookie      = lookup(each.value.actions, "bypass_cache_on_cookie")
    cache_by_device_type        = lookup(each.value.actions, "cache_by_device_type")
    cache_deception_armor       = lookup(each.value.actions, "cache_deception_armor")
    cache_level                 = lookup(each.value.actions, "cache_level")
    cache_on_cookie             = lookup(each.value.actions, "cache_on_cookie")
    disable_apps                = lookup(each.value.actions, "disable_apps")
    disable_performance         = lookup(each.value.actions, "disable_performance")
    disable_railgun             = lookup(each.value.actions, "disable_railgun")
    disable_security            = lookup(each.value.actions, "disable_security")
    disable_zaraz               = lookup(each.value.actions, "disable_zaraz")
    edge_cache_ttl              = lookup(each.value.actions, "edge_cache_ttl")
    email_obfuscation           = lookup(each.value.actions, "email_obfuscation")
    explicit_cache_control      = lookup(each.value.actions, "explicit_cache_control")
    host_header_override        = lookup(each.value.actions, "host_header_override")
    ip_geolocation              = lookup(each.value.actions, "ip_geolocation")
    mirage                      = lookup(each.value.actions, "mirage")
    opportunistic_encryption    = lookup(each.value.actions, "opportunistic_encryption")
    origin_error_page_pass_thru = lookup(each.value.actions, "origin_error_page_pass_thru")
    polish                      = lookup(each.value.actions, "polish")
    resolve_override            = lookup(each.value.actions, "resolve_override")
    respect_strong_etag         = lookup(each.value.actions, "respect_strong_etag")
    response_buffering          = lookup(each.value.actions, "response_buffering")
    rocket_loader               = lookup(each.value.actions, "rocket_loader")
    security_level              = lookup(each.value.actions, "security_level")
    server_side_exclude         = lookup(each.value.actions, "server_side_exclude")
    sort_query_string_for_cache = lookup(each.value.actions, "sort_query_string_for_cache")
    ssl                         = lookup(each.value.actions, "ssl")
    true_client_ip_header       = lookup(each.value.actions, "true_client_ip_header")
    waf                         = lookup(each.value.actions, "waf")

    forwarding_url {
      status_code = lookup(each.value.actions, "status_code")
      url         = lookup(each.value.actions, "url")
    }

    minify {
      css  = each.value.actions.minify_css != null ? each.value.actions.minify_css : "off"
      html = each.value.actions.minify_html != null ? each.value.actions.minify_html : "off"
      js   = each.value.actions.minify_js != null ? each.value.actions.minify_js : "off"
    }

    cache_key_fields {
      header {
        check_presence = lookup(each.value.actions, "header_presence")
        exclude        = lookup(each.value.actions, "header_exclude")
        include        = lookup(each.value.actions, "header_include")
      }

      cookie {
        check_presence = lookup(each.value.actions, "cookie_presence")
        include        = lookup(each.value.actions, "cookie_include")
      }

      host {
        resolved = lookup(each.value.actions, "resolved", false)
      }

      query_string {
        exclude = lookup(each.value.actions, "query_exclude")
        include = lookup(each.value.actions, "query_include")
        ignore  = lookup(each.value.actions, "ignore", false)
      }

      user {
        device_type = lookup(each.value.actions, "device_type", false)
        geo         = lookup(each.value.actions, "geo", false)
        lang        = lookup(each.value.actions, "lang", false)
      }
    }

    dynamic "cache_ttl_by_status" {
      for_each = each.value.actions.cache_ttl_by_status != null ? lookup(each.value.actions, "cache_ttl_by_status", []) : []

      content {
        codes = lookup(cache_ttl_by_status.value, "codes")
        ttl   = lookup(cache_ttl_by_status.value, "ttl")
      }
    }
  }
}

Env-

module "cloudflare_page_rules" {
  source = "REDACTED"

  cloudflare_page_rule = [
    {
      actions = {
        status_code = "REDACTED"
        url         = "REDACTED"
      }
      target  = "REDACTED"
      zone_id = var.zone_id
    }
  ]
}

Link to debug output

https://gist.github.com/liran19/4d1248a8870cd27cb2a2b50ccc9b1bf2

Panic output

│ Error: Plugin did not respond
│ 
│ The plugin encountered an error, and failed to respond to the
│ plugin6.(*GRPCProvider).ApplyResourceChange call. The plugin logs may
│ contain more details.
╵

Stack trace from the terraform-provider-cloudflare_v4.32.0 plugin:

panic: interface conversion: interface {} is nil, not map[string]interface {}

goroutine 133 [running]:
github.com/cloudflare/terraform-provider-cloudflare/internal/sdkv2provider.transformToCloudflarePageRuleAction({0x1f29020, 0xc00017c460}, {0x1cb2b85, 0x10}, {0x15aed40?, 0xc001290a98?}, 0xc000abcd28?)
        github.com/cloudflare/terraform-provider-cloudflare/internal/sdkv2provider/resource_cloudflare_page_rule.go:487 +0x12bd
github.com/cloudflare/terraform-provider-cloudflare/internal/sdkv2provider.resourceCloudflarePageRuleUpdate({0x1f29020, 0xc00017c460}, 0xc000e18a80, {0x1ca28c0?, 0xc000dfa160?})
        github.com/cloudflare/terraform-provider-cloudflare/internal/sdkv2provider/resource_cloudflare_page_rule.go:177 +0x6f9
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).update(0xc0008fd500, {0x1f28f78, 0xc001285980}, 0xd?, {0x1ca28c0, 0xc000dfa160})
        github.com/hashicorp/terraform-plugin-sdk/v2@v2.33.0/helper/schema/resource.go:812 +0x11b
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*Resource).Apply(0xc0008fd500, {0x1f28f78, 0xc001285980}, 0xc000fb4410, 0xc000f2bb80, {0x1ca28c0, 0xc000dfa160})
        github.com/hashicorp/terraform-plugin-sdk/v2@v2.33.0/helper/schema/resource.go:919 +0x83a
github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.(*GRPCProviderServer).ApplyResourceChange(0xc000010f90, {0x1f28f78?, 0xc0012857d0?}, 0xc000ff0500)
        github.com/hashicorp/terraform-plugin-sdk/v2@v2.33.0/helper/schema/grpc_provider.go:1078 +0xdbc
github.com/hashicorp/terraform-plugin-mux/tf5to6server.v5tov6Server.ApplyResourceChange({{0x1f38138?, 0xc000010f90?}}, {0x1f28f78, 0xc0012857d0}, 0x0?)
        github.com/hashicorp/terraform-plugin-mux@v0.15.0/tf5to6server/tf5to6server.go:47 +0x54
github.com/hashicorp/terraform-plugin-mux/tf6muxserver.(*muxServer).ApplyResourceChange(0x1f28fb0?, {0x1f28f78?, 0xc0012854d0?}, 0xc000ff04b0)
        github.com/hashicorp/terraform-plugin-mux@v0.15.0/tf6muxserver/mux_server_ApplyResourceChange.go:36 +0x193
github.com/hashicorp/terraform-plugin-go/tfprotov6/tf6server.(*server).ApplyResourceChange(0xc0009f8000, {0x1f28f78?, 0xc001284ae0?}, 0xc000145260)
        github.com/hashicorp/terraform-plugin-go@v0.23.0/tfprotov6/tf6server/server.go:865 +0x3d0
github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6._Provider_ApplyResourceChange_Handler({0x1bf3980?, 0xc0009f8000}, {0x1f28f78, 0xc001284ae0}, 0xc000f2a880, 0x0)
        github.com/hashicorp/terraform-plugin-go@v0.23.0/tfprotov6/internal/tfplugin6/tfplugin6_grpc.pb.go:518 +0x169
google.golang.org/grpc.(*Server).processUnaryRPC(0xc000803600, {0x1f28f78, 0xc001284a50}, {0x1f30ec0, 0xc000b6a000}, 0xc0009efb00, 0xc0009f6510, 0x2cb0878, 0x0)
        google.golang.org/grpc@v1.63.2/server.go:1369 +0xe23
google.golang.org/grpc.(*Server).handleStream(0xc000803600, {0x1f30ec0, 0xc000b6a000}, 0xc0009efb00)
        google.golang.org/grpc@v1.63.2/server.go:1780 +0x1016
google.golang.org/grpc.(*Server).serveStreams.func2.1()
        google.golang.org/grpc@v1.63.2/server.go:1019 +0x8b
created by google.golang.org/grpc.(*Server).serveStreams.func2 in goroutine 51
        google.golang.org/grpc@v1.63.2/server.go:1030 +0x135

Error: The terraform-provider-cloudflare_v4.32.0 plugin crashed!

This is always indicative of a bug within the plugin. It would be immensely
helpful if you could report the crash with the plugin's maintainers so that it
can be fixed. The output above should help diagnose the issue.

Operation failed: failed running terraform apply (exit 1)

Expected output

Modification of the existing page rules

Actual output

│ Error: Plugin did not respond │ │ The plugin encountered an error, and failed to respond to the │ plugin6.(*GRPCProvider).ApplyResourceChange call. The plugin logs may │ contain more details. ╵

Steps to reproduce

  1. Import an existing Page Rule
  2. Terraform Plan - Should give positive output (added in the gist file)
  3. Terraform apply (using both 4.32 and 4.33) - to get the Panic error.

Additional factoids

There are some mandatory fields in the page rules resource, and that's why, during the plan, they are being added with default values, and I don't get the " Your infrastructure matches the configuration."

References

No response

github-actions[bot] commented 6 months ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

jacobbednarz commented 6 months ago

the error you've listed here is not the problem here; it is only a symptom.

Stack trace from the terraform-provider-cloudflare_v4.32.0 plugin:

panic: interface conversion: interface {} is nil, not map[string]interface {}

is the issue. as this is reproduction includes dynamics (and likely includes its own logic bugs), i'm sorry but we can't debug it. if you can reproduce the problem without using them, i'm happy to triage.

tibbing commented 5 months ago

Observing similar issue in the latest version of the provider (4.36.0). Works fine in 4.34.0.

Stack trace from the terraform-provider-cloudflare_v4.36.0 plugin:

panic: interface conversion: interface {} is nil, not []interface {}

goroutine 32 [running]:
github.com/cloudflare/terraform-provider-cloudflare/internal/sdkv2provider.resourceCloudflareZoneSettingsOverrideStateUpgradeV1.func1(...)
        github.com/cloudflare/terraform-provider-cloudflare/internal/sdkv2provider/resource_cloudflare_zone_settings_override_migrate.go:46