cloudflare / terraform-provider-cloudflare

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

Encountered an error while destroying a cloudflare_zone_settings_override resource due to an invalid value for first_party_fonts feature. #3520

Closed Hige closed 3 months ago

Hige commented 3 months ago

Confirmation

Terraform and Cloudflare provider version

Terraform v1.9.2 on linux_amd64

Affected resource(s)

cloudflare_zone_settings_override

Terraform configuration files

resource "cloudflare_zone_settings_override" "dns_zone_settings_override" {
  depends_on   = [cloudflare_zone.dns_managed_zone]
  count = var.zone.is_settings_override == true ? 1 : 0

  zone_id  = cloudflare_zone.dns_managed_zone.id

  settings {
    ssl = try(var.zone.settings.ssl, "off")
    origin_max_http_version = try(var.zone.settings.origin_max_http_version, "2")

    http2 = null
    mirage = null
    origin_error_page_pass_thru = null
    polish = null
    prefetch_preload = null
    proxy_read_timeout = null
    response_buffering = null
    sort_query_string_for_cache = null
    true_client_ip_header = null
    webp = null
    image_resizing = null
    fonts = null
  }
}

Link to debug output

https://gist.github.com/Hige/84d9b236c7db719de64c5b400e77ee34#file-gistfile1-txt

Panic output

No response

Expected output

The cloudflare_zone_settings_override resource should be destroyed without error.

Actual output

The destruction of the cloudflare_zone_settings_override resource fails with an error related to the first_party_fonts feature.

2024-07-30T10:54:29.027+0300 [ERROR] vertex "module.zone[\"example2.com\"].cloudflare_zone_settings_override.dns_zone_settings_override[0] (destroy)" error: could not unmarshal first_party_fonts feature because "" is not a valid value, accepted values are off/on
ā•·
ā”‚ Error: could not unmarshal first_party_fonts feature because "" is not a valid value, accepted values are off/on
ā”‚ 

Steps to reproduce

Define a cloudflare_zone_settings_override resource with various settings. Apply the configuration. Attempt to destroy the resource. Important Factoids The issue seems related to the handling of the first_party_fonts feature, which is not explicitly set in the configuration.

Additional factoids

In the documentation for the resource, there is no mention of the first_party_fonts setting in the settings block list schema.

References

No response

github-actions[bot] commented 3 months ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

jacobbednarz commented 3 months ago

this is happening because of the way you're defining and setting the values dynamically. at some point, you've defined it (your state will confirm this) and the initial setting will be saved and attempted to be reset when it was deleted.

this resource shouldn't be used dynamically or with dynamic values; you will hit errors like this frequently. you should only set the values explicitly that differ from the cloudflare defaults.

Hige commented 3 months ago

You are right, I do encounter errors quite frequently. The solution to these errors is to explicitly set unwanted properties to null, for example:

polish = null

I don't quite understand what I'm doing wrong. I want to override only two settings:

ssl = try(var.zone.settings.ssl, "off")
origin_max_http_version = try(var.zone.settings.origin_max_http_version, "2")

But for some reason, I'm getting the errors you mentioned.

In this case, I don't even have the option to override the first_party_fonts property, and it's also not present in the state. Here is my state for the cloudflare_zone_settings_override resource:

{
    "module": "module.zone[\"example2.com\"]",
    "mode": "managed",
    "type": "cloudflare_zone_settings_override",
    "name": "dns_zone_settings_override",
    "provider": "provider[\"registry.terraform.io/cloudflare/cloudflare\"]",
    "instances": [
    {
      "index_key": 0,
      "schema_version": 1,
      "attributes": {
        "id": "303bb55d3c507092a5d506ce4f28c7d4",
        "initial_settings": [
          {
            "always_online": "off",
            "always_use_https": "off",
            "automatic_https_rewrites": "on",
            "binary_ast": "off",
            "brotli": "on",
            "browser_cache_ttl": 14400,
            "browser_check": "on",
            "cache_level": "aggressive",
            "challenge_ttl": 1800,
            "ciphers": [],
            "cname_flattening": "flatten_at_root",
            "development_mode": "off",
            "early_hints": "off",
            "email_obfuscation": "on",
            "filter_logs_to_cloudflare": "off",
            "fonts": "",
            "h2_prioritization": "off",
            "hotlink_protection": "off",
            "http2": "on",
            "http3": "on",
            "image_resizing": "off",
            "ip_geolocation": "on",
            "ipv6": "on",
            "log_to_cloudflare": "on",
            "max_upload": 100,
            "min_tls_version": "1.0",
            "minify": [
              {
                "css": "off",
                "html": "off",
                "js": "off"
              }
            ],
            "mirage": "off",
            "mobile_redirect": [],
            "nel": [],
            "opportunistic_encryption": "on",
            "opportunistic_onion": "on",
            "orange_to_orange": "off",
            "origin_error_page_pass_thru": "off",
            "origin_max_http_version": "2",
            "polish": "off",
            "prefetch_preload": "off",
            "privacy_pass": "on",
            "proxy_read_timeout": "100",
            "pseudo_ipv4": "off",
            "response_buffering": "off",
            "rocket_loader": "off",
            "security_header": [
              {
                "enabled": false,
                "include_subdomains": false,
                "max_age": 0,
                "nosniff": false,
                "preload": false
              }
            ],
            "security_level": "medium",
            "server_side_exclude": "on",
            "sort_query_string_for_cache": "off",
            "ssl": "full",
            "tls_1_2_only": "off",
            "tls_1_3": "on",
            "tls_client_auth": "off",
            "true_client_ip_header": "off",
            "universal_ssl": "",
            "visitor_ip": "on",
            "waf": "off",
            "webp": "off",
            "websockets": "on",
            "zero_rtt": "off"
          }
        ],
        "initial_settings_read_at": "2023-03-24T20:30:17.04831394Z",
        "readonly_settings": [
          "advanced_ddos",
          "http2",
          "long_lived_grpc",
          "mirage",
          "origin_error_page_pass_thru",
          "polish",
          "prefetch_preload",
          "proxy_read_timeout",
          "response_buffering",
          "sort_query_string_for_cache",
          "true_client_ip_header",
          "webp",
          "image_resizing"
        ],
        "settings": [
          {
            "always_online": "off",
            "always_use_https": "off",
            "automatic_https_rewrites": "on",
            "binary_ast": "off",
            "brotli": "on",
            "browser_cache_ttl": 14400,
            "browser_check": "on",
            "cache_level": "aggressive",
            "challenge_ttl": 1800,
            "ciphers": [],
            "cname_flattening": "flatten_at_root",
            "development_mode": "off",
            "early_hints": "off",
            "email_obfuscation": "on",
            "filter_logs_to_cloudflare": "off",
            "fonts": "off",
            "h2_prioritization": "off",
            "hotlink_protection": "off",
            "http2": "on",
            "http3": "on",
            "image_resizing": "off",
            "ip_geolocation": "on",
            "ipv6": "on",
            "log_to_cloudflare": "on",
            "max_upload": 100,
            "min_tls_version": "1.0",
            "minify": [
              {
                "css": "off",
                "html": "off",
                "js": "off"
              }
            ],
            "mirage": "off",
            "mobile_redirect": [],
            "nel": [
              {
                "enabled": true
              }
            ],
            "opportunistic_encryption": "on",
            "opportunistic_onion": "on",
            "orange_to_orange": "off",
            "origin_error_page_pass_thru": "off",
            "origin_max_http_version": "2",
            "polish": "off",
            "prefetch_preload": "off",
            "privacy_pass": "on",
            "proxy_read_timeout": "100",
            "pseudo_ipv4": "off",
            "response_buffering": "off",
            "rocket_loader": "off",
            "security_header": [
              {
                "enabled": false,
                "include_subdomains": false,
                "max_age": 0,
                "nosniff": false,
                "preload": false
              }
            ],
            "security_level": "medium",
            "server_side_exclude": "on",
            "sort_query_string_for_cache": "off",
            "ssl": "flexible",
            "tls_1_2_only": "off",
            "tls_1_3": "on",
            "tls_client_auth": "off",
            "true_client_ip_header": "off",
            "universal_ssl": "",
            "visitor_ip": "on",
            "waf": "off",
            "webp": "",
            "websockets": "on",
            "zero_rtt": "off"
          }
        ],
        "zone_id": "303bb55d3c507092a5d506ce4f28c7d4",
        "zone_status": "active",
        "zone_type": "full"
      },
      "sensitive_attributes": [],
      "private": "bnVsbA==",
      "dependencies": [
        "module.zone.cloudflare_zone.dns_managed_zone"
      ]
    }
  ]
},

Can you show what I'm doing wrong and how it should be done correctly? Let me know if you need any further adjustments or additional details!

jacobbednarz commented 3 months ago

setting attributes to null doesn't quite work in the way you think it does in the SDKv2. you can read more about the internals in #2170 however, just because it's null here doesn't mean that the state always gets the right version here.

one of the major problems with this resource, and why it's in the process of being killed off, is that it attempts to maintain the initial state and the desired state in order to apply the differences. there are loads of rough areas with this as it rubs up against Terraform conventions as a whole not to mention re-implements a bunch of stuff we don't really need. for that reason, the documentation recommends only setting the values you explicitly want to override (no dynamics, nulls, etc).

to get your desired outcome here, i'd recommend terraform state rm cloudflare_zone_setting_override ... and only defining those two values. i'd also avoid using a module here as that is also likely making the abstraction debugging here harder.

Hige commented 3 months ago

Thanks. Rewrote my terraform without using cloudflare_zone_settings_override. It really causes a lot of problems.

jacobbednarz commented 3 months ago

in the future (v5 but we may backport it to v4), there will be cloudflare_zone_setting which will handle single settings correctly and avoid all these issues.

ratesangelo commented 2 weeks ago

Can I assume that first_party_fonts -eq third_part_fonts( from UI speed > optimization? )

Optimize font loading. Cloudflare Fonts reduces external requests for **third-party** fonts, resulting in improved privacy and performance for faster page loads..

Refer to the [Troubleshooting](https://developers.cloudflare.com/speed/optimization/content/fonts/troubleshooting/) section for more information.

Is this a typo?