diff --git a/internal/services/cdn/cdn_frontdoor_rule_resource.go b/internal/services/cdn/cdn_frontdoor_rule_resource.go index 588a52c31adc..0032d099a44e 100644 --- a/internal/services/cdn/cdn_frontdoor_rule_resource.go +++ b/internal/services/cdn/cdn_frontdoor_rule_resource.go @@ -123,7 +123,7 @@ func resourceCdnFrontDoorRule() *pluginsdk.Resource { }, // NOTE: it is valid for the query string to be an empty string. - // Leave blank to preserve the incoming query string. Issue #18249 + // Leave blank to preserve the incoming query string. Issue #18249 & #19682 "query_string": { Type: pluginsdk.TypeString, Optional: true, diff --git a/internal/services/cdn/cdn_frontdoor_rule_resource_test.go b/internal/services/cdn/cdn_frontdoor_rule_resource_test.go index 2993430aab9a..320efa30b715 100644 --- a/internal/services/cdn/cdn_frontdoor_rule_resource_test.go +++ b/internal/services/cdn/cdn_frontdoor_rule_resource_test.go @@ -330,6 +330,21 @@ func TestAccCdnFrontDoorRule_honorOrigin(t *testing.T) { }) } +func TestAccCdnFrontDoorRule_allowEmptyQueryString(t *testing.T) { + // NOTE: Regression test case for issue #19682 + data := acceptance.BuildTestData(t, "azurerm_cdn_frontdoor_rule", "test") + r := CdnFrontDoorRuleResource{} + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.allowEmptyQueryString(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + func (r CdnFrontDoorRuleResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { id, err := parse.FrontDoorRuleID(state.ID) if err != nil { @@ -1119,3 +1134,41 @@ resource "azurerm_cdn_frontdoor_rule" "test" { } `, template, data.RandomInteger) } + +func (r CdnFrontDoorRuleResource) allowEmptyQueryString(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` + provider "azurerm" { + features {} + } + + %s + + resource "azurerm_cdn_frontdoor_rule" "test" { + depends_on = [azurerm_cdn_frontdoor_origin_group.test, azurerm_cdn_frontdoor_origin.test] + + name = "accTestRule%d" + cdn_frontdoor_rule_set_id = azurerm_cdn_frontdoor_rule_set.test.id + + order = 0 + + conditions { + request_uri_condition { + match_values = ["contoso"] + negate_condition = false + operator = "Contains" + } + } + + actions { + url_redirect_action { + redirect_type = "PermanentRedirect" + redirect_protocol = "MatchRequest" + query_string = "" + destination_hostname = "contoso.com" + destination_path = "/test/page" + } + } + } +`, template, data.RandomInteger) +} diff --git a/internal/services/cdn/validate/front_door_validation_helpers.go b/internal/services/cdn/validate/front_door_validation_helpers.go index 5fedb32eb988..a6f5cf26ca13 100644 --- a/internal/services/cdn/validate/front_door_validation_helpers.go +++ b/internal/services/cdn/validate/front_door_validation_helpers.go @@ -141,8 +141,6 @@ func CdnFrontDoorUrlRedirectActionQueryString(i interface{}, k string) (_ []stri if len(v) > 2048 { return nil, []error{fmt.Errorf("'url_redirect_action' is invalid: %q cannot be longer than 2048 characters in length, got %d", k, len(v))} } - } else { - return nil, []error{fmt.Errorf("'url_redirect_action' is invalid: %q must not be empty, got %q", k, v)} } return nil, nil