diff --git a/internal/services/containers/kubernetes_cluster_other_resource_test.go b/internal/services/containers/kubernetes_cluster_other_resource_test.go index 9e993d452276..2599dff64ac0 100644 --- a/internal/services/containers/kubernetes_cluster_other_resource_test.go +++ b/internal/services/containers/kubernetes_cluster_other_resource_test.go @@ -886,7 +886,26 @@ func TestAccKubernetesCluster_customCATrustEnabled(t *testing.T) { }) } +func TestAccKubernetesCluster_webAppRoutingWithMultipleDnsZone(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_kubernetes_cluster", "test") + r := KubernetesClusterResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.webAppRoutingWithMultipleDnsZone(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("web_app_routing.0.web_app_routing_identity.#").HasValue("1"), + ), + }, + data.ImportStep(), + }) +} + func TestAccKubernetesCluster_webAppRouting(t *testing.T) { + if !features.FourPointOhBeta() { + t.Skip("Skipping test in 4.0 as `dns_zone_id` is removed") + } data := acceptance.BuildTestData(t, "azurerm_kubernetes_cluster", "test") r := KubernetesClusterResource{} @@ -912,11 +931,22 @@ func TestAccKubernetesCluster_webAppRouting(t *testing.T) { check.That(data.ResourceName).ExistsInAzure(r), ), }, + data.ImportStep("web_app_routing.0.dns_zone_id", "web_app_routing.0.dns_zone_ids.#", "web_app_routing.0.dns_zone_ids.0"), + { + Config: r.webAppRoutingWithMultipleDnsZone(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("web_app_routing.0.web_app_routing_identity.#").HasValue("1"), + ), + }, data.ImportStep(), }) } func TestAccKubernetesCluster_webAppRoutingPrivateDNS(t *testing.T) { + if !features.FourPointOhBeta() { + t.Skip("Skipping test in 4.0 as `dns_zone_id` is removed") + } data := acceptance.BuildTestData(t, "azurerm_kubernetes_cluster", "test") r := KubernetesClusterResource{} @@ -928,7 +958,7 @@ func TestAccKubernetesCluster_webAppRoutingPrivateDNS(t *testing.T) { check.That(data.ResourceName).Key("web_app_routing.0.web_app_routing_identity.#").HasValue("1"), ), }, - data.ImportStep(), + data.ImportStep("web_app_routing.0.dns_zone_id", "web_app_routing.0.dns_zone_ids.#", "web_app_routing.0.dns_zone_ids.0"), }) } @@ -3080,6 +3110,53 @@ resource "azurerm_kubernetes_cluster" "test" { `, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger) } +func (KubernetesClusterResource) webAppRoutingWithMultipleDnsZone(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-aks-%[2]d" + location = "%[1]s" +} + +resource "azurerm_dns_zone" "test" { + name = "acctestzone%[2]d.com" + resource_group_name = azurerm_resource_group.test.name +} + +resource "azurerm_dns_zone" "test2" { + name = "acctestzone2%[2]d.com" + resource_group_name = azurerm_resource_group.test.name +} + +resource "azurerm_kubernetes_cluster" "test" { + name = "acctestaks%[2]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + dns_prefix = "acctestaks%[2]d" + + default_node_pool { + name = "default" + node_count = 1 + vm_size = "Standard_DS2_v2" + upgrade_settings { + max_surge = "10%%" + } + } + + identity { + type = "SystemAssigned" + } + + web_app_routing { + dns_zone_ids = [azurerm_dns_zone.test.id, azurerm_dns_zone.test2.id] + } +} + `, data.Locations.Primary, data.RandomInteger) +} + func (KubernetesClusterResource) webAppRouting(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { diff --git a/internal/services/containers/kubernetes_cluster_resource.go b/internal/services/containers/kubernetes_cluster_resource.go index 0584f625c8e7..847d6c2ab4e0 100644 --- a/internal/services/containers/kubernetes_cluster_resource.go +++ b/internal/services/containers/kubernetes_cluster_resource.go @@ -434,14 +434,18 @@ func resourceKubernetesCluster() *pluginsdk.Resource { MaxItems: 1, Elem: &pluginsdk.Resource{ Schema: map[string]*pluginsdk.Schema{ - "dns_zone_id": { - Type: pluginsdk.TypeString, + "dns_zone_ids": { + Type: pluginsdk.TypeList, Required: true, - ValidateFunc: validation.Any( - dnsValidate.ValidateDnsZoneID, - privatezones.ValidatePrivateDnsZoneID, - validation.StringIsEmpty, - ), + MinItems: 1, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + ValidateFunc: validation.Any( + dnsValidate.ValidateDnsZoneID, + privatezones.ValidatePrivateDnsZoneID, + validation.StringIsEmpty, + ), + }, }, "web_app_routing_identity": { Type: pluginsdk.TypeList, @@ -1675,6 +1679,31 @@ func resourceKubernetesCluster() *pluginsdk.Resource { }, }, } + resource.Schema["web_app_routing"].Elem.(*pluginsdk.Resource).Schema["dns_zone_id"] = &pluginsdk.Schema{ + Deprecated: "`dns_zone_id` has been deprecated in favor of `dns_zone_ids` and will be removed in v4.0 of the AzureRM Provider.", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.Any( + dnsValidate.ValidateDnsZoneID, + privatezones.ValidatePrivateDnsZoneID, + validation.StringIsEmpty, + ), + ConflictsWith: []string{"web_app_routing.0.dns_zone_ids"}, + } + resource.Schema["web_app_routing"].Elem.(*pluginsdk.Resource).Schema["dns_zone_ids"] = &pluginsdk.Schema{ + Type: pluginsdk.TypeList, + Optional: true, + MinItems: 1, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + ValidateFunc: validation.Any( + dnsValidate.ValidateDnsZoneID, + privatezones.ValidatePrivateDnsZoneID, + validation.StringIsEmpty, + ), + }, + ConflictsWith: []string{"web_app_routing.0.dns_zone_id"}, + } } if features.FourPointOhBeta() { @@ -2981,7 +3010,7 @@ func resourceKubernetesClusterRead(d *pluginsdk.ResourceData, meta interface{}) return fmt.Errorf("setting `microsoft_defender`: %+v", err) } - ingressProfile := flattenKubernetesClusterIngressProfile(props.IngressProfile) + ingressProfile := flattenKubernetesClusterIngressProfile(props.IngressProfile, d.Get("web_app_routing").([]interface{})) if err := d.Set("web_app_routing", ingressProfile); err != nil { return fmt.Errorf("setting `web_app_routing`: %+v", err) } @@ -4730,22 +4759,40 @@ func expandKubernetesClusterIngressProfile(d *pluginsdk.ResourceData, input []in } if input[0] != nil { config := input[0].(map[string]interface{}) - dnsZoneResourceId := config["dns_zone_id"].(string) - if dnsZoneResourceId != "" { - out.WebAppRouting.DnsZoneResourceIds = pointer.To([]string{dnsZoneResourceId}) + if !features.FourPointOhBeta() { + dnsZoneResourceId := config["dns_zone_id"].(string) + if dnsZoneResourceId != "" { + out.WebAppRouting.DnsZoneResourceIds = pointer.To([]string{dnsZoneResourceId}) + } + } + if v := config["dns_zone_ids"]; v != nil { + if dnsZoneResourceIds, ok := v.([]interface{}); ok && len(dnsZoneResourceIds) > 0 { + out.WebAppRouting.DnsZoneResourceIds = utils.ExpandStringSlice(dnsZoneResourceIds) + } } } return &out } -func flattenKubernetesClusterIngressProfile(input *managedclusters.ManagedClusterIngressProfile) []interface{} { +func flattenKubernetesClusterIngressProfile(input *managedclusters.ManagedClusterIngressProfile, old []interface{}) []interface{} { if input == nil || input.WebAppRouting == nil || (input.WebAppRouting.Enabled != nil && !*input.WebAppRouting.Enabled) { return []interface{}{} } - dnsZoneId := "" - if v := input.WebAppRouting.DnsZoneResourceIds; v != nil && len(*v) != 0 { - dnsZoneId = (*v)[0] + out := map[string]interface{}{} + useDnsZoneId := false + if !features.FourPointOhBeta() { + if len(old) > 0 && old[0] != nil { + oldConfig := old[0].(map[string]interface{}) + useDnsZoneId = oldConfig["dns_zone_id"].(string) != "" + } + } + if useDnsZoneId { + if v := input.WebAppRouting.DnsZoneResourceIds; v != nil && len(*v) != 0 { + out["dns_zone_id"] = (*v)[0] + } + } else { + out["dns_zone_ids"] = utils.FlattenStringSlice(input.WebAppRouting.DnsZoneResourceIds) } webAppRoutingIdentity := []interface{}{} @@ -4754,12 +4801,9 @@ func flattenKubernetesClusterIngressProfile(input *managedclusters.ManagedCluste webAppRoutingIdentity = flattenKubernetesClusterAddOnIdentityProfile(v) } - return []interface{}{ - map[string]interface{}{ - "dns_zone_id": dnsZoneId, - "web_app_routing_identity": webAppRoutingIdentity, - }, - } + out["web_app_routing_identity"] = webAppRoutingIdentity + + return []interface{}{out} } func expandKubernetesClusterAzureMonitorProfile(input []interface{}) *managedclusters.ManagedClusterAzureMonitorProfile { diff --git a/website/docs/r/kubernetes_cluster.html.markdown b/website/docs/r/kubernetes_cluster.html.markdown index c7014d19a95b..d61a413f6234 100644 --- a/website/docs/r/kubernetes_cluster.html.markdown +++ b/website/docs/r/kubernetes_cluster.html.markdown @@ -889,7 +889,7 @@ A `sysctl_config` block supports the following: A `web_app_routing` block supports the following: -* `dns_zone_id` - (Required) Specifies the ID of the DNS Zone in which DNS entries are created for applications deployed to the cluster when Web App Routing is enabled. For Bring-Your-Own DNS zones this property should be set to an empty string `""`. +* `dns_zone_ids` - (Required) Specifies the list of the DNS Zone IDs in which DNS entries are created for applications deployed to the cluster when Web App Routing is enabled. If not using Bring-Your-Own DNS zones this property should be set to an empty list. ---