diff --git a/internal/services/containers/kubernetes_cluster_resource.go b/internal/services/containers/kubernetes_cluster_resource.go index 11d03d7f6a42..b4b2686f3f48 100644 --- a/internal/services/containers/kubernetes_cluster_resource.go +++ b/internal/services/containers/kubernetes_cluster_resource.go @@ -651,6 +651,12 @@ func resourceKubernetesCluster() *pluginsdk.Resource { Default: false, }, + "run_command_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: true, + }, + "private_dns_zone_id": { Type: pluginsdk.TypeString, Optional: true, @@ -1061,6 +1067,7 @@ func resourceKubernetesClusterCreate(d *pluginsdk.ResourceData, meta interface{} EnablePrivateCluster: &enablePrivateCluster, AuthorizedIPRanges: apiServerAuthorizedIPRanges, EnablePrivateClusterPublicFQDN: utils.Bool(d.Get("private_cluster_public_fqdn_enabled").(bool)), + DisableRunCommand: utils.Bool(!d.Get("run_command_enabled").(bool)), } nodeResourceGroup := d.Get("node_resource_group").(string) @@ -1350,6 +1357,11 @@ func resourceKubernetesClusterUpdate(d *pluginsdk.ResourceData, meta interface{} existing.ManagedClusterProperties.APIServerAccessProfile.EnablePrivateClusterPublicFQDN = utils.Bool(d.Get("private_cluster_public_fqdn_enabled").(bool)) } + if d.HasChange("run_command_enabled") { + updateCluster = true + existing.ManagedClusterProperties.APIServerAccessProfile.DisableRunCommand = utils.Bool(!d.Get("run_command_enabled").(bool)) + } + if d.HasChange("auto_scaler_profile") { updateCluster = true autoScalerProfileRaw := d.Get("auto_scaler_profile").([]interface{}) @@ -1714,6 +1726,11 @@ func resourceKubernetesClusterRead(d *pluginsdk.ResourceData, meta interface{}) d.Set("private_cluster_enabled", accessProfile.EnablePrivateCluster) d.Set("private_cluster_public_fqdn_enabled", accessProfile.EnablePrivateClusterPublicFQDN) + runCommandEnabled := true + if accessProfile.DisableRunCommand != nil { + runCommandEnabled = !*accessProfile.DisableRunCommand + } + d.Set("run_command_enabled", runCommandEnabled) switch { case accessProfile.PrivateDNSZone != nil && strings.EqualFold("System", *accessProfile.PrivateDNSZone): d.Set("private_dns_zone_id", "System") diff --git a/internal/services/containers/kubernetes_cluster_resource_test.go b/internal/services/containers/kubernetes_cluster_resource_test.go index c77a438c21d0..652d29582643 100644 --- a/internal/services/containers/kubernetes_cluster_resource_test.go +++ b/internal/services/containers/kubernetes_cluster_resource_test.go @@ -36,6 +36,28 @@ func TestAccKubernetesCluster_hostEncryption(t *testing.T) { }) } +func TestAccKubernetesCluster_runCommand(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_kubernetes_cluster", "test") + r := KubernetesClusterResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.runCommand(data, currentKubernetesVersion, true), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("run_command_enabled").HasValue("true"), + ), + }, + { + Config: r.runCommand(data, currentKubernetesVersion, false), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("run_command_enabled").HasValue("false"), + ), + }, + }) +} + func (t KubernetesClusterResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { id, err := parse.ClusterID(state.ID) if err != nil { @@ -116,6 +138,38 @@ resource "azurerm_kubernetes_cluster" "test" { `, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, controlPlaneVersion) } +func (KubernetesClusterResource) runCommand(data acceptance.TestData, controlPlaneVersion string, runCommandEnabled bool) 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" + kubernetes_version = %q + run_command_enabled = %t + + default_node_pool { + name = "default" + node_count = 1 + vm_size = "Standard_DS2_v2" + } + + identity { + type = "SystemAssigned" + } +} + `, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, controlPlaneVersion, runCommandEnabled) +} + func (r KubernetesClusterResource) upgradeSettingsConfig(data acceptance.TestData, maxSurge string) string { if maxSurge != "" { maxSurge = fmt.Sprintf(`upgrade_settings { diff --git a/website/docs/r/kubernetes_cluster.html.markdown b/website/docs/r/kubernetes_cluster.html.markdown index 21ac83c897d6..8a447735a958 100644 --- a/website/docs/r/kubernetes_cluster.html.markdown +++ b/website/docs/r/kubernetes_cluster.html.markdown @@ -206,7 +206,9 @@ resource "azurerm_kubernetes_cluster" "example" { * `role_based_access_control_enabled` (Optional) - Whether Role Based Access Control for the Kubernetes Cluster should be enabled. Defaults to `true`. Changing this forces a new resource to be created. -* `service_principal` - (Optional) A `service_principal` block as documented below. One of either `identity` or `service_principal` must be specified. +* `run_command_enabled` - (Optional) Whether to enable run command for the cluster or not. Defaults to `true`. + +* `service_principal` - (Optional) A `service_principal` block as documented below. One of either `identity` or `service_principal` must be specified. !> **Note:** A migration scenario from `service_principal` to `identity` is supported. When upgrading `service_principal` to `identity`, your cluster's control plane and addon pods will switch to use managed identity, but the kubelets will keep using your configured `service_principal` until you upgrade your Node Pool.