-
Notifications
You must be signed in to change notification settings - Fork 761
Description
Confirmation
- This is a bug with an existing resource and is not a feature request or enhancement. Feature requests should be submitted with Cloudflare Support or your account team.
- I have searched the issue tracker and my issue isn't already found.
- I have replicated my issue using the latest version of the provider and it is still present.
Terraform and Cloudflare provider version
$ terraform -v
Terraform v1.12.2
on darwin_arm64
provider: v5.8.2
Affected resource(s)
- cloudflare_ruleset
Terraform configuration files
resource "cloudflare_ruleset" "example_ruleset" {
zone_id = cloudflare_zone.origin_marketplacer_com.id
kind = "zone"
phase = "http_ratelimit"
name = "default"
rules = [
{
description = "rule a"
enabled = true
expression = "(http.host in {\"a.com\"})"
action = "block"
ratelimit = {
characteristics = [
"ip.src",
"cf.colo.id",
]
mitigation_timeout = 0
period = 10
requests_per_period = 200
requests_to_origin = true
}
},
{
description = "rule b"
enabled = true
expression = "(http.host in {\"b.com\"})"
action = "block"
ratelimit = {
characteristics = [
"ip.src",
"cf.colo.id",
]
mitigation_timeout = 0
period = 10
requests_per_period = 200
requests_to_origin = true
}
},
{
description = "rule c"
enabled = true
expression = "(http.host in {\"c.com\"})"
action = "block"
ratelimit = {
characteristics = [
"ip.src",
"cf.colo.id",
]
mitigation_timeout = 0
period = 10
requests_per_period = 200
requests_to_origin = true
}
}
]
}
Link to debug output
n/a
Panic output
n/a
Expected output
if you apply the above config, it creates three rules, all good. If you then remove 'rule a', then I'd expect rule a to be removed, and 'rule b/c' to be unchanged. If at some later time I add 'rule a' back to the config, I'd expect it to be inserted without change to 'rule b/c'
Actual output
when you plan removing rule a from the config above, terraform shows rules b and c "moving up" - that is rule a is reconfigured to match rule b, rule b is reconfigured to match rule c, and then the old rule c is deleted:
~ {
~ description = "rule a" -> "rule b"
~ id = "78e2c032fa934fca87b78ec51a8aa876" -> (known after apply)
~ ref = "78e2c032fa934fca87b78ec51a8aa876" -> (known after apply)
# (4 unchanged attributes hidden)
},
~ {
~ description = "rule b" -> "rule c"
~ id = "2113c87e80ca491981fd326330c413f2" -> (known after apply)
~ ref = "2113c87e80ca491981fd326330c413f2" -> (known after apply)
# (4 unchanged attributes hidden)
},
- {
- action = "block" -> null
- description = "rule c" -> null
- enabled = true -> null
- expression = "(http.host in {\"b.com\"})" -> null
- id = "801316ad90c04acdba36148b31838ceb" -> null
- ratelimit = {
- characteristics = [
- "ip.src",
- "cf.colo.id",
] -> null
- mitigation_timeout = 0 -> null
- period = 10 -> null
- requests_per_period = 200 -> null
- requests_to_origin = true -> null
} -> null
- ref = "801316ad90c04acdba36148b31838ceb" -> null
},
behind the scenes, though, that doesn't appear to be what happens - instead, what appears to happen is that all three rules are deleted, and then rule b and rule c are recreated as entirely new rules - so before the plan above I had:
rule a id: 78e2c032fa934fca87b78ec51a8aa876
rule b id: 2113c87e80ca491981fd326330c413f2
rule c id :801316ad90c04acdba36148b31838ceb
then after the apply I have:
rule b id: 4303ec36d8084c5b82414ddca552e3ed
rule c id: 885170548236493ea560afd88dc63117
when you add rule a back to the console, the plan shows the reverse
~ {
~ description = "rule b" -> "rule a"
~ id = "4303ec36d8084c5b82414ddca552e3ed" -> (known after apply)
~ ref = "4303ec36d8084c5b82414ddca552e3ed" -> (known after apply)
# (4 unchanged attributes hidden)
},
~ {
~ description = "rule c" -> "rule b"
~ id = "885170548236493ea560afd88dc63117" -> (known after apply)
~ ref = "885170548236493ea560afd88dc63117" -> (known after apply)
# (4 unchanged attributes hidden)
},
+ {
+ action = "block"
+ description = "rule c"
+ enabled = true
+ expression = "(http.host in {\"b.com\"})"
+ id = (known after apply)
+ ratelimit = {
+ characteristics = [
+ "ip.src",
+ "cf.colo.id",
]
+ mitigation_timeout = 0
+ period = 10
+ requests_per_period = 200
+ requests_to_origin = true
}
+ ref = (known after apply)
},
and when applied, all three rules are recreated
rule a id: 2dfd6e99f53e4e5a9552cbb1badf51ce
rule b id: 8494b9eaa19d41d28994e7227c918d4f
rule c id :0dd37aeeefb7415cad9e4ea9647a5d67
Steps to reproduce
- apply the config above
- wait some period for the rules to start accruing metrics
- remove rule a from the config above, apply
- observe in the plan that terraform is going to "move everything up"
- observe in the cloudflare console that rules b and c have been recreated, and all history lost
Additional factoids
From a narrow terraform POV, this is fine - you're getting the end result you asked for . However, back in the cloudflare console you lose all the history of rules b/c - 30 days of metrics vanish - that's a pretty major violation of the principle of least surprise. The 30 days of graphs for each rule are important to our use of Cloudflare, we don't like to erase them if we can avoid it, so we've had to resort to adding and removing rules in the console.
The frustrating thing here is that the Cloudflare console handles this beautifully - inserting and deleting rules from the middle of the rule corpus doesn't cause other rules to lose their history.
This is not a new problem, the v4 provider was even worse (in that it would recreate all the rules if there was any change in any rule in the corpus). I was hoping that the move from independent rule blocks with implicit ordering to a single rules list with explicit ordering in v5 would make this issue go away, sadly, it hasn't yet.
References
This is essentially a rehashing of #3357 , but for provider v5