diff --git a/internal/services/cdn/cdn_frontdoor_route_resource.go b/internal/services/cdn/cdn_frontdoor_route_resource.go index 104ccdef93ae..d62d934c0831 100644 --- a/internal/services/cdn/cdn_frontdoor_route_resource.go +++ b/internal/services/cdn/cdn_frontdoor_route_resource.go @@ -63,10 +63,10 @@ func resourceCdnFrontDoorRoute() *pluginsdk.Resource { // NOTE: These are not sent to the API, they are only here so Terraform // can provision/destroy the resources in the correct order. + // Made this field optional to address comments in Issue #29063 "cdn_frontdoor_origin_ids": { Type: pluginsdk.TypeList, - Required: true, - + Optional: true, Elem: &pluginsdk.Schema{ Type: pluginsdk.TypeString, ValidateFunc: validate.FrontDoorOriginID, @@ -347,7 +347,7 @@ func resourceCdnFrontDoorRouteRead(d *pluginsdk.ResourceData, meta interface{}) // NOTE: These are not sent to the API, they are only here so Terraform // can provision/destroy the resources in the correct order. if originIds := d.Get("cdn_frontdoor_origin_ids").([]interface{}); len(originIds) > 0 { - d.Set("cdn_frontdoor_origin_ids", utils.ExpandStringSlice(originIds)) + d.Set("cdn_frontdoor_origin_ids", originIds) } d.Set("name", id.RouteName) @@ -533,7 +533,7 @@ func resourceCdnFrontDoorRouteUpdate(d *pluginsdk.ResourceData, meta interface{} // NOTE: These are not sent to the API, they are only here so Terraform // can provision/destroy the resources in the correct order. if originIds := d.Get("cdn_frontdoor_origin_ids").([]interface{}); len(originIds) > 0 { - d.Set("cdn_frontdoor_origin_ids", utils.ExpandStringSlice(originIds)) + d.Set("cdn_frontdoor_origin_ids", originIds) } return resourceCdnFrontDoorRouteRead(d, meta) diff --git a/internal/services/cdn/cdn_frontdoor_route_resource_test.go b/internal/services/cdn/cdn_frontdoor_route_resource_test.go index 76e73f815e01..6b4f04ff6f45 100644 --- a/internal/services/cdn/cdn_frontdoor_route_resource_test.go +++ b/internal/services/cdn/cdn_frontdoor_route_resource_test.go @@ -37,6 +37,34 @@ func TestAccCdnFrontDoorRoute_basic(t *testing.T) { }) } +func TestAccCdnFrontDoorRoute_basicDependsOn(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_cdn_frontdoor_route", "test") + r := CdnFrontDoorRouteResource{} + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basicDependsOn(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("cdn_frontdoor_origin_group_id"), + }) +} + +func TestAccCdnFrontDoorRoute_basicDependsOnAndField(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_cdn_frontdoor_route", "test") + r := CdnFrontDoorRouteResource{} + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basicDependsOnAndField(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("cdn_frontdoor_origin_group_id", "cdn_frontdoor_origin_ids"), + }) +} + func TestAccCdnFrontDoorRoute_requiresImport(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_cdn_frontdoor_route", "test") r := CdnFrontDoorRouteResource{} @@ -83,6 +111,13 @@ func TestAccCdnFrontDoorRoute_update(t *testing.T) { ), }, data.ImportStep("cdn_frontdoor_origin_group_id", "cdn_frontdoor_origin_ids"), + { + Config: r.updateDependsOn(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("cdn_frontdoor_origin_group_id"), }) } @@ -198,6 +233,41 @@ resource "azurerm_cdn_frontdoor_route" "test" { `, template, data.RandomInteger) } +func (r CdnFrontDoorRouteResource) basicDependsOn(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_cdn_frontdoor_route" "test" { + name = "accTestRoute-%d" + cdn_frontdoor_endpoint_id = azurerm_cdn_frontdoor_endpoint.test.id + cdn_frontdoor_origin_group_id = azurerm_cdn_frontdoor_origin_group.test.id + patterns_to_match = ["/*"] + supported_protocols = ["Http", "Https"] + + depends_on = [azurerm_cdn_frontdoor_origin.test] +} +`, template, data.RandomInteger) +} + +func (r CdnFrontDoorRouteResource) basicDependsOnAndField(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_cdn_frontdoor_route" "test" { + name = "accTestRoute-%d" + cdn_frontdoor_endpoint_id = azurerm_cdn_frontdoor_endpoint.test.id + cdn_frontdoor_origin_group_id = azurerm_cdn_frontdoor_origin_group.test.id + cdn_frontdoor_origin_ids = [azurerm_cdn_frontdoor_origin.test.id] + patterns_to_match = ["/*"] + supported_protocols = ["Http", "Https"] + + depends_on = [azurerm_cdn_frontdoor_origin.test] +} +`, template, data.RandomInteger) +} + func (r CdnFrontDoorRouteResource) requiresImport(data acceptance.TestData) string { config := r.basic(data) return fmt.Sprintf(` @@ -288,3 +358,30 @@ resource "azurerm_cdn_frontdoor_route" "test" { } `, template, data.RandomInteger) } + +func (r CdnFrontDoorRouteResource) updateDependsOn(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_cdn_frontdoor_route" "test" { + name = "accTestRoute-%d" + cdn_frontdoor_endpoint_id = azurerm_cdn_frontdoor_endpoint.test.id + cdn_frontdoor_origin_group_id = azurerm_cdn_frontdoor_origin_group.test.id + + enabled = true + forwarding_protocol = "HttpOnly" + https_redirect_enabled = false + patterns_to_match = ["/*"] + cdn_frontdoor_rule_set_ids = [azurerm_cdn_frontdoor_rule_set.test.id] + supported_protocols = ["Https"] + + cache { + query_strings = ["bar"] + query_string_caching_behavior = "IncludeSpecifiedQueryStrings" + } + + depends_on = [azurerm_cdn_frontdoor_origin.test] +} +`, template, data.RandomInteger) +} diff --git a/website/docs/r/cdn_frontdoor_route.html.markdown b/website/docs/r/cdn_frontdoor_route.html.markdown index 95ccd965d4e0..3a7eec382ffb 100644 --- a/website/docs/r/cdn_frontdoor_route.html.markdown +++ b/website/docs/r/cdn_frontdoor_route.html.markdown @@ -10,6 +10,8 @@ description: |- Manages a Front Door (standard/premium) Route. +~> **Note:** The `azurerm_cdn_frontdoor_route` resource must **explicitly** reference its associated `azurerm_cdn_frontdoor_origin` resource(s). This can be achieved either by using a `depends_on` meta-argument that points to the `azurerm_cdn_frontdoor_origin` resource(s), or by specifying the `azurerm_cdn_frontdoor_origin` IDs via the `cdn_frontdoor_origin_ids` field. + ## Example Usage ```hcl @@ -134,16 +136,18 @@ The following arguments are supported: * `cdn_frontdoor_origin_group_id` - (Required) The resource ID of the Front Door Origin Group where this Front Door Route should be created. -* `cdn_frontdoor_origin_ids` - (Required) One or more Front Door Origin resource IDs that this Front Door Route will link to. - -* `forwarding_protocol` - (Optional) The Protocol that will be use when forwarding traffic to backends. Possible values are `HttpOnly`, `HttpsOnly` or `MatchRequest`. Defaults to `MatchRequest`. - * `patterns_to_match` - (Required) The route patterns of the rule. * `supported_protocols` - (Required) One or more Protocols supported by this Front Door Route. Possible values are `Http` or `Https`. ~> **Note:** If `https_redirect_enabled` is set to `true` the `supported_protocols` field must contain both `Http` and `Https` values. +* `cdn_frontdoor_origin_ids` - (Optional) One or more Front Door Origin resource IDs for this Front Door Route. + +~> **Note:** The `cdn_frontdoor_origin_ids` field is not transmitted to the Azure API; it is used exclusively by Terraform to determine correct resource provisioning and destruction order. If this field is omitted, a `depends_on` meta-argument referencing the corresponding `azurerm_cdn_frontdoor_origin` resource(s) is required. When importing an existing `azurerm_cdn_frontdoor_route resource`, you must manually add either the `cdn_frontdoor_origin_ids` field or the `depends_on` meta-argument to the configuration post-import. + +* `forwarding_protocol` - (Optional) The Protocol that will be use when forwarding traffic to backends. Possible values are `HttpOnly`, `HttpsOnly` or `MatchRequest`. Defaults to `MatchRequest`. + * `cache` - (Optional) A `cache` block as defined below. ~> **Note:** To disable caching, do not provide the `cache` block in the configuration file.