terraform-provider-azurerm
terraform-provider-azurerm copied to clipboard
[App Gateway] URL Rewrites don't support undefined values
Community Note
- Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
- Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
- If you are interested in working on this issue or have submitted a pull request, please leave a comment
Terraform (and AzureRM Provider) Version
= 2.54.0
Affected Resource(s)
azurerm_application_gateway
Terraform Configuration Files
rewrite_rule_set {
name = "test-rewrite-ruleset"
rewrite_rule {
name = "test-rewrite-rule"
rule_sequence = 1
condition {
variable = "var_uri_path"
pattern = ".*article/(.*)/(.*)"
}
url {
}
}
}
This configuration, which should cause an error, does not because the url.path and url.query_string values become "" (empty strings) instead of nil. Empty strings are valid values but should not be the value when nothing is declared. As such, this causes a mis-configuration of the re-write as the path and query strings are removed rather than retained.
Debug Output
Panic Output
Expected Behaviour
Undefined properties should not be passed to the underlying API as empty strings
Actual Behaviour
Undefined properties are passed to the underlying API as empty strings
Steps to Reproduce
terraform apply
Important Factoids
References
- #10950
cc-ing previously involved participants: @jackofallops, @katbyte, @ido-tr
Since the url block has a property reroute which has a default value, which causes the empty url block defined in config ends up to be a map with all the keys at least has its zero value if absent. This means the nil checks below actually are always true:
https://github.com/terraform-providers/terraform-provider-azurerm/blob/79b76b6588198e0087a44ee652371580bc305919/azurerm/internal/services/network/application_gateway_resource.go#L2982-L2993
I'm wondering whether the empty string makes sense under this scenario, or can we simply not construct it in the api request if it is an empty string (as Portal can also not set an empty string) ?
Empty strings are valid / sensible values for a rewrite path and string, so we can't really ignore them, but "undefined" reroutes are allowed (the backend assumes false) so we may be able to fix this by removing the default value for reroute, then?
Edit: Though thinking about it, it seems that even with an empty block (url { }) in TF config we'd see empty strings for und-declared values, which is not what we want. The API docs for this show that the values should essentially be string|null for the values.
FWIK, there is no way in current Terraform plugin SDK to differ the zero value/absent for a nested property inside a block. One trick have ever been used is to use a insensible value of that type to indicate the absence, e.g. using -1 to indicate absence for a property whose sensible range starts from 0. However, back to your use case, it is a string. Maybe, we shall modify the schema a bit so as to express the absence of the path/query_string, e.g.
query_string {
value = ""
}
I found a workaround for this issue till it will be resolved. You can add query_string = "{var_query_string}" under the URL section For example:
url {
path = foo
query_string = "{var_query_string}"
}
I was trying to track this bug down this weekend and didn't find the existing report until now—the workaround suggested above is the only way I can come up with to generate non-breaking URL rewrite rules. In case the root cause of this is unclear to anybody looking at it, I did get the following from the debug logs:
2021-05-24T14:32:25.369-0400 [WARN] Provider "registry.terraform.io/hashicorp/azurerm" produced an invalid plan for module.app_gateway.azurerm_application_gateway.load_balancer, but we are tolerating it because it is using the legacy plugin SDK.
The following problems may be the cause of any confusing errors from downstream operations:
- .zones: planned value cty.ListValEmpty(cty.String) for a non-computed attribute
- .enable_http2: planned value cty.False for a non-computed attribute
- .rewrite_rule_set[0].rewrite_rule[0].url[0].query_string: planned value cty.StringVal("") for a non-computed attribute
- .rewrite_rule_set[0].rewrite_rule[2].condition[0].negate: planned value cty.False for a non-computed attribute
- .rewrite_rule_set[0].rewrite_rule[2].url[0].query_string: planned value cty.StringVal("") for a non-computed attribute
(output truncated, but there were quite a few others in my specific configuration.)
The bit that is related to the configuration breakage is .rewrite_rule_set[0].rewrite_rule[2].url[0].query_string: planned value cty.StringVal("") for a non-computed attribute, but the part about "using the legacy plugin SDK" seems like the actual root cause?
I just submitted a PR which can circumvents the limitations we currently have by using a components option, similar to the UI:
...
rewrite_rule_set {
name = "${local.rewrite_rule_set_name}_1"
rewrite_rule {
name = "${local.rewrite_rule_name}_1"
rule_sequence = 1
condition {
variable = "var_uri_path"
pattern = ".*article/(.*)/(.*)"
}
url {
path = "/article.aspx"
components = "path_only"
}
}
rewrite_rule {
name = "${local.rewrite_rule_name}_2"
rule_sequence = 2
condition {
variable = "var_uri_path"
pattern = ".*article2/(.*)/(.*)"
}
url {
query_string = "id={var_uri_path_1}&title={var_uri_path_2}"
components = "query_string_only"
}
}
}
...
Happy to hear your thoughts about it!
This functionality has been released in v3.4.0 of the Terraform Provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading.
For further feature requests or bug reports with this functionality, please create a new GitHub issue following the template. Thank you!
This functionality has been released in v3.19.0 of the Terraform Provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading.
For further feature requests or bug reports with this functionality, please create a new GitHub issue following the template. Thank you!
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.