From 81ce5a8b24669eef4b1f32f9174b7b5b89ec14d5 Mon Sep 17 00:00:00 2001 From: JasonWhall <42138928+JasonWhall@users.noreply.github.com> Date: Thu, 23 Sep 2021 08:05:40 +0100 Subject: [PATCH 1/3] Add OSM Addon Option Signed-off-by: JasonWhall <42138928+JasonWhall@users.noreply.github.com> --- .../services/containers/kubernetes_addons.go | 45 ++++++++++++- ...kubernetes_cluster_addons_resource_test.go | 67 +++++++++++++++++++ .../kubernetes_cluster_data_source.go | 27 ++++++++ .../kubernetes_cluster_data_source_test.go | 32 +++++++++ .../docs/d/kubernetes_cluster.html.markdown | 8 +++ .../docs/r/kubernetes_cluster.html.markdown | 12 ++++ 6 files changed, 190 insertions(+), 1 deletion(-) diff --git a/internal/services/containers/kubernetes_addons.go b/internal/services/containers/kubernetes_addons.go index 5e7b4de5d193..20f6301ca701 100644 --- a/internal/services/containers/kubernetes_addons.go +++ b/internal/services/containers/kubernetes_addons.go @@ -24,6 +24,7 @@ const ( httpApplicationRoutingKey = "httpApplicationRouting" omsAgentKey = "omsagent" ingressApplicationGatewayKey = "ingressApplicationGateway" + openServiceMeshKey = "openServiceMesh" ) // The AKS API hard-codes which add-ons are supported in which environment @@ -36,11 +37,13 @@ var unsupportedAddonsForEnvironment = map[string][]string{ aciConnectorKey, // https://github.com/hashicorp/terraform-provider-azurerm/issues/5510 httpApplicationRoutingKey, // https://github.com/hashicorp/terraform-provider-azurerm/issues/5960 kubernetesDashboardKey, // https://github.com/hashicorp/terraform-provider-azurerm/issues/7487 + openServiceMeshKey, // Preview features are not supported in Azure China }, azure.USGovernmentCloud.Name: { azurePolicyKey, // https://github.com/hashicorp/terraform-provider-azurerm/issues/6702 httpApplicationRoutingKey, // https://github.com/hashicorp/terraform-provider-azurerm/issues/5960 kubernetesDashboardKey, // https://github.com/hashicorp/terraform-provider-azurerm/issues/7136 + openServiceMeshKey, // Preview features are not supported in Azure Government }, } @@ -218,6 +221,20 @@ func schemaKubernetesAddOnProfiles() *pluginsdk.Schema { }, }, }, + + "open_service_mesh": { + Type: pluginsdk.TypeList, + MaxItems: 1, + Optional: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "enabled": { + Type: pluginsdk.TypeBool, + Required: true, + }, + }, + }, + }, }, }, } @@ -235,6 +252,7 @@ func expandKubernetesAddOnProfiles(input []interface{}, env azure.Environment) ( httpApplicationRoutingKey: &disabled, omsAgentKey: &disabled, ingressApplicationGatewayKey: &disabled, + openServiceMeshKey: &disabled, } if len(input) == 0 || input[0] == nil { @@ -341,6 +359,18 @@ func expandKubernetesAddOnProfiles(input []interface{}, env azure.Environment) ( } } + openServiceMesh := profile["open_service_mesh"].([]interface{}) + if len(openServiceMesh) > 0 && openServiceMesh[0] != nil { + value := openServiceMesh[0].(map[string]interface{}) + enabled := value["enabled"].(bool) + + addonProfiles[openServiceMeshKey] = &containerservice.ManagedClusterAddonProfile{ + Enabled: utils.Bool(enabled), + Config: nil, + } + + } + return filterUnsupportedKubernetesAddOns(addonProfiles, env) } @@ -502,8 +532,20 @@ func flattenKubernetesAddOnProfiles(profile map[string]*containerservice.Managed }) } + openServiceMeshes := make([]interface{}, 0) + if openServiceMesh := kubernetesAddonProfileLocate(profile, openServiceMeshKey); openServiceMesh != nil { + enabled := false + if enabledVal := openServiceMesh.Enabled; enabledVal != nil { + enabled = *enabledVal + } + + openServiceMeshes = append(openServiceMeshes, map[string]interface{}{ + "enabled": enabled, + }) + } + // this is a UX hack, since if the top level block isn't defined everything should be turned off - if len(aciConnectors) == 0 && len(azurePolicies) == 0 && len(httpApplicationRoutes) == 0 && len(kubeDashboards) == 0 && len(omsAgents) == 0 && len(ingressApplicationGateways) == 0 { + if len(aciConnectors) == 0 && len(azurePolicies) == 0 && len(httpApplicationRoutes) == 0 && len(kubeDashboards) == 0 && len(omsAgents) == 0 && len(ingressApplicationGateways) == 0 && len(openServiceMeshes) == 0 { return []interface{}{} } @@ -515,6 +557,7 @@ func flattenKubernetesAddOnProfiles(profile map[string]*containerservice.Managed "kube_dashboard": kubeDashboards, "oms_agent": omsAgents, "ingress_application_gateway": ingressApplicationGateways, + "open_service_mesh": openServiceMeshes, }, } } diff --git a/internal/services/containers/kubernetes_cluster_addons_resource_test.go b/internal/services/containers/kubernetes_cluster_addons_resource_test.go index 5789d1340664..0a407e07425c 100644 --- a/internal/services/containers/kubernetes_cluster_addons_resource_test.go +++ b/internal/services/containers/kubernetes_cluster_addons_resource_test.go @@ -19,6 +19,7 @@ var kubernetesAddOnTests = map[string]func(t *testing.T){ "addonProfileAppGatewayAppGatewayId": testAccKubernetesCluster_addonProfileIngressApplicationGateway_appGatewayId, "addonProfileAppGatewaySubnetCIDR": testAccKubernetesCluster_addonProfileIngressApplicationGateway_subnetCIDR, "addonProfileAppGatewaySubnetID": testAccKubernetesCluster_addonProfileIngressApplicationGateway_subnetId, + "addonProfileOpenServiceMesh": testAccKubernetesCluster_addonProfileOpenServiceMesh, } var addOnAppGatewaySubnetCIDR string = "10.241.0.0/16" // AKS will use 10.240.0.0/16 for the aks subnet so use 10.241.0.0/16 for the app gateway subnet @@ -341,6 +342,28 @@ func testAccKubernetesCluster_addonProfileIngressApplicationGateway_subnetId(t * }) } +func TestAccKubernetesCluster_addonProfileOpenServiceMesh(t *testing.T) { + checkIfShouldRunTestsIndividually(t) + testAccKubernetesCluster_addonProfileOpenServiceMesh(t) +} + +func testAccKubernetesCluster_addonProfileOpenServiceMesh(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_kubernetes_cluster", "test") + r := KubernetesClusterResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.addonProfileOpenServiceMeshConfig(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("addon_profile.0.open_service_mesh.#").HasValue("1"), + check.That(data.ResourceName).Key("addon_profile.0.open_service_mesh.0.enabled").HasValue("false"), + ), + }, + data.ImportStep(), + }) +} + func (KubernetesClusterResource) addonProfileAciConnectorLinuxConfig(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { @@ -1095,3 +1118,47 @@ resource "azurerm_kubernetes_cluster" "test" { } `, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger) } + +func (KubernetesClusterResource) addonProfileOpenServiceMeshConfig(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-aks-%d" + location = "%s" +} + +resource "azurerm_kubernetes_cluster" "test" { + name = "acctestaks%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + dns_prefix = "acctestaks%d" + + linux_profile { + admin_username = "acctestuser%d" + + ssh_key { + key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" + } + } + + default_node_pool { + name = "default" + node_count = 1 + vm_size = "Standard_DS2_v2" + } + + addon_profile { + open_service_mesh { + enabled = false + } + } + + identity { + type = "SystemAssigned" + } +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger) +} diff --git a/internal/services/containers/kubernetes_cluster_data_source.go b/internal/services/containers/kubernetes_cluster_data_source.go index 0c90d982dd0f..f2a1cdd7c8a6 100644 --- a/internal/services/containers/kubernetes_cluster_data_source.go +++ b/internal/services/containers/kubernetes_cluster_data_source.go @@ -167,6 +167,19 @@ func dataSourceKubernetesCluster() *pluginsdk.Resource { }, }, }, + + "open_service_mesh": { + Type: pluginsdk.TypeList, + Computed: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "enabled": { + Type: pluginsdk.TypeBool, + Computed: true, + }, + }, + }, + }, }, }, }, @@ -925,6 +938,20 @@ func flattenKubernetesClusterDataSourceAddonProfiles(profile map[string]*contain } values["ingress_application_gateway"] = ingressApplicationGateways + openServiceMeshes := make([]interface{}, 0) + if openServiceMesh := kubernetesAddonProfileLocate(profile, openServiceMeshKey); openServiceMesh != nil { + enabled := false + if enabledVal := openServiceMesh.Enabled; enabledVal != nil { + enabled = *enabledVal + } + + output := map[string]interface{}{ + "enabled": enabled, + } + openServiceMeshes = append(openServiceMeshes, output) + } + values["open_service_mesh"] = openServiceMeshes + return []interface{}{values} } diff --git a/internal/services/containers/kubernetes_cluster_data_source_test.go b/internal/services/containers/kubernetes_cluster_data_source_test.go index 29a2b866696c..cd2d16a31dc6 100644 --- a/internal/services/containers/kubernetes_cluster_data_source_test.go +++ b/internal/services/containers/kubernetes_cluster_data_source_test.go @@ -33,6 +33,7 @@ var kubernetesDataSourceTests = map[string]func(t *testing.T){ "addOnProfileIngressApplicationGateewayAppGateway": testAccDataSourceKubernetesCluster_addOnProfileIngressApplicationGatewayAppGateway, "addOnProfileIngressApplicationGateewaySubnetCIDR": testAccDataSourceKubernetesCluster_addOnProfileIngressApplicationGatewaySubnetCIDR, "addOnProfileIngressApplicationGateewaySubnetId": testAccDataSourceKubernetesCluster_addOnProfileIngressApplicationGatewaySubnetId, + "addOnProfileOpenServiceMesh": testAccDataSourceKubernetesCluster_addOnProfileOpenServiceMesh, "autoscalingNoAvailabilityZones": testAccDataSourceKubernetesCluster_autoscalingNoAvailabilityZones, "autoscalingWithAvailabilityZones": testAccDataSourceKubernetesCluster_autoscalingWithAvailabilityZones, "nodeLabels": testAccDataSourceKubernetesCluster_nodeLabels, @@ -556,6 +557,26 @@ func testAccDataSourceKubernetesCluster_addOnProfileIngressApplicationGatewaySub }) } +func TestAccDataSourceKubernetesCluster_addOnProfileOpenServiceMesh(t *testing.T) { + checkIfShouldRunTestsIndividually(t) + testAccDataSourceKubernetesCluster_addOnProfileOpenServiceMesh(t) +} + +func testAccDataSourceKubernetesCluster_addOnProfileOpenServiceMesh(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_kubernetes_cluster", "test") + r := KubernetesClusterDataSource{} + + data.DataSourceTest(t, []acceptance.TestStep{ + { + Config: r.addOnProfileOpenServiceMeshConfig(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).Key("addon_profile.0.open_service_mesh.#").HasValue("1"), + check.That(data.ResourceName).Key("addon_profile.0.open_service_mesh.0.enabled").HasValue("true"), + ), + }, + }) +} + func TestAccDataSourceKubernetesCluster_autoscalingNoAvailabilityZones(t *testing.T) { checkIfShouldRunTestsIndividually(t) testAccDataSourceKubernetesCluster_autoscalingNoAvailabilityZones(t) @@ -864,6 +885,17 @@ data "azurerm_kubernetes_cluster" "test" { `, KubernetesClusterResource{}.addonProfileIngressApplicationGatewaySubnetIdConfig(data)) } +func (KubernetesClusterDataSource) addOnProfileOpenServiceMeshConfig(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +data "azurerm_kubernetes_cluster" "test" { + name = azurerm_kubernetes_cluster.test.name + resource_group_name = azurerm_kubernetes_cluster.test.resource_group_name +} +`, KubernetesClusterResource{}.addonProfileOpenServiceMeshConfig(data)) +} + func (KubernetesClusterDataSource) autoScalingNoAvailabilityZonesConfig(data acceptance.TestData) string { return fmt.Sprintf(` %s diff --git a/website/docs/d/kubernetes_cluster.html.markdown b/website/docs/d/kubernetes_cluster.html.markdown index fd72f7439d31..2a4705553168 100644 --- a/website/docs/d/kubernetes_cluster.html.markdown +++ b/website/docs/d/kubernetes_cluster.html.markdown @@ -100,6 +100,8 @@ A `addon_profile` block exports the following: * `ingress_application_gateway` - An `ingress_application_gateway` block. +* `open_service_mesh` - An `open_service_mesh` block. + --- A `agent_pool_profile` block exports the following: @@ -290,6 +292,12 @@ The `ingress_application_gateway_identity` block exports the following: --- +An `open_service_mesh` block supports the following: + +* `enabled` - Is Open Service Mesh enabled? + +--- + A `role_based_access_control` block exports the following: * `azure_active_directory` - A `azure_active_directory` block as documented above. diff --git a/website/docs/r/kubernetes_cluster.html.markdown b/website/docs/r/kubernetes_cluster.html.markdown index 661109558b9a..5c10bade8cc4 100644 --- a/website/docs/r/kubernetes_cluster.html.markdown +++ b/website/docs/r/kubernetes_cluster.html.markdown @@ -231,6 +231,12 @@ A `addon_profile` block supports the following: * `ingress_application_gateway` - (Optional) An `ingress_application_gateway` block as defined below. +* `open_service_mesh` - (Optional) An `open_service_mesh` block as defined below. For more details, please visit [Open Service Mesh for AKS](https://docs.microsoft.com/azure/aks/open-service-mesh-about). + +-> **NOTE.** At this time Open Service Mesh is not supported in Azure US government or Azure China. + +-> **NOTE.** Open Service Mesh is available on an opt-in preview basis. For more details about how to opt-in, please visit [Open Service Mesh for AKS](https://docs.microsoft.com/azure/aks/open-service-mesh-deploy-add-on#register-the-aks-openservicemesh-preview-feature) + --- An `auto_scaler_profile` block supports the following: @@ -564,6 +570,12 @@ An `ingress_application_gateway` block supports the following: --- +An `open_service_mesh` block supports the following: + +* `enabled` - Is Open Service Mesh enabled? + +--- + A `role_based_access_control` block supports the following: * `azure_active_directory` - (Optional) An `azure_active_directory` block. From e0dfaa58c118f20d9effcf764fed35aebc245a83 Mon Sep 17 00:00:00 2001 From: JasonWhall <42138928+JasonWhall@users.noreply.github.com> Date: Fri, 1 Oct 2021 11:17:46 +0100 Subject: [PATCH 2/3] Update test to check for correct value Signed-off-by: JasonWhall <42138928+JasonWhall@users.noreply.github.com> --- .../services/containers/kubernetes_cluster_data_source_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/services/containers/kubernetes_cluster_data_source_test.go b/internal/services/containers/kubernetes_cluster_data_source_test.go index cd2d16a31dc6..d84cab1b4234 100644 --- a/internal/services/containers/kubernetes_cluster_data_source_test.go +++ b/internal/services/containers/kubernetes_cluster_data_source_test.go @@ -571,7 +571,7 @@ func testAccDataSourceKubernetesCluster_addOnProfileOpenServiceMesh(t *testing.T Config: r.addOnProfileOpenServiceMeshConfig(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).Key("addon_profile.0.open_service_mesh.#").HasValue("1"), - check.That(data.ResourceName).Key("addon_profile.0.open_service_mesh.0.enabled").HasValue("true"), + check.That(data.ResourceName).Key("addon_profile.0.open_service_mesh.0.enabled").HasValue("false"), ), }, }) From 6295cea15674098a87b3e35887b43efb8be745fa Mon Sep 17 00:00:00 2001 From: JasonWhall <42138928+JasonWhall@users.noreply.github.com> Date: Mon, 4 Oct 2021 21:02:48 +0100 Subject: [PATCH 3/3] Update acc tests to enable and disable OSM Signed-off-by: JasonWhall <42138928+JasonWhall@users.noreply.github.com> --- ...kubernetes_cluster_addons_resource_test.go | 19 +++++++++++++++---- .../kubernetes_cluster_data_source_test.go | 4 ++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/internal/services/containers/kubernetes_cluster_addons_resource_test.go b/internal/services/containers/kubernetes_cluster_addons_resource_test.go index 0a407e07425c..33560206d955 100644 --- a/internal/services/containers/kubernetes_cluster_addons_resource_test.go +++ b/internal/services/containers/kubernetes_cluster_addons_resource_test.go @@ -353,7 +353,18 @@ func testAccKubernetesCluster_addonProfileOpenServiceMesh(t *testing.T) { data.ResourceTest(t, r, []acceptance.TestStep{ { - Config: r.addonProfileOpenServiceMeshConfig(data), + // Enable OSM + Config: r.addonProfileOpenServiceMeshConfig(data, true), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("addon_profile.0.open_service_mesh.#").HasValue("1"), + check.That(data.ResourceName).Key("addon_profile.0.open_service_mesh.0.enabled").HasValue("true"), + ), + }, + data.ImportStep(), + { + // Disable OSM + Config: r.addonProfileOpenServiceMeshConfig(data, false), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), check.That(data.ResourceName).Key("addon_profile.0.open_service_mesh.#").HasValue("1"), @@ -1119,7 +1130,7 @@ resource "azurerm_kubernetes_cluster" "test" { `, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger) } -func (KubernetesClusterResource) addonProfileOpenServiceMeshConfig(data acceptance.TestData) string { +func (KubernetesClusterResource) addonProfileOpenServiceMeshConfig(data acceptance.TestData, enabled bool) string { return fmt.Sprintf(` provider "azurerm" { features {} @@ -1152,7 +1163,7 @@ resource "azurerm_kubernetes_cluster" "test" { addon_profile { open_service_mesh { - enabled = false + enabled = %t } } @@ -1160,5 +1171,5 @@ resource "azurerm_kubernetes_cluster" "test" { type = "SystemAssigned" } } -`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger) +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger, enabled) } diff --git a/internal/services/containers/kubernetes_cluster_data_source_test.go b/internal/services/containers/kubernetes_cluster_data_source_test.go index d84cab1b4234..f22e4e8ed148 100644 --- a/internal/services/containers/kubernetes_cluster_data_source_test.go +++ b/internal/services/containers/kubernetes_cluster_data_source_test.go @@ -571,7 +571,7 @@ func testAccDataSourceKubernetesCluster_addOnProfileOpenServiceMesh(t *testing.T Config: r.addOnProfileOpenServiceMeshConfig(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).Key("addon_profile.0.open_service_mesh.#").HasValue("1"), - check.That(data.ResourceName).Key("addon_profile.0.open_service_mesh.0.enabled").HasValue("false"), + check.That(data.ResourceName).Key("addon_profile.0.open_service_mesh.0.enabled").HasValue("true"), ), }, }) @@ -893,7 +893,7 @@ data "azurerm_kubernetes_cluster" "test" { name = azurerm_kubernetes_cluster.test.name resource_group_name = azurerm_kubernetes_cluster.test.resource_group_name } -`, KubernetesClusterResource{}.addonProfileOpenServiceMeshConfig(data)) +`, KubernetesClusterResource{}.addonProfileOpenServiceMeshConfig(data, true)) } func (KubernetesClusterDataSource) autoScalingNoAvailabilityZonesConfig(data acceptance.TestData) string {