Deploy Azure Kubernetes Service Clusters

The azure-native:containerservice:ManagedCluster resource, part of the Pulumi Azure Native provider, provisions an Azure Kubernetes Service (AKS) managed cluster with control plane, node pools, and cluster-level configuration. This guide focuses on four capabilities: HTTP proxy configuration for restricted networks, NAT gateway for outbound connectivity, Istio service mesh with Key Vault certificates, and Azure RBAC and security profile integration.

Clusters require a resource group, service principal or managed identity, and may reference Log Analytics workspaces, Key Vaults, or network infrastructure. The examples are intentionally small. Combine them with your own node pool configuration, networking, and workload deployments.

Configure HTTP proxy for outbound cluster traffic

Clusters in restricted network environments often route outbound traffic through HTTP proxies to reach Azure services and external endpoints.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const managedCluster = new azure_native.containerservice.ManagedCluster("managedCluster", {
    addonProfiles: {},
    agentPoolProfiles: [{
        count: 3,
        enableNodePublicIP: true,
        mode: azure_native.containerservice.AgentPoolMode.System,
        name: "nodepool1",
        osType: azure_native.containerservice.OSType.Linux,
        type: azure_native.containerservice.AgentPoolType.VirtualMachineScaleSets,
        vmSize: "Standard_DS2_v2",
    }],
    autoScalerProfile: {
        scaleDownDelayAfterAdd: "15m",
        scanInterval: "20s",
    },
    diskEncryptionSetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des",
    dnsPrefix: "dnsprefix1",
    enableRBAC: true,
    httpProxyConfig: {
        httpProxy: "http://myproxy.server.com:8080",
        httpsProxy: "https://myproxy.server.com:8080",
        noProxy: [
            "localhost",
            "127.0.0.1",
        ],
        trustedCa: "Q29uZ3JhdHMhIFlvdSBoYXZlIGZvdW5kIGEgaGlkZGVuIG1lc3NhZ2U=",
    },
    kubernetesVersion: "",
    linuxProfile: {
        adminUsername: "azureuser",
        ssh: {
            publicKeys: [{
                keyData: "keydata",
            }],
        },
    },
    location: "location1",
    networkProfile: {
        loadBalancerProfile: {
            managedOutboundIPs: {
                count: 2,
            },
        },
        loadBalancerSku: azure_native.containerservice.LoadBalancerSku.Standard,
        outboundType: azure_native.containerservice.OutboundType.LoadBalancer,
    },
    resourceGroupName: "rg1",
    resourceName: "clustername1",
    servicePrincipalProfile: {
        clientId: "clientid",
        secret: "secret",
    },
    sku: {
        name: "Basic",
        tier: azure_native.containerservice.ManagedClusterSKUTier.Free,
    },
    tags: {
        archv2: "",
        tier: "production",
    },
    windowsProfile: {
        adminPassword: "replacePassword1234$",
        adminUsername: "azureuser",
    },
});
import pulumi
import pulumi_azure_native as azure_native

managed_cluster = azure_native.containerservice.ManagedCluster("managedCluster",
    addon_profiles={},
    agent_pool_profiles=[{
        "count": 3,
        "enable_node_public_ip": True,
        "mode": azure_native.containerservice.AgentPoolMode.SYSTEM,
        "name": "nodepool1",
        "os_type": azure_native.containerservice.OSType.LINUX,
        "type": azure_native.containerservice.AgentPoolType.VIRTUAL_MACHINE_SCALE_SETS,
        "vm_size": "Standard_DS2_v2",
    }],
    auto_scaler_profile={
        "scale_down_delay_after_add": "15m",
        "scan_interval": "20s",
    },
    disk_encryption_set_id="/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des",
    dns_prefix="dnsprefix1",
    enable_rbac=True,
    http_proxy_config={
        "http_proxy": "http://myproxy.server.com:8080",
        "https_proxy": "https://myproxy.server.com:8080",
        "no_proxy": [
            "localhost",
            "127.0.0.1",
        ],
        "trusted_ca": "Q29uZ3JhdHMhIFlvdSBoYXZlIGZvdW5kIGEgaGlkZGVuIG1lc3NhZ2U=",
    },
    kubernetes_version="",
    linux_profile={
        "admin_username": "azureuser",
        "ssh": {
            "public_keys": [{
                "key_data": "keydata",
            }],
        },
    },
    location="location1",
    network_profile={
        "load_balancer_profile": {
            "managed_outbound_ips": {
                "count": 2,
            },
        },
        "load_balancer_sku": azure_native.containerservice.LoadBalancerSku.STANDARD,
        "outbound_type": azure_native.containerservice.OutboundType.LOAD_BALANCER,
    },
    resource_group_name="rg1",
    resource_name_="clustername1",
    service_principal_profile={
        "client_id": "clientid",
        "secret": "secret",
    },
    sku={
        "name": "Basic",
        "tier": azure_native.containerservice.ManagedClusterSKUTier.FREE,
    },
    tags={
        "archv2": "",
        "tier": "production",
    },
    windows_profile={
        "admin_password": "replacePassword1234$",
        "admin_username": "azureuser",
    })
package main

import (
	containerservice "github.com/pulumi/pulumi-azure-native-sdk/containerservice/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := containerservice.NewManagedCluster(ctx, "managedCluster", &containerservice.ManagedClusterArgs{
			AddonProfiles: containerservice.ManagedClusterAddonProfileMap{},
			AgentPoolProfiles: containerservice.ManagedClusterAgentPoolProfileArray{
				&containerservice.ManagedClusterAgentPoolProfileArgs{
					Count:              pulumi.Int(3),
					EnableNodePublicIP: pulumi.Bool(true),
					Mode:               pulumi.String(containerservice.AgentPoolModeSystem),
					Name:               pulumi.String("nodepool1"),
					OsType:             pulumi.String(containerservice.OSTypeLinux),
					Type:               pulumi.String(containerservice.AgentPoolTypeVirtualMachineScaleSets),
					VmSize:             pulumi.String("Standard_DS2_v2"),
				},
			},
			AutoScalerProfile: &containerservice.ManagedClusterPropertiesAutoScalerProfileArgs{
				ScaleDownDelayAfterAdd: pulumi.String("15m"),
				ScanInterval:           pulumi.String("20s"),
			},
			DiskEncryptionSetID: pulumi.String("/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des"),
			DnsPrefix:           pulumi.String("dnsprefix1"),
			EnableRBAC:          pulumi.Bool(true),
			HttpProxyConfig: &containerservice.ManagedClusterHTTPProxyConfigArgs{
				HttpProxy:  pulumi.String("http://myproxy.server.com:8080"),
				HttpsProxy: pulumi.String("https://myproxy.server.com:8080"),
				NoProxy: pulumi.StringArray{
					pulumi.String("localhost"),
					pulumi.String("127.0.0.1"),
				},
				TrustedCa: pulumi.String("Q29uZ3JhdHMhIFlvdSBoYXZlIGZvdW5kIGEgaGlkZGVuIG1lc3NhZ2U="),
			},
			KubernetesVersion: pulumi.String(""),
			LinuxProfile: &containerservice.ContainerServiceLinuxProfileArgs{
				AdminUsername: pulumi.String("azureuser"),
				Ssh: &containerservice.ContainerServiceSshConfigurationArgs{
					PublicKeys: containerservice.ContainerServiceSshPublicKeyArray{
						&containerservice.ContainerServiceSshPublicKeyArgs{
							KeyData: pulumi.String("keydata"),
						},
					},
				},
			},
			Location: pulumi.String("location1"),
			NetworkProfile: &containerservice.ContainerServiceNetworkProfileArgs{
				LoadBalancerProfile: &containerservice.ManagedClusterLoadBalancerProfileArgs{
					ManagedOutboundIPs: &containerservice.ManagedClusterLoadBalancerProfileManagedOutboundIPsArgs{
						Count: pulumi.Int(2),
					},
				},
				LoadBalancerSku: pulumi.String(containerservice.LoadBalancerSkuStandard),
				OutboundType:    pulumi.String(containerservice.OutboundTypeLoadBalancer),
			},
			ResourceGroupName: pulumi.String("rg1"),
			ResourceName:      pulumi.String("clustername1"),
			ServicePrincipalProfile: &containerservice.ManagedClusterServicePrincipalProfileArgs{
				ClientId: pulumi.String("clientid"),
				Secret:   pulumi.String("secret"),
			},
			Sku: &containerservice.ManagedClusterSKUArgs{
				Name: pulumi.String("Basic"),
				Tier: pulumi.String(containerservice.ManagedClusterSKUTierFree),
			},
			Tags: pulumi.StringMap{
				"archv2": pulumi.String(""),
				"tier":   pulumi.String("production"),
			},
			WindowsProfile: &containerservice.ManagedClusterWindowsProfileArgs{
				AdminPassword: pulumi.String("replacePassword1234$"),
				AdminUsername: pulumi.String("azureuser"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var managedCluster = new AzureNative.ContainerService.ManagedCluster("managedCluster", new()
    {
        AddonProfiles = null,
        AgentPoolProfiles = new[]
        {
            new AzureNative.ContainerService.Inputs.ManagedClusterAgentPoolProfileArgs
            {
                Count = 3,
                EnableNodePublicIP = true,
                Mode = AzureNative.ContainerService.AgentPoolMode.System,
                Name = "nodepool1",
                OsType = AzureNative.ContainerService.OSType.Linux,
                Type = AzureNative.ContainerService.AgentPoolType.VirtualMachineScaleSets,
                VmSize = "Standard_DS2_v2",
            },
        },
        AutoScalerProfile = new AzureNative.ContainerService.Inputs.ManagedClusterPropertiesAutoScalerProfileArgs
        {
            ScaleDownDelayAfterAdd = "15m",
            ScanInterval = "20s",
        },
        DiskEncryptionSetID = "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des",
        DnsPrefix = "dnsprefix1",
        EnableRBAC = true,
        HttpProxyConfig = new AzureNative.ContainerService.Inputs.ManagedClusterHTTPProxyConfigArgs
        {
            HttpProxy = "http://myproxy.server.com:8080",
            HttpsProxy = "https://myproxy.server.com:8080",
            NoProxy = new[]
            {
                "localhost",
                "127.0.0.1",
            },
            TrustedCa = "Q29uZ3JhdHMhIFlvdSBoYXZlIGZvdW5kIGEgaGlkZGVuIG1lc3NhZ2U=",
        },
        KubernetesVersion = "",
        LinuxProfile = new AzureNative.ContainerService.Inputs.ContainerServiceLinuxProfileArgs
        {
            AdminUsername = "azureuser",
            Ssh = new AzureNative.ContainerService.Inputs.ContainerServiceSshConfigurationArgs
            {
                PublicKeys = new[]
                {
                    new AzureNative.ContainerService.Inputs.ContainerServiceSshPublicKeyArgs
                    {
                        KeyData = "keydata",
                    },
                },
            },
        },
        Location = "location1",
        NetworkProfile = new AzureNative.ContainerService.Inputs.ContainerServiceNetworkProfileArgs
        {
            LoadBalancerProfile = new AzureNative.ContainerService.Inputs.ManagedClusterLoadBalancerProfileArgs
            {
                ManagedOutboundIPs = new AzureNative.ContainerService.Inputs.ManagedClusterLoadBalancerProfileManagedOutboundIPsArgs
                {
                    Count = 2,
                },
            },
            LoadBalancerSku = AzureNative.ContainerService.LoadBalancerSku.Standard,
            OutboundType = AzureNative.ContainerService.OutboundType.LoadBalancer,
        },
        ResourceGroupName = "rg1",
        ResourceName = "clustername1",
        ServicePrincipalProfile = new AzureNative.ContainerService.Inputs.ManagedClusterServicePrincipalProfileArgs
        {
            ClientId = "clientid",
            Secret = "secret",
        },
        Sku = new AzureNative.ContainerService.Inputs.ManagedClusterSKUArgs
        {
            Name = "Basic",
            Tier = AzureNative.ContainerService.ManagedClusterSKUTier.Free,
        },
        Tags = 
        {
            { "archv2", "" },
            { "tier", "production" },
        },
        WindowsProfile = new AzureNative.ContainerService.Inputs.ManagedClusterWindowsProfileArgs
        {
            AdminPassword = "replacePassword1234$",
            AdminUsername = "azureuser",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.containerservice.ManagedCluster;
import com.pulumi.azurenative.containerservice.ManagedClusterArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterAgentPoolProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterPropertiesAutoScalerProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterHTTPProxyConfigArgs;
import com.pulumi.azurenative.containerservice.inputs.ContainerServiceLinuxProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ContainerServiceSshConfigurationArgs;
import com.pulumi.azurenative.containerservice.inputs.ContainerServiceNetworkProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterLoadBalancerProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterLoadBalancerProfileManagedOutboundIPsArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterServicePrincipalProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterSKUArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterWindowsProfileArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var managedCluster = new ManagedCluster("managedCluster", ManagedClusterArgs.builder()
            .addonProfiles(Map.ofEntries(
            ))
            .agentPoolProfiles(ManagedClusterAgentPoolProfileArgs.builder()
                .count(3)
                .enableNodePublicIP(true)
                .mode("System")
                .name("nodepool1")
                .osType("Linux")
                .type("VirtualMachineScaleSets")
                .vmSize("Standard_DS2_v2")
                .build())
            .autoScalerProfile(ManagedClusterPropertiesAutoScalerProfileArgs.builder()
                .scaleDownDelayAfterAdd("15m")
                .scanInterval("20s")
                .build())
            .diskEncryptionSetID("/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des")
            .dnsPrefix("dnsprefix1")
            .enableRBAC(true)
            .httpProxyConfig(ManagedClusterHTTPProxyConfigArgs.builder()
                .httpProxy("http://myproxy.server.com:8080")
                .httpsProxy("https://myproxy.server.com:8080")
                .noProxy(                
                    "localhost",
                    "127.0.0.1")
                .trustedCa("Q29uZ3JhdHMhIFlvdSBoYXZlIGZvdW5kIGEgaGlkZGVuIG1lc3NhZ2U=")
                .build())
            .kubernetesVersion("")
            .linuxProfile(ContainerServiceLinuxProfileArgs.builder()
                .adminUsername("azureuser")
                .ssh(ContainerServiceSshConfigurationArgs.builder()
                    .publicKeys(ContainerServiceSshPublicKeyArgs.builder()
                        .keyData("keydata")
                        .build())
                    .build())
                .build())
            .location("location1")
            .networkProfile(ContainerServiceNetworkProfileArgs.builder()
                .loadBalancerProfile(ManagedClusterLoadBalancerProfileArgs.builder()
                    .managedOutboundIPs(ManagedClusterLoadBalancerProfileManagedOutboundIPsArgs.builder()
                        .count(2)
                        .build())
                    .build())
                .loadBalancerSku("standard")
                .outboundType("loadBalancer")
                .build())
            .resourceGroupName("rg1")
            .resourceName("clustername1")
            .servicePrincipalProfile(ManagedClusterServicePrincipalProfileArgs.builder()
                .clientId("clientid")
                .secret("secret")
                .build())
            .sku(ManagedClusterSKUArgs.builder()
                .name("Basic")
                .tier("Free")
                .build())
            .tags(Map.ofEntries(
                Map.entry("archv2", ""),
                Map.entry("tier", "production")
            ))
            .windowsProfile(ManagedClusterWindowsProfileArgs.builder()
                .adminPassword("replacePassword1234$")
                .adminUsername("azureuser")
                .build())
            .build());

    }
}
resources:
  managedCluster:
    type: azure-native:containerservice:ManagedCluster
    properties:
      addonProfiles: {}
      agentPoolProfiles:
        - count: 3
          enableNodePublicIP: true
          mode: System
          name: nodepool1
          osType: Linux
          type: VirtualMachineScaleSets
          vmSize: Standard_DS2_v2
      autoScalerProfile:
        scaleDownDelayAfterAdd: 15m
        scanInterval: 20s
      diskEncryptionSetID: /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des
      dnsPrefix: dnsprefix1
      enableRBAC: true
      httpProxyConfig:
        httpProxy: http://myproxy.server.com:8080
        httpsProxy: https://myproxy.server.com:8080
        noProxy:
          - localhost
          - 127.0.0.1
        trustedCa: Q29uZ3JhdHMhIFlvdSBoYXZlIGZvdW5kIGEgaGlkZGVuIG1lc3NhZ2U=
      kubernetesVersion: ""
      linuxProfile:
        adminUsername: azureuser
        ssh:
          publicKeys:
            - keyData: keydata
      location: location1
      networkProfile:
        loadBalancerProfile:
          managedOutboundIPs:
            count: 2
        loadBalancerSku: standard
        outboundType: loadBalancer
      resourceGroupName: rg1
      resourceName: clustername1
      servicePrincipalProfile:
        clientId: clientid
        secret: secret
      sku:
        name: Basic
        tier: Free
      tags:
        archv2: ""
        tier: production
      windowsProfile:
        adminPassword: replacePassword1234$
        adminUsername: azureuser

The httpProxyConfig property defines proxy servers for HTTP and HTTPS traffic. The httpProxy and httpsProxy properties specify proxy URLs, while noProxy lists addresses that bypass the proxy (typically localhost and cluster internal ranges). The trustedCa property contains a base64-encoded CA certificate that nodes use to trust the HTTPS proxy’s certificate chain.

Use AKS-managed NAT gateway for outbound connectivity

Clusters that need predictable outbound IP addresses without managing load balancer resources can use AKS-managed NAT gateways for egress traffic.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const managedCluster = new azure_native.containerservice.ManagedCluster("managedCluster", {
    addonProfiles: {},
    agentPoolProfiles: [{
        count: 3,
        enableNodePublicIP: false,
        mode: azure_native.containerservice.AgentPoolMode.System,
        name: "nodepool1",
        osType: azure_native.containerservice.OSType.Linux,
        type: azure_native.containerservice.AgentPoolType.VirtualMachineScaleSets,
        vmSize: "Standard_DS2_v2",
    }],
    autoScalerProfile: {
        scaleDownDelayAfterAdd: "15m",
        scanInterval: "20s",
    },
    diskEncryptionSetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des",
    dnsPrefix: "dnsprefix1",
    enableRBAC: true,
    kubernetesVersion: "",
    linuxProfile: {
        adminUsername: "azureuser",
        ssh: {
            publicKeys: [{
                keyData: "keydata",
            }],
        },
    },
    location: "location1",
    networkProfile: {
        loadBalancerSku: azure_native.containerservice.LoadBalancerSku.Standard,
        natGatewayProfile: {
            managedOutboundIPProfile: {
                count: 2,
            },
        },
        outboundType: azure_native.containerservice.OutboundType.ManagedNATGateway,
    },
    resourceGroupName: "rg1",
    resourceName: "clustername1",
    servicePrincipalProfile: {
        clientId: "clientid",
        secret: "secret",
    },
    sku: {
        name: "Basic",
        tier: azure_native.containerservice.ManagedClusterSKUTier.Free,
    },
    tags: {
        archv2: "",
        tier: "production",
    },
    windowsProfile: {
        adminPassword: "replacePassword1234$",
        adminUsername: "azureuser",
    },
});
import pulumi
import pulumi_azure_native as azure_native

managed_cluster = azure_native.containerservice.ManagedCluster("managedCluster",
    addon_profiles={},
    agent_pool_profiles=[{
        "count": 3,
        "enable_node_public_ip": False,
        "mode": azure_native.containerservice.AgentPoolMode.SYSTEM,
        "name": "nodepool1",
        "os_type": azure_native.containerservice.OSType.LINUX,
        "type": azure_native.containerservice.AgentPoolType.VIRTUAL_MACHINE_SCALE_SETS,
        "vm_size": "Standard_DS2_v2",
    }],
    auto_scaler_profile={
        "scale_down_delay_after_add": "15m",
        "scan_interval": "20s",
    },
    disk_encryption_set_id="/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des",
    dns_prefix="dnsprefix1",
    enable_rbac=True,
    kubernetes_version="",
    linux_profile={
        "admin_username": "azureuser",
        "ssh": {
            "public_keys": [{
                "key_data": "keydata",
            }],
        },
    },
    location="location1",
    network_profile={
        "load_balancer_sku": azure_native.containerservice.LoadBalancerSku.STANDARD,
        "nat_gateway_profile": {
            "managed_outbound_ip_profile": {
                "count": 2,
            },
        },
        "outbound_type": azure_native.containerservice.OutboundType.MANAGED_NAT_GATEWAY,
    },
    resource_group_name="rg1",
    resource_name_="clustername1",
    service_principal_profile={
        "client_id": "clientid",
        "secret": "secret",
    },
    sku={
        "name": "Basic",
        "tier": azure_native.containerservice.ManagedClusterSKUTier.FREE,
    },
    tags={
        "archv2": "",
        "tier": "production",
    },
    windows_profile={
        "admin_password": "replacePassword1234$",
        "admin_username": "azureuser",
    })
package main

import (
	containerservice "github.com/pulumi/pulumi-azure-native-sdk/containerservice/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := containerservice.NewManagedCluster(ctx, "managedCluster", &containerservice.ManagedClusterArgs{
			AddonProfiles: containerservice.ManagedClusterAddonProfileMap{},
			AgentPoolProfiles: containerservice.ManagedClusterAgentPoolProfileArray{
				&containerservice.ManagedClusterAgentPoolProfileArgs{
					Count:              pulumi.Int(3),
					EnableNodePublicIP: pulumi.Bool(false),
					Mode:               pulumi.String(containerservice.AgentPoolModeSystem),
					Name:               pulumi.String("nodepool1"),
					OsType:             pulumi.String(containerservice.OSTypeLinux),
					Type:               pulumi.String(containerservice.AgentPoolTypeVirtualMachineScaleSets),
					VmSize:             pulumi.String("Standard_DS2_v2"),
				},
			},
			AutoScalerProfile: &containerservice.ManagedClusterPropertiesAutoScalerProfileArgs{
				ScaleDownDelayAfterAdd: pulumi.String("15m"),
				ScanInterval:           pulumi.String("20s"),
			},
			DiskEncryptionSetID: pulumi.String("/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des"),
			DnsPrefix:           pulumi.String("dnsprefix1"),
			EnableRBAC:          pulumi.Bool(true),
			KubernetesVersion:   pulumi.String(""),
			LinuxProfile: &containerservice.ContainerServiceLinuxProfileArgs{
				AdminUsername: pulumi.String("azureuser"),
				Ssh: &containerservice.ContainerServiceSshConfigurationArgs{
					PublicKeys: containerservice.ContainerServiceSshPublicKeyArray{
						&containerservice.ContainerServiceSshPublicKeyArgs{
							KeyData: pulumi.String("keydata"),
						},
					},
				},
			},
			Location: pulumi.String("location1"),
			NetworkProfile: &containerservice.ContainerServiceNetworkProfileArgs{
				LoadBalancerSku: pulumi.String(containerservice.LoadBalancerSkuStandard),
				NatGatewayProfile: &containerservice.ManagedClusterNATGatewayProfileArgs{
					ManagedOutboundIPProfile: &containerservice.ManagedClusterManagedOutboundIPProfileArgs{
						Count: pulumi.Int(2),
					},
				},
				OutboundType: pulumi.String(containerservice.OutboundTypeManagedNATGateway),
			},
			ResourceGroupName: pulumi.String("rg1"),
			ResourceName:      pulumi.String("clustername1"),
			ServicePrincipalProfile: &containerservice.ManagedClusterServicePrincipalProfileArgs{
				ClientId: pulumi.String("clientid"),
				Secret:   pulumi.String("secret"),
			},
			Sku: &containerservice.ManagedClusterSKUArgs{
				Name: pulumi.String("Basic"),
				Tier: pulumi.String(containerservice.ManagedClusterSKUTierFree),
			},
			Tags: pulumi.StringMap{
				"archv2": pulumi.String(""),
				"tier":   pulumi.String("production"),
			},
			WindowsProfile: &containerservice.ManagedClusterWindowsProfileArgs{
				AdminPassword: pulumi.String("replacePassword1234$"),
				AdminUsername: pulumi.String("azureuser"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var managedCluster = new AzureNative.ContainerService.ManagedCluster("managedCluster", new()
    {
        AddonProfiles = null,
        AgentPoolProfiles = new[]
        {
            new AzureNative.ContainerService.Inputs.ManagedClusterAgentPoolProfileArgs
            {
                Count = 3,
                EnableNodePublicIP = false,
                Mode = AzureNative.ContainerService.AgentPoolMode.System,
                Name = "nodepool1",
                OsType = AzureNative.ContainerService.OSType.Linux,
                Type = AzureNative.ContainerService.AgentPoolType.VirtualMachineScaleSets,
                VmSize = "Standard_DS2_v2",
            },
        },
        AutoScalerProfile = new AzureNative.ContainerService.Inputs.ManagedClusterPropertiesAutoScalerProfileArgs
        {
            ScaleDownDelayAfterAdd = "15m",
            ScanInterval = "20s",
        },
        DiskEncryptionSetID = "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des",
        DnsPrefix = "dnsprefix1",
        EnableRBAC = true,
        KubernetesVersion = "",
        LinuxProfile = new AzureNative.ContainerService.Inputs.ContainerServiceLinuxProfileArgs
        {
            AdminUsername = "azureuser",
            Ssh = new AzureNative.ContainerService.Inputs.ContainerServiceSshConfigurationArgs
            {
                PublicKeys = new[]
                {
                    new AzureNative.ContainerService.Inputs.ContainerServiceSshPublicKeyArgs
                    {
                        KeyData = "keydata",
                    },
                },
            },
        },
        Location = "location1",
        NetworkProfile = new AzureNative.ContainerService.Inputs.ContainerServiceNetworkProfileArgs
        {
            LoadBalancerSku = AzureNative.ContainerService.LoadBalancerSku.Standard,
            NatGatewayProfile = new AzureNative.ContainerService.Inputs.ManagedClusterNATGatewayProfileArgs
            {
                ManagedOutboundIPProfile = new AzureNative.ContainerService.Inputs.ManagedClusterManagedOutboundIPProfileArgs
                {
                    Count = 2,
                },
            },
            OutboundType = AzureNative.ContainerService.OutboundType.ManagedNATGateway,
        },
        ResourceGroupName = "rg1",
        ResourceName = "clustername1",
        ServicePrincipalProfile = new AzureNative.ContainerService.Inputs.ManagedClusterServicePrincipalProfileArgs
        {
            ClientId = "clientid",
            Secret = "secret",
        },
        Sku = new AzureNative.ContainerService.Inputs.ManagedClusterSKUArgs
        {
            Name = "Basic",
            Tier = AzureNative.ContainerService.ManagedClusterSKUTier.Free,
        },
        Tags = 
        {
            { "archv2", "" },
            { "tier", "production" },
        },
        WindowsProfile = new AzureNative.ContainerService.Inputs.ManagedClusterWindowsProfileArgs
        {
            AdminPassword = "replacePassword1234$",
            AdminUsername = "azureuser",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.containerservice.ManagedCluster;
import com.pulumi.azurenative.containerservice.ManagedClusterArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterAgentPoolProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterPropertiesAutoScalerProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ContainerServiceLinuxProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ContainerServiceSshConfigurationArgs;
import com.pulumi.azurenative.containerservice.inputs.ContainerServiceNetworkProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterNATGatewayProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterManagedOutboundIPProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterServicePrincipalProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterSKUArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterWindowsProfileArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var managedCluster = new ManagedCluster("managedCluster", ManagedClusterArgs.builder()
            .addonProfiles(Map.ofEntries(
            ))
            .agentPoolProfiles(ManagedClusterAgentPoolProfileArgs.builder()
                .count(3)
                .enableNodePublicIP(false)
                .mode("System")
                .name("nodepool1")
                .osType("Linux")
                .type("VirtualMachineScaleSets")
                .vmSize("Standard_DS2_v2")
                .build())
            .autoScalerProfile(ManagedClusterPropertiesAutoScalerProfileArgs.builder()
                .scaleDownDelayAfterAdd("15m")
                .scanInterval("20s")
                .build())
            .diskEncryptionSetID("/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des")
            .dnsPrefix("dnsprefix1")
            .enableRBAC(true)
            .kubernetesVersion("")
            .linuxProfile(ContainerServiceLinuxProfileArgs.builder()
                .adminUsername("azureuser")
                .ssh(ContainerServiceSshConfigurationArgs.builder()
                    .publicKeys(ContainerServiceSshPublicKeyArgs.builder()
                        .keyData("keydata")
                        .build())
                    .build())
                .build())
            .location("location1")
            .networkProfile(ContainerServiceNetworkProfileArgs.builder()
                .loadBalancerSku("standard")
                .natGatewayProfile(ManagedClusterNATGatewayProfileArgs.builder()
                    .managedOutboundIPProfile(ManagedClusterManagedOutboundIPProfileArgs.builder()
                        .count(2)
                        .build())
                    .build())
                .outboundType("managedNATGateway")
                .build())
            .resourceGroupName("rg1")
            .resourceName("clustername1")
            .servicePrincipalProfile(ManagedClusterServicePrincipalProfileArgs.builder()
                .clientId("clientid")
                .secret("secret")
                .build())
            .sku(ManagedClusterSKUArgs.builder()
                .name("Basic")
                .tier("Free")
                .build())
            .tags(Map.ofEntries(
                Map.entry("archv2", ""),
                Map.entry("tier", "production")
            ))
            .windowsProfile(ManagedClusterWindowsProfileArgs.builder()
                .adminPassword("replacePassword1234$")
                .adminUsername("azureuser")
                .build())
            .build());

    }
}
resources:
  managedCluster:
    type: azure-native:containerservice:ManagedCluster
    properties:
      addonProfiles: {}
      agentPoolProfiles:
        - count: 3
          enableNodePublicIP: false
          mode: System
          name: nodepool1
          osType: Linux
          type: VirtualMachineScaleSets
          vmSize: Standard_DS2_v2
      autoScalerProfile:
        scaleDownDelayAfterAdd: 15m
        scanInterval: 20s
      diskEncryptionSetID: /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des
      dnsPrefix: dnsprefix1
      enableRBAC: true
      kubernetesVersion: ""
      linuxProfile:
        adminUsername: azureuser
        ssh:
          publicKeys:
            - keyData: keydata
      location: location1
      networkProfile:
        loadBalancerSku: standard
        natGatewayProfile:
          managedOutboundIPProfile:
            count: 2
        outboundType: managedNATGateway
      resourceGroupName: rg1
      resourceName: clustername1
      servicePrincipalProfile:
        clientId: clientid
        secret: secret
      sku:
        name: Basic
        tier: Free
      tags:
        archv2: ""
        tier: production
      windowsProfile:
        adminPassword: replacePassword1234$
        adminUsername: azureuser

Setting outboundType to managedNATGateway instructs AKS to provision a NAT gateway for cluster egress. The natGatewayProfile configures the gateway, with managedOutboundIPProfile specifying how many public IPs to allocate. This provides stable outbound IPs without requiring load balancer configuration.

Enable Istio service mesh with custom certificate authority

Applications requiring service-to-service encryption and traffic management can use Azure Service Mesh (Istio) with certificates from Azure Key Vault.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const managedCluster = new azure_native.containerservice.ManagedCluster("managedCluster", {
    addonProfiles: {
        azureKeyvaultSecretsProvider: {
            config: {
                enableSecretRotation: "true",
                rotationPollInterval: "2m",
            },
            enabled: true,
        },
    },
    agentPoolProfiles: [{
        count: 3,
        enableNodePublicIP: true,
        mode: azure_native.containerservice.AgentPoolMode.System,
        name: "nodepool1",
        osType: azure_native.containerservice.OSType.Linux,
        type: azure_native.containerservice.AgentPoolType.VirtualMachineScaleSets,
        vmSize: "Standard_DS2_v2",
    }],
    autoScalerProfile: {
        scaleDownDelayAfterAdd: "15m",
        scanInterval: "20s",
    },
    diskEncryptionSetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des",
    dnsPrefix: "dnsprefix1",
    enableRBAC: true,
    kubernetesVersion: "",
    linuxProfile: {
        adminUsername: "azureuser",
        ssh: {
            publicKeys: [{
                keyData: "keydata",
            }],
        },
    },
    location: "location1",
    networkProfile: {
        loadBalancerProfile: {
            managedOutboundIPs: {
                count: 2,
            },
        },
        loadBalancerSku: azure_native.containerservice.LoadBalancerSku.Standard,
        outboundType: azure_native.containerservice.OutboundType.LoadBalancer,
    },
    resourceGroupName: "rg1",
    resourceName: "clustername1",
    serviceMeshProfile: {
        istio: {
            certificateAuthority: {
                plugin: {
                    certChainObjectName: "cert-chain",
                    certObjectName: "ca-cert",
                    keyObjectName: "ca-key",
                    keyVaultId: "/subscriptions/854c9ddb-fe9e-4aea-8d58-99ed88282881/resourceGroups/ddama-test/providers/Microsoft.KeyVault/vaults/my-akv",
                    rootCertObjectName: "root-cert",
                },
            },
            components: {
                egressGateways: [{
                    enabled: true,
                    gatewayConfigurationName: "test-gateway-configuration",
                    name: "test-istio-egress",
                }],
                ingressGateways: [{
                    enabled: true,
                    mode: azure_native.containerservice.IstioIngressGatewayMode.Internal,
                }],
            },
        },
        mode: azure_native.containerservice.ServiceMeshMode.Istio,
    },
    servicePrincipalProfile: {
        clientId: "clientid",
        secret: "secret",
    },
    sku: {
        name: "Basic",
        tier: azure_native.containerservice.ManagedClusterSKUTier.Free,
    },
    tags: {
        archv2: "",
        tier: "production",
    },
    windowsProfile: {
        adminPassword: "replacePassword1234$",
        adminUsername: "azureuser",
    },
});
import pulumi
import pulumi_azure_native as azure_native

managed_cluster = azure_native.containerservice.ManagedCluster("managedCluster",
    addon_profiles={
        "azureKeyvaultSecretsProvider": {
            "config": {
                "enableSecretRotation": "true",
                "rotationPollInterval": "2m",
            },
            "enabled": True,
        },
    },
    agent_pool_profiles=[{
        "count": 3,
        "enable_node_public_ip": True,
        "mode": azure_native.containerservice.AgentPoolMode.SYSTEM,
        "name": "nodepool1",
        "os_type": azure_native.containerservice.OSType.LINUX,
        "type": azure_native.containerservice.AgentPoolType.VIRTUAL_MACHINE_SCALE_SETS,
        "vm_size": "Standard_DS2_v2",
    }],
    auto_scaler_profile={
        "scale_down_delay_after_add": "15m",
        "scan_interval": "20s",
    },
    disk_encryption_set_id="/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des",
    dns_prefix="dnsprefix1",
    enable_rbac=True,
    kubernetes_version="",
    linux_profile={
        "admin_username": "azureuser",
        "ssh": {
            "public_keys": [{
                "key_data": "keydata",
            }],
        },
    },
    location="location1",
    network_profile={
        "load_balancer_profile": {
            "managed_outbound_ips": {
                "count": 2,
            },
        },
        "load_balancer_sku": azure_native.containerservice.LoadBalancerSku.STANDARD,
        "outbound_type": azure_native.containerservice.OutboundType.LOAD_BALANCER,
    },
    resource_group_name="rg1",
    resource_name_="clustername1",
    service_mesh_profile={
        "istio": {
            "certificate_authority": {
                "plugin": {
                    "cert_chain_object_name": "cert-chain",
                    "cert_object_name": "ca-cert",
                    "key_object_name": "ca-key",
                    "key_vault_id": "/subscriptions/854c9ddb-fe9e-4aea-8d58-99ed88282881/resourceGroups/ddama-test/providers/Microsoft.KeyVault/vaults/my-akv",
                    "root_cert_object_name": "root-cert",
                },
            },
            "components": {
                "egress_gateways": [{
                    "enabled": True,
                    "gateway_configuration_name": "test-gateway-configuration",
                    "name": "test-istio-egress",
                }],
                "ingress_gateways": [{
                    "enabled": True,
                    "mode": azure_native.containerservice.IstioIngressGatewayMode.INTERNAL,
                }],
            },
        },
        "mode": azure_native.containerservice.ServiceMeshMode.ISTIO,
    },
    service_principal_profile={
        "client_id": "clientid",
        "secret": "secret",
    },
    sku={
        "name": "Basic",
        "tier": azure_native.containerservice.ManagedClusterSKUTier.FREE,
    },
    tags={
        "archv2": "",
        "tier": "production",
    },
    windows_profile={
        "admin_password": "replacePassword1234$",
        "admin_username": "azureuser",
    })
package main

import (
	containerservice "github.com/pulumi/pulumi-azure-native-sdk/containerservice/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := containerservice.NewManagedCluster(ctx, "managedCluster", &containerservice.ManagedClusterArgs{
			AddonProfiles: containerservice.ManagedClusterAddonProfileMap{
				"azureKeyvaultSecretsProvider": &containerservice.ManagedClusterAddonProfileArgs{
					Config: pulumi.StringMap{
						"enableSecretRotation": pulumi.String("true"),
						"rotationPollInterval": pulumi.String("2m"),
					},
					Enabled: pulumi.Bool(true),
				},
			},
			AgentPoolProfiles: containerservice.ManagedClusterAgentPoolProfileArray{
				&containerservice.ManagedClusterAgentPoolProfileArgs{
					Count:              pulumi.Int(3),
					EnableNodePublicIP: pulumi.Bool(true),
					Mode:               pulumi.String(containerservice.AgentPoolModeSystem),
					Name:               pulumi.String("nodepool1"),
					OsType:             pulumi.String(containerservice.OSTypeLinux),
					Type:               pulumi.String(containerservice.AgentPoolTypeVirtualMachineScaleSets),
					VmSize:             pulumi.String("Standard_DS2_v2"),
				},
			},
			AutoScalerProfile: &containerservice.ManagedClusterPropertiesAutoScalerProfileArgs{
				ScaleDownDelayAfterAdd: pulumi.String("15m"),
				ScanInterval:           pulumi.String("20s"),
			},
			DiskEncryptionSetID: pulumi.String("/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des"),
			DnsPrefix:           pulumi.String("dnsprefix1"),
			EnableRBAC:          pulumi.Bool(true),
			KubernetesVersion:   pulumi.String(""),
			LinuxProfile: &containerservice.ContainerServiceLinuxProfileArgs{
				AdminUsername: pulumi.String("azureuser"),
				Ssh: &containerservice.ContainerServiceSshConfigurationArgs{
					PublicKeys: containerservice.ContainerServiceSshPublicKeyArray{
						&containerservice.ContainerServiceSshPublicKeyArgs{
							KeyData: pulumi.String("keydata"),
						},
					},
				},
			},
			Location: pulumi.String("location1"),
			NetworkProfile: &containerservice.ContainerServiceNetworkProfileArgs{
				LoadBalancerProfile: &containerservice.ManagedClusterLoadBalancerProfileArgs{
					ManagedOutboundIPs: &containerservice.ManagedClusterLoadBalancerProfileManagedOutboundIPsArgs{
						Count: pulumi.Int(2),
					},
				},
				LoadBalancerSku: pulumi.String(containerservice.LoadBalancerSkuStandard),
				OutboundType:    pulumi.String(containerservice.OutboundTypeLoadBalancer),
			},
			ResourceGroupName: pulumi.String("rg1"),
			ResourceName:      pulumi.String("clustername1"),
			ServiceMeshProfile: &containerservice.ServiceMeshProfileArgs{
				Istio: &containerservice.IstioServiceMeshArgs{
					CertificateAuthority: &containerservice.IstioCertificateAuthorityArgs{
						Plugin: &containerservice.IstioPluginCertificateAuthorityArgs{
							CertChainObjectName: pulumi.String("cert-chain"),
							CertObjectName:      pulumi.String("ca-cert"),
							KeyObjectName:       pulumi.String("ca-key"),
							KeyVaultId:          pulumi.String("/subscriptions/854c9ddb-fe9e-4aea-8d58-99ed88282881/resourceGroups/ddama-test/providers/Microsoft.KeyVault/vaults/my-akv"),
							RootCertObjectName:  pulumi.String("root-cert"),
						},
					},
					Components: &containerservice.IstioComponentsArgs{
						EgressGateways: containerservice.IstioEgressGatewayArray{
							&containerservice.IstioEgressGatewayArgs{
								Enabled:                  pulumi.Bool(true),
								GatewayConfigurationName: pulumi.String("test-gateway-configuration"),
								Name:                     pulumi.String("test-istio-egress"),
							},
						},
						IngressGateways: containerservice.IstioIngressGatewayArray{
							&containerservice.IstioIngressGatewayArgs{
								Enabled: pulumi.Bool(true),
								Mode:    pulumi.String(containerservice.IstioIngressGatewayModeInternal),
							},
						},
					},
				},
				Mode: pulumi.String(containerservice.ServiceMeshModeIstio),
			},
			ServicePrincipalProfile: &containerservice.ManagedClusterServicePrincipalProfileArgs{
				ClientId: pulumi.String("clientid"),
				Secret:   pulumi.String("secret"),
			},
			Sku: &containerservice.ManagedClusterSKUArgs{
				Name: pulumi.String("Basic"),
				Tier: pulumi.String(containerservice.ManagedClusterSKUTierFree),
			},
			Tags: pulumi.StringMap{
				"archv2": pulumi.String(""),
				"tier":   pulumi.String("production"),
			},
			WindowsProfile: &containerservice.ManagedClusterWindowsProfileArgs{
				AdminPassword: pulumi.String("replacePassword1234$"),
				AdminUsername: pulumi.String("azureuser"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var managedCluster = new AzureNative.ContainerService.ManagedCluster("managedCluster", new()
    {
        AddonProfiles = 
        {
            { "azureKeyvaultSecretsProvider", new AzureNative.ContainerService.Inputs.ManagedClusterAddonProfileArgs
            {
                Config = 
                {
                    { "enableSecretRotation", "true" },
                    { "rotationPollInterval", "2m" },
                },
                Enabled = true,
            } },
        },
        AgentPoolProfiles = new[]
        {
            new AzureNative.ContainerService.Inputs.ManagedClusterAgentPoolProfileArgs
            {
                Count = 3,
                EnableNodePublicIP = true,
                Mode = AzureNative.ContainerService.AgentPoolMode.System,
                Name = "nodepool1",
                OsType = AzureNative.ContainerService.OSType.Linux,
                Type = AzureNative.ContainerService.AgentPoolType.VirtualMachineScaleSets,
                VmSize = "Standard_DS2_v2",
            },
        },
        AutoScalerProfile = new AzureNative.ContainerService.Inputs.ManagedClusterPropertiesAutoScalerProfileArgs
        {
            ScaleDownDelayAfterAdd = "15m",
            ScanInterval = "20s",
        },
        DiskEncryptionSetID = "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des",
        DnsPrefix = "dnsprefix1",
        EnableRBAC = true,
        KubernetesVersion = "",
        LinuxProfile = new AzureNative.ContainerService.Inputs.ContainerServiceLinuxProfileArgs
        {
            AdminUsername = "azureuser",
            Ssh = new AzureNative.ContainerService.Inputs.ContainerServiceSshConfigurationArgs
            {
                PublicKeys = new[]
                {
                    new AzureNative.ContainerService.Inputs.ContainerServiceSshPublicKeyArgs
                    {
                        KeyData = "keydata",
                    },
                },
            },
        },
        Location = "location1",
        NetworkProfile = new AzureNative.ContainerService.Inputs.ContainerServiceNetworkProfileArgs
        {
            LoadBalancerProfile = new AzureNative.ContainerService.Inputs.ManagedClusterLoadBalancerProfileArgs
            {
                ManagedOutboundIPs = new AzureNative.ContainerService.Inputs.ManagedClusterLoadBalancerProfileManagedOutboundIPsArgs
                {
                    Count = 2,
                },
            },
            LoadBalancerSku = AzureNative.ContainerService.LoadBalancerSku.Standard,
            OutboundType = AzureNative.ContainerService.OutboundType.LoadBalancer,
        },
        ResourceGroupName = "rg1",
        ResourceName = "clustername1",
        ServiceMeshProfile = new AzureNative.ContainerService.Inputs.ServiceMeshProfileArgs
        {
            Istio = new AzureNative.ContainerService.Inputs.IstioServiceMeshArgs
            {
                CertificateAuthority = new AzureNative.ContainerService.Inputs.IstioCertificateAuthorityArgs
                {
                    Plugin = new AzureNative.ContainerService.Inputs.IstioPluginCertificateAuthorityArgs
                    {
                        CertChainObjectName = "cert-chain",
                        CertObjectName = "ca-cert",
                        KeyObjectName = "ca-key",
                        KeyVaultId = "/subscriptions/854c9ddb-fe9e-4aea-8d58-99ed88282881/resourceGroups/ddama-test/providers/Microsoft.KeyVault/vaults/my-akv",
                        RootCertObjectName = "root-cert",
                    },
                },
                Components = new AzureNative.ContainerService.Inputs.IstioComponentsArgs
                {
                    EgressGateways = new[]
                    {
                        new AzureNative.ContainerService.Inputs.IstioEgressGatewayArgs
                        {
                            Enabled = true,
                            GatewayConfigurationName = "test-gateway-configuration",
                            Name = "test-istio-egress",
                        },
                    },
                    IngressGateways = new[]
                    {
                        new AzureNative.ContainerService.Inputs.IstioIngressGatewayArgs
                        {
                            Enabled = true,
                            Mode = AzureNative.ContainerService.IstioIngressGatewayMode.Internal,
                        },
                    },
                },
            },
            Mode = AzureNative.ContainerService.ServiceMeshMode.Istio,
        },
        ServicePrincipalProfile = new AzureNative.ContainerService.Inputs.ManagedClusterServicePrincipalProfileArgs
        {
            ClientId = "clientid",
            Secret = "secret",
        },
        Sku = new AzureNative.ContainerService.Inputs.ManagedClusterSKUArgs
        {
            Name = "Basic",
            Tier = AzureNative.ContainerService.ManagedClusterSKUTier.Free,
        },
        Tags = 
        {
            { "archv2", "" },
            { "tier", "production" },
        },
        WindowsProfile = new AzureNative.ContainerService.Inputs.ManagedClusterWindowsProfileArgs
        {
            AdminPassword = "replacePassword1234$",
            AdminUsername = "azureuser",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.containerservice.ManagedCluster;
import com.pulumi.azurenative.containerservice.ManagedClusterArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterAgentPoolProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterPropertiesAutoScalerProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ContainerServiceLinuxProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ContainerServiceSshConfigurationArgs;
import com.pulumi.azurenative.containerservice.inputs.ContainerServiceNetworkProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterLoadBalancerProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterLoadBalancerProfileManagedOutboundIPsArgs;
import com.pulumi.azurenative.containerservice.inputs.ServiceMeshProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.IstioServiceMeshArgs;
import com.pulumi.azurenative.containerservice.inputs.IstioCertificateAuthorityArgs;
import com.pulumi.azurenative.containerservice.inputs.IstioPluginCertificateAuthorityArgs;
import com.pulumi.azurenative.containerservice.inputs.IstioComponentsArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterServicePrincipalProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterSKUArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterWindowsProfileArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var managedCluster = new ManagedCluster("managedCluster", ManagedClusterArgs.builder()
            .addonProfiles(Map.of("azureKeyvaultSecretsProvider", ManagedClusterAddonProfileArgs.builder()
                .config(Map.ofEntries(
                    Map.entry("enableSecretRotation", "true"),
                    Map.entry("rotationPollInterval", "2m")
                ))
                .enabled(true)
                .build()))
            .agentPoolProfiles(ManagedClusterAgentPoolProfileArgs.builder()
                .count(3)
                .enableNodePublicIP(true)
                .mode("System")
                .name("nodepool1")
                .osType("Linux")
                .type("VirtualMachineScaleSets")
                .vmSize("Standard_DS2_v2")
                .build())
            .autoScalerProfile(ManagedClusterPropertiesAutoScalerProfileArgs.builder()
                .scaleDownDelayAfterAdd("15m")
                .scanInterval("20s")
                .build())
            .diskEncryptionSetID("/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des")
            .dnsPrefix("dnsprefix1")
            .enableRBAC(true)
            .kubernetesVersion("")
            .linuxProfile(ContainerServiceLinuxProfileArgs.builder()
                .adminUsername("azureuser")
                .ssh(ContainerServiceSshConfigurationArgs.builder()
                    .publicKeys(ContainerServiceSshPublicKeyArgs.builder()
                        .keyData("keydata")
                        .build())
                    .build())
                .build())
            .location("location1")
            .networkProfile(ContainerServiceNetworkProfileArgs.builder()
                .loadBalancerProfile(ManagedClusterLoadBalancerProfileArgs.builder()
                    .managedOutboundIPs(ManagedClusterLoadBalancerProfileManagedOutboundIPsArgs.builder()
                        .count(2)
                        .build())
                    .build())
                .loadBalancerSku("standard")
                .outboundType("loadBalancer")
                .build())
            .resourceGroupName("rg1")
            .resourceName("clustername1")
            .serviceMeshProfile(ServiceMeshProfileArgs.builder()
                .istio(IstioServiceMeshArgs.builder()
                    .certificateAuthority(IstioCertificateAuthorityArgs.builder()
                        .plugin(IstioPluginCertificateAuthorityArgs.builder()
                            .certChainObjectName("cert-chain")
                            .certObjectName("ca-cert")
                            .keyObjectName("ca-key")
                            .keyVaultId("/subscriptions/854c9ddb-fe9e-4aea-8d58-99ed88282881/resourceGroups/ddama-test/providers/Microsoft.KeyVault/vaults/my-akv")
                            .rootCertObjectName("root-cert")
                            .build())
                        .build())
                    .components(IstioComponentsArgs.builder()
                        .egressGateways(IstioEgressGatewayArgs.builder()
                            .enabled(true)
                            .gatewayConfigurationName("test-gateway-configuration")
                            .name("test-istio-egress")
                            .build())
                        .ingressGateways(IstioIngressGatewayArgs.builder()
                            .enabled(true)
                            .mode("Internal")
                            .build())
                        .build())
                    .build())
                .mode("Istio")
                .build())
            .servicePrincipalProfile(ManagedClusterServicePrincipalProfileArgs.builder()
                .clientId("clientid")
                .secret("secret")
                .build())
            .sku(ManagedClusterSKUArgs.builder()
                .name("Basic")
                .tier("Free")
                .build())
            .tags(Map.ofEntries(
                Map.entry("archv2", ""),
                Map.entry("tier", "production")
            ))
            .windowsProfile(ManagedClusterWindowsProfileArgs.builder()
                .adminPassword("replacePassword1234$")
                .adminUsername("azureuser")
                .build())
            .build());

    }
}
resources:
  managedCluster:
    type: azure-native:containerservice:ManagedCluster
    properties:
      addonProfiles:
        azureKeyvaultSecretsProvider:
          config:
            enableSecretRotation: 'true'
            rotationPollInterval: 2m
          enabled: true
      agentPoolProfiles:
        - count: 3
          enableNodePublicIP: true
          mode: System
          name: nodepool1
          osType: Linux
          type: VirtualMachineScaleSets
          vmSize: Standard_DS2_v2
      autoScalerProfile:
        scaleDownDelayAfterAdd: 15m
        scanInterval: 20s
      diskEncryptionSetID: /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des
      dnsPrefix: dnsprefix1
      enableRBAC: true
      kubernetesVersion: ""
      linuxProfile:
        adminUsername: azureuser
        ssh:
          publicKeys:
            - keyData: keydata
      location: location1
      networkProfile:
        loadBalancerProfile:
          managedOutboundIPs:
            count: 2
        loadBalancerSku: standard
        outboundType: loadBalancer
      resourceGroupName: rg1
      resourceName: clustername1
      serviceMeshProfile:
        istio:
          certificateAuthority:
            plugin:
              certChainObjectName: cert-chain
              certObjectName: ca-cert
              keyObjectName: ca-key
              keyVaultId: /subscriptions/854c9ddb-fe9e-4aea-8d58-99ed88282881/resourceGroups/ddama-test/providers/Microsoft.KeyVault/vaults/my-akv
              rootCertObjectName: root-cert
          components:
            egressGateways:
              - enabled: true
                gatewayConfigurationName: test-gateway-configuration
                name: test-istio-egress
            ingressGateways:
              - enabled: true
                mode: Internal
        mode: Istio
      servicePrincipalProfile:
        clientId: clientid
        secret: secret
      sku:
        name: Basic
        tier: Free
      tags:
        archv2: ""
        tier: production
      windowsProfile:
        adminPassword: replacePassword1234$
        adminUsername: azureuser

The serviceMeshProfile enables Istio on the cluster. The certificateAuthority.plugin configuration points to Key Vault objects containing CA certificates (certObjectName, keyObjectName, rootCertObjectName) that Istio uses for mTLS. The components section defines ingressGateways and egressGateways that handle traffic entering and leaving the mesh.

Integrate Azure RBAC for Kubernetes authorization

Organizations using Azure Active Directory can enable Azure RBAC to manage Kubernetes permissions through Azure role assignments instead of native Kubernetes RBAC.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const managedCluster = new azure_native.containerservice.ManagedCluster("managedCluster", {
    aadProfile: {
        enableAzureRBAC: true,
        managed: true,
    },
    addonProfiles: {},
    agentPoolProfiles: [{
        availabilityZones: [
            "1",
            "2",
            "3",
        ],
        count: 3,
        enableNodePublicIP: true,
        mode: azure_native.containerservice.AgentPoolMode.System,
        name: "nodepool1",
        osType: azure_native.containerservice.OSType.Linux,
        type: azure_native.containerservice.AgentPoolType.VirtualMachineScaleSets,
        vmSize: "Standard_DS1_v2",
    }],
    autoScalerProfile: {
        scaleDownDelayAfterAdd: "15m",
        scanInterval: "20s",
    },
    diskEncryptionSetID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des",
    dnsPrefix: "dnsprefix1",
    enableRBAC: true,
    kubernetesVersion: "",
    linuxProfile: {
        adminUsername: "azureuser",
        ssh: {
            publicKeys: [{
                keyData: "keydata",
            }],
        },
    },
    location: "location1",
    networkProfile: {
        loadBalancerProfile: {
            managedOutboundIPs: {
                count: 2,
            },
        },
        loadBalancerSku: azure_native.containerservice.LoadBalancerSku.Standard,
        outboundType: azure_native.containerservice.OutboundType.LoadBalancer,
    },
    resourceGroupName: "rg1",
    resourceName: "clustername1",
    servicePrincipalProfile: {
        clientId: "clientid",
        secret: "secret",
    },
    sku: {
        name: "Basic",
        tier: azure_native.containerservice.ManagedClusterSKUTier.Free,
    },
    tags: {
        archv2: "",
        tier: "production",
    },
    windowsProfile: {
        adminPassword: "replacePassword1234$",
        adminUsername: "azureuser",
    },
});
import pulumi
import pulumi_azure_native as azure_native

managed_cluster = azure_native.containerservice.ManagedCluster("managedCluster",
    aad_profile={
        "enable_azure_rbac": True,
        "managed": True,
    },
    addon_profiles={},
    agent_pool_profiles=[{
        "availability_zones": [
            "1",
            "2",
            "3",
        ],
        "count": 3,
        "enable_node_public_ip": True,
        "mode": azure_native.containerservice.AgentPoolMode.SYSTEM,
        "name": "nodepool1",
        "os_type": azure_native.containerservice.OSType.LINUX,
        "type": azure_native.containerservice.AgentPoolType.VIRTUAL_MACHINE_SCALE_SETS,
        "vm_size": "Standard_DS1_v2",
    }],
    auto_scaler_profile={
        "scale_down_delay_after_add": "15m",
        "scan_interval": "20s",
    },
    disk_encryption_set_id="/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des",
    dns_prefix="dnsprefix1",
    enable_rbac=True,
    kubernetes_version="",
    linux_profile={
        "admin_username": "azureuser",
        "ssh": {
            "public_keys": [{
                "key_data": "keydata",
            }],
        },
    },
    location="location1",
    network_profile={
        "load_balancer_profile": {
            "managed_outbound_ips": {
                "count": 2,
            },
        },
        "load_balancer_sku": azure_native.containerservice.LoadBalancerSku.STANDARD,
        "outbound_type": azure_native.containerservice.OutboundType.LOAD_BALANCER,
    },
    resource_group_name="rg1",
    resource_name_="clustername1",
    service_principal_profile={
        "client_id": "clientid",
        "secret": "secret",
    },
    sku={
        "name": "Basic",
        "tier": azure_native.containerservice.ManagedClusterSKUTier.FREE,
    },
    tags={
        "archv2": "",
        "tier": "production",
    },
    windows_profile={
        "admin_password": "replacePassword1234$",
        "admin_username": "azureuser",
    })
package main

import (
	containerservice "github.com/pulumi/pulumi-azure-native-sdk/containerservice/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := containerservice.NewManagedCluster(ctx, "managedCluster", &containerservice.ManagedClusterArgs{
			AadProfile: &containerservice.ManagedClusterAADProfileArgs{
				EnableAzureRBAC: pulumi.Bool(true),
				Managed:         pulumi.Bool(true),
			},
			AddonProfiles: containerservice.ManagedClusterAddonProfileMap{},
			AgentPoolProfiles: containerservice.ManagedClusterAgentPoolProfileArray{
				&containerservice.ManagedClusterAgentPoolProfileArgs{
					AvailabilityZones: pulumi.StringArray{
						pulumi.String("1"),
						pulumi.String("2"),
						pulumi.String("3"),
					},
					Count:              pulumi.Int(3),
					EnableNodePublicIP: pulumi.Bool(true),
					Mode:               pulumi.String(containerservice.AgentPoolModeSystem),
					Name:               pulumi.String("nodepool1"),
					OsType:             pulumi.String(containerservice.OSTypeLinux),
					Type:               pulumi.String(containerservice.AgentPoolTypeVirtualMachineScaleSets),
					VmSize:             pulumi.String("Standard_DS1_v2"),
				},
			},
			AutoScalerProfile: &containerservice.ManagedClusterPropertiesAutoScalerProfileArgs{
				ScaleDownDelayAfterAdd: pulumi.String("15m"),
				ScanInterval:           pulumi.String("20s"),
			},
			DiskEncryptionSetID: pulumi.String("/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des"),
			DnsPrefix:           pulumi.String("dnsprefix1"),
			EnableRBAC:          pulumi.Bool(true),
			KubernetesVersion:   pulumi.String(""),
			LinuxProfile: &containerservice.ContainerServiceLinuxProfileArgs{
				AdminUsername: pulumi.String("azureuser"),
				Ssh: &containerservice.ContainerServiceSshConfigurationArgs{
					PublicKeys: containerservice.ContainerServiceSshPublicKeyArray{
						&containerservice.ContainerServiceSshPublicKeyArgs{
							KeyData: pulumi.String("keydata"),
						},
					},
				},
			},
			Location: pulumi.String("location1"),
			NetworkProfile: &containerservice.ContainerServiceNetworkProfileArgs{
				LoadBalancerProfile: &containerservice.ManagedClusterLoadBalancerProfileArgs{
					ManagedOutboundIPs: &containerservice.ManagedClusterLoadBalancerProfileManagedOutboundIPsArgs{
						Count: pulumi.Int(2),
					},
				},
				LoadBalancerSku: pulumi.String(containerservice.LoadBalancerSkuStandard),
				OutboundType:    pulumi.String(containerservice.OutboundTypeLoadBalancer),
			},
			ResourceGroupName: pulumi.String("rg1"),
			ResourceName:      pulumi.String("clustername1"),
			ServicePrincipalProfile: &containerservice.ManagedClusterServicePrincipalProfileArgs{
				ClientId: pulumi.String("clientid"),
				Secret:   pulumi.String("secret"),
			},
			Sku: &containerservice.ManagedClusterSKUArgs{
				Name: pulumi.String("Basic"),
				Tier: pulumi.String(containerservice.ManagedClusterSKUTierFree),
			},
			Tags: pulumi.StringMap{
				"archv2": pulumi.String(""),
				"tier":   pulumi.String("production"),
			},
			WindowsProfile: &containerservice.ManagedClusterWindowsProfileArgs{
				AdminPassword: pulumi.String("replacePassword1234$"),
				AdminUsername: pulumi.String("azureuser"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var managedCluster = new AzureNative.ContainerService.ManagedCluster("managedCluster", new()
    {
        AadProfile = new AzureNative.ContainerService.Inputs.ManagedClusterAADProfileArgs
        {
            EnableAzureRBAC = true,
            Managed = true,
        },
        AddonProfiles = null,
        AgentPoolProfiles = new[]
        {
            new AzureNative.ContainerService.Inputs.ManagedClusterAgentPoolProfileArgs
            {
                AvailabilityZones = new[]
                {
                    "1",
                    "2",
                    "3",
                },
                Count = 3,
                EnableNodePublicIP = true,
                Mode = AzureNative.ContainerService.AgentPoolMode.System,
                Name = "nodepool1",
                OsType = AzureNative.ContainerService.OSType.Linux,
                Type = AzureNative.ContainerService.AgentPoolType.VirtualMachineScaleSets,
                VmSize = "Standard_DS1_v2",
            },
        },
        AutoScalerProfile = new AzureNative.ContainerService.Inputs.ManagedClusterPropertiesAutoScalerProfileArgs
        {
            ScaleDownDelayAfterAdd = "15m",
            ScanInterval = "20s",
        },
        DiskEncryptionSetID = "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des",
        DnsPrefix = "dnsprefix1",
        EnableRBAC = true,
        KubernetesVersion = "",
        LinuxProfile = new AzureNative.ContainerService.Inputs.ContainerServiceLinuxProfileArgs
        {
            AdminUsername = "azureuser",
            Ssh = new AzureNative.ContainerService.Inputs.ContainerServiceSshConfigurationArgs
            {
                PublicKeys = new[]
                {
                    new AzureNative.ContainerService.Inputs.ContainerServiceSshPublicKeyArgs
                    {
                        KeyData = "keydata",
                    },
                },
            },
        },
        Location = "location1",
        NetworkProfile = new AzureNative.ContainerService.Inputs.ContainerServiceNetworkProfileArgs
        {
            LoadBalancerProfile = new AzureNative.ContainerService.Inputs.ManagedClusterLoadBalancerProfileArgs
            {
                ManagedOutboundIPs = new AzureNative.ContainerService.Inputs.ManagedClusterLoadBalancerProfileManagedOutboundIPsArgs
                {
                    Count = 2,
                },
            },
            LoadBalancerSku = AzureNative.ContainerService.LoadBalancerSku.Standard,
            OutboundType = AzureNative.ContainerService.OutboundType.LoadBalancer,
        },
        ResourceGroupName = "rg1",
        ResourceName = "clustername1",
        ServicePrincipalProfile = new AzureNative.ContainerService.Inputs.ManagedClusterServicePrincipalProfileArgs
        {
            ClientId = "clientid",
            Secret = "secret",
        },
        Sku = new AzureNative.ContainerService.Inputs.ManagedClusterSKUArgs
        {
            Name = "Basic",
            Tier = AzureNative.ContainerService.ManagedClusterSKUTier.Free,
        },
        Tags = 
        {
            { "archv2", "" },
            { "tier", "production" },
        },
        WindowsProfile = new AzureNative.ContainerService.Inputs.ManagedClusterWindowsProfileArgs
        {
            AdminPassword = "replacePassword1234$",
            AdminUsername = "azureuser",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.containerservice.ManagedCluster;
import com.pulumi.azurenative.containerservice.ManagedClusterArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterAADProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterAgentPoolProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterPropertiesAutoScalerProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ContainerServiceLinuxProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ContainerServiceSshConfigurationArgs;
import com.pulumi.azurenative.containerservice.inputs.ContainerServiceNetworkProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterLoadBalancerProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterLoadBalancerProfileManagedOutboundIPsArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterServicePrincipalProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterSKUArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterWindowsProfileArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var managedCluster = new ManagedCluster("managedCluster", ManagedClusterArgs.builder()
            .aadProfile(ManagedClusterAADProfileArgs.builder()
                .enableAzureRBAC(true)
                .managed(true)
                .build())
            .addonProfiles(Map.ofEntries(
            ))
            .agentPoolProfiles(ManagedClusterAgentPoolProfileArgs.builder()
                .availabilityZones(                
                    "1",
                    "2",
                    "3")
                .count(3)
                .enableNodePublicIP(true)
                .mode("System")
                .name("nodepool1")
                .osType("Linux")
                .type("VirtualMachineScaleSets")
                .vmSize("Standard_DS1_v2")
                .build())
            .autoScalerProfile(ManagedClusterPropertiesAutoScalerProfileArgs.builder()
                .scaleDownDelayAfterAdd("15m")
                .scanInterval("20s")
                .build())
            .diskEncryptionSetID("/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des")
            .dnsPrefix("dnsprefix1")
            .enableRBAC(true)
            .kubernetesVersion("")
            .linuxProfile(ContainerServiceLinuxProfileArgs.builder()
                .adminUsername("azureuser")
                .ssh(ContainerServiceSshConfigurationArgs.builder()
                    .publicKeys(ContainerServiceSshPublicKeyArgs.builder()
                        .keyData("keydata")
                        .build())
                    .build())
                .build())
            .location("location1")
            .networkProfile(ContainerServiceNetworkProfileArgs.builder()
                .loadBalancerProfile(ManagedClusterLoadBalancerProfileArgs.builder()
                    .managedOutboundIPs(ManagedClusterLoadBalancerProfileManagedOutboundIPsArgs.builder()
                        .count(2)
                        .build())
                    .build())
                .loadBalancerSku("standard")
                .outboundType("loadBalancer")
                .build())
            .resourceGroupName("rg1")
            .resourceName("clustername1")
            .servicePrincipalProfile(ManagedClusterServicePrincipalProfileArgs.builder()
                .clientId("clientid")
                .secret("secret")
                .build())
            .sku(ManagedClusterSKUArgs.builder()
                .name("Basic")
                .tier("Free")
                .build())
            .tags(Map.ofEntries(
                Map.entry("archv2", ""),
                Map.entry("tier", "production")
            ))
            .windowsProfile(ManagedClusterWindowsProfileArgs.builder()
                .adminPassword("replacePassword1234$")
                .adminUsername("azureuser")
                .build())
            .build());

    }
}
resources:
  managedCluster:
    type: azure-native:containerservice:ManagedCluster
    properties:
      aadProfile:
        enableAzureRBAC: true
        managed: true
      addonProfiles: {}
      agentPoolProfiles:
        - availabilityZones:
            - '1'
            - '2'
            - '3'
          count: 3
          enableNodePublicIP: true
          mode: System
          name: nodepool1
          osType: Linux
          type: VirtualMachineScaleSets
          vmSize: Standard_DS1_v2
      autoScalerProfile:
        scaleDownDelayAfterAdd: 15m
        scanInterval: 20s
      diskEncryptionSetID: /subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/rg1/providers/Microsoft.Compute/diskEncryptionSets/des
      dnsPrefix: dnsprefix1
      enableRBAC: true
      kubernetesVersion: ""
      linuxProfile:
        adminUsername: azureuser
        ssh:
          publicKeys:
            - keyData: keydata
      location: location1
      networkProfile:
        loadBalancerProfile:
          managedOutboundIPs:
            count: 2
        loadBalancerSku: standard
        outboundType: loadBalancer
      resourceGroupName: rg1
      resourceName: clustername1
      servicePrincipalProfile:
        clientId: clientid
        secret: secret
      sku:
        name: Basic
        tier: Free
      tags:
        archv2: ""
        tier: production
      windowsProfile:
        adminPassword: replacePassword1234$
        adminUsername: azureuser

The aadProfile.enableAzureRBAC property integrates Azure RBAC with Kubernetes authorization. When enabled with managed set to true, Azure AD users and groups receive Kubernetes permissions through Azure role assignments rather than ClusterRoleBindings. This centralizes access control in Azure AD.

Enable Microsoft Defender and workload identity

Production clusters often require security monitoring through Microsoft Defender and workload identity for pod-level Azure AD authentication.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const managedCluster = new azure_native.containerservice.ManagedCluster("managedCluster", {
    agentPoolProfiles: [{
        count: 3,
        enableNodePublicIP: true,
        mode: azure_native.containerservice.AgentPoolMode.System,
        name: "nodepool1",
        osType: azure_native.containerservice.OSType.Linux,
        type: azure_native.containerservice.AgentPoolType.VirtualMachineScaleSets,
        vmSize: "Standard_DS2_v2",
    }],
    dnsPrefix: "dnsprefix1",
    kubernetesVersion: "",
    linuxProfile: {
        adminUsername: "azureuser",
        ssh: {
            publicKeys: [{
                keyData: "keydata",
            }],
        },
    },
    location: "location1",
    networkProfile: {
        loadBalancerProfile: {
            managedOutboundIPs: {
                count: 2,
            },
        },
        loadBalancerSku: azure_native.containerservice.LoadBalancerSku.Standard,
        outboundType: azure_native.containerservice.OutboundType.LoadBalancer,
    },
    resourceGroupName: "rg1",
    resourceName: "clustername1",
    securityProfile: {
        defender: {
            logAnalyticsWorkspaceResourceId: "/subscriptions/SUB_ID/resourcegroups/RG_NAME/providers/microsoft.operationalinsights/workspaces/WORKSPACE_NAME",
            securityMonitoring: {
                enabled: true,
            },
        },
        workloadIdentity: {
            enabled: true,
        },
    },
    sku: {
        name: "Basic",
        tier: azure_native.containerservice.ManagedClusterSKUTier.Free,
    },
    tags: {
        archv2: "",
        tier: "production",
    },
});
import pulumi
import pulumi_azure_native as azure_native

managed_cluster = azure_native.containerservice.ManagedCluster("managedCluster",
    agent_pool_profiles=[{
        "count": 3,
        "enable_node_public_ip": True,
        "mode": azure_native.containerservice.AgentPoolMode.SYSTEM,
        "name": "nodepool1",
        "os_type": azure_native.containerservice.OSType.LINUX,
        "type": azure_native.containerservice.AgentPoolType.VIRTUAL_MACHINE_SCALE_SETS,
        "vm_size": "Standard_DS2_v2",
    }],
    dns_prefix="dnsprefix1",
    kubernetes_version="",
    linux_profile={
        "admin_username": "azureuser",
        "ssh": {
            "public_keys": [{
                "key_data": "keydata",
            }],
        },
    },
    location="location1",
    network_profile={
        "load_balancer_profile": {
            "managed_outbound_ips": {
                "count": 2,
            },
        },
        "load_balancer_sku": azure_native.containerservice.LoadBalancerSku.STANDARD,
        "outbound_type": azure_native.containerservice.OutboundType.LOAD_BALANCER,
    },
    resource_group_name="rg1",
    resource_name_="clustername1",
    security_profile={
        "defender": {
            "log_analytics_workspace_resource_id": "/subscriptions/SUB_ID/resourcegroups/RG_NAME/providers/microsoft.operationalinsights/workspaces/WORKSPACE_NAME",
            "security_monitoring": {
                "enabled": True,
            },
        },
        "workload_identity": {
            "enabled": True,
        },
    },
    sku={
        "name": "Basic",
        "tier": azure_native.containerservice.ManagedClusterSKUTier.FREE,
    },
    tags={
        "archv2": "",
        "tier": "production",
    })
package main

import (
	containerservice "github.com/pulumi/pulumi-azure-native-sdk/containerservice/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := containerservice.NewManagedCluster(ctx, "managedCluster", &containerservice.ManagedClusterArgs{
			AgentPoolProfiles: containerservice.ManagedClusterAgentPoolProfileArray{
				&containerservice.ManagedClusterAgentPoolProfileArgs{
					Count:              pulumi.Int(3),
					EnableNodePublicIP: pulumi.Bool(true),
					Mode:               pulumi.String(containerservice.AgentPoolModeSystem),
					Name:               pulumi.String("nodepool1"),
					OsType:             pulumi.String(containerservice.OSTypeLinux),
					Type:               pulumi.String(containerservice.AgentPoolTypeVirtualMachineScaleSets),
					VmSize:             pulumi.String("Standard_DS2_v2"),
				},
			},
			DnsPrefix:         pulumi.String("dnsprefix1"),
			KubernetesVersion: pulumi.String(""),
			LinuxProfile: &containerservice.ContainerServiceLinuxProfileArgs{
				AdminUsername: pulumi.String("azureuser"),
				Ssh: &containerservice.ContainerServiceSshConfigurationArgs{
					PublicKeys: containerservice.ContainerServiceSshPublicKeyArray{
						&containerservice.ContainerServiceSshPublicKeyArgs{
							KeyData: pulumi.String("keydata"),
						},
					},
				},
			},
			Location: pulumi.String("location1"),
			NetworkProfile: &containerservice.ContainerServiceNetworkProfileArgs{
				LoadBalancerProfile: &containerservice.ManagedClusterLoadBalancerProfileArgs{
					ManagedOutboundIPs: &containerservice.ManagedClusterLoadBalancerProfileManagedOutboundIPsArgs{
						Count: pulumi.Int(2),
					},
				},
				LoadBalancerSku: pulumi.String(containerservice.LoadBalancerSkuStandard),
				OutboundType:    pulumi.String(containerservice.OutboundTypeLoadBalancer),
			},
			ResourceGroupName: pulumi.String("rg1"),
			ResourceName:      pulumi.String("clustername1"),
			SecurityProfile: &containerservice.ManagedClusterSecurityProfileArgs{
				Defender: &containerservice.ManagedClusterSecurityProfileDefenderArgs{
					LogAnalyticsWorkspaceResourceId: pulumi.String("/subscriptions/SUB_ID/resourcegroups/RG_NAME/providers/microsoft.operationalinsights/workspaces/WORKSPACE_NAME"),
					SecurityMonitoring: &containerservice.ManagedClusterSecurityProfileDefenderSecurityMonitoringArgs{
						Enabled: pulumi.Bool(true),
					},
				},
				WorkloadIdentity: &containerservice.ManagedClusterSecurityProfileWorkloadIdentityArgs{
					Enabled: pulumi.Bool(true),
				},
			},
			Sku: &containerservice.ManagedClusterSKUArgs{
				Name: pulumi.String("Basic"),
				Tier: pulumi.String(containerservice.ManagedClusterSKUTierFree),
			},
			Tags: pulumi.StringMap{
				"archv2": pulumi.String(""),
				"tier":   pulumi.String("production"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;

return await Deployment.RunAsync(() => 
{
    var managedCluster = new AzureNative.ContainerService.ManagedCluster("managedCluster", new()
    {
        AgentPoolProfiles = new[]
        {
            new AzureNative.ContainerService.Inputs.ManagedClusterAgentPoolProfileArgs
            {
                Count = 3,
                EnableNodePublicIP = true,
                Mode = AzureNative.ContainerService.AgentPoolMode.System,
                Name = "nodepool1",
                OsType = AzureNative.ContainerService.OSType.Linux,
                Type = AzureNative.ContainerService.AgentPoolType.VirtualMachineScaleSets,
                VmSize = "Standard_DS2_v2",
            },
        },
        DnsPrefix = "dnsprefix1",
        KubernetesVersion = "",
        LinuxProfile = new AzureNative.ContainerService.Inputs.ContainerServiceLinuxProfileArgs
        {
            AdminUsername = "azureuser",
            Ssh = new AzureNative.ContainerService.Inputs.ContainerServiceSshConfigurationArgs
            {
                PublicKeys = new[]
                {
                    new AzureNative.ContainerService.Inputs.ContainerServiceSshPublicKeyArgs
                    {
                        KeyData = "keydata",
                    },
                },
            },
        },
        Location = "location1",
        NetworkProfile = new AzureNative.ContainerService.Inputs.ContainerServiceNetworkProfileArgs
        {
            LoadBalancerProfile = new AzureNative.ContainerService.Inputs.ManagedClusterLoadBalancerProfileArgs
            {
                ManagedOutboundIPs = new AzureNative.ContainerService.Inputs.ManagedClusterLoadBalancerProfileManagedOutboundIPsArgs
                {
                    Count = 2,
                },
            },
            LoadBalancerSku = AzureNative.ContainerService.LoadBalancerSku.Standard,
            OutboundType = AzureNative.ContainerService.OutboundType.LoadBalancer,
        },
        ResourceGroupName = "rg1",
        ResourceName = "clustername1",
        SecurityProfile = new AzureNative.ContainerService.Inputs.ManagedClusterSecurityProfileArgs
        {
            Defender = new AzureNative.ContainerService.Inputs.ManagedClusterSecurityProfileDefenderArgs
            {
                LogAnalyticsWorkspaceResourceId = "/subscriptions/SUB_ID/resourcegroups/RG_NAME/providers/microsoft.operationalinsights/workspaces/WORKSPACE_NAME",
                SecurityMonitoring = new AzureNative.ContainerService.Inputs.ManagedClusterSecurityProfileDefenderSecurityMonitoringArgs
                {
                    Enabled = true,
                },
            },
            WorkloadIdentity = new AzureNative.ContainerService.Inputs.ManagedClusterSecurityProfileWorkloadIdentityArgs
            {
                Enabled = true,
            },
        },
        Sku = new AzureNative.ContainerService.Inputs.ManagedClusterSKUArgs
        {
            Name = "Basic",
            Tier = AzureNative.ContainerService.ManagedClusterSKUTier.Free,
        },
        Tags = 
        {
            { "archv2", "" },
            { "tier", "production" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.containerservice.ManagedCluster;
import com.pulumi.azurenative.containerservice.ManagedClusterArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterAgentPoolProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ContainerServiceLinuxProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ContainerServiceSshConfigurationArgs;
import com.pulumi.azurenative.containerservice.inputs.ContainerServiceNetworkProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterLoadBalancerProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterLoadBalancerProfileManagedOutboundIPsArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterSecurityProfileArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterSecurityProfileDefenderArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterSecurityProfileDefenderSecurityMonitoringArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterSecurityProfileWorkloadIdentityArgs;
import com.pulumi.azurenative.containerservice.inputs.ManagedClusterSKUArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var managedCluster = new ManagedCluster("managedCluster", ManagedClusterArgs.builder()
            .agentPoolProfiles(ManagedClusterAgentPoolProfileArgs.builder()
                .count(3)
                .enableNodePublicIP(true)
                .mode("System")
                .name("nodepool1")
                .osType("Linux")
                .type("VirtualMachineScaleSets")
                .vmSize("Standard_DS2_v2")
                .build())
            .dnsPrefix("dnsprefix1")
            .kubernetesVersion("")
            .linuxProfile(ContainerServiceLinuxProfileArgs.builder()
                .adminUsername("azureuser")
                .ssh(ContainerServiceSshConfigurationArgs.builder()
                    .publicKeys(ContainerServiceSshPublicKeyArgs.builder()
                        .keyData("keydata")
                        .build())
                    .build())
                .build())
            .location("location1")
            .networkProfile(ContainerServiceNetworkProfileArgs.builder()
                .loadBalancerProfile(ManagedClusterLoadBalancerProfileArgs.builder()
                    .managedOutboundIPs(ManagedClusterLoadBalancerProfileManagedOutboundIPsArgs.builder()
                        .count(2)
                        .build())
                    .build())
                .loadBalancerSku("standard")
                .outboundType("loadBalancer")
                .build())
            .resourceGroupName("rg1")
            .resourceName("clustername1")
            .securityProfile(ManagedClusterSecurityProfileArgs.builder()
                .defender(ManagedClusterSecurityProfileDefenderArgs.builder()
                    .logAnalyticsWorkspaceResourceId("/subscriptions/SUB_ID/resourcegroups/RG_NAME/providers/microsoft.operationalinsights/workspaces/WORKSPACE_NAME")
                    .securityMonitoring(ManagedClusterSecurityProfileDefenderSecurityMonitoringArgs.builder()
                        .enabled(true)
                        .build())
                    .build())
                .workloadIdentity(ManagedClusterSecurityProfileWorkloadIdentityArgs.builder()
                    .enabled(true)
                    .build())
                .build())
            .sku(ManagedClusterSKUArgs.builder()
                .name("Basic")
                .tier("Free")
                .build())
            .tags(Map.ofEntries(
                Map.entry("archv2", ""),
                Map.entry("tier", "production")
            ))
            .build());

    }
}
resources:
  managedCluster:
    type: azure-native:containerservice:ManagedCluster
    properties:
      agentPoolProfiles:
        - count: 3
          enableNodePublicIP: true
          mode: System
          name: nodepool1
          osType: Linux
          type: VirtualMachineScaleSets
          vmSize: Standard_DS2_v2
      dnsPrefix: dnsprefix1
      kubernetesVersion: ""
      linuxProfile:
        adminUsername: azureuser
        ssh:
          publicKeys:
            - keyData: keydata
      location: location1
      networkProfile:
        loadBalancerProfile:
          managedOutboundIPs:
            count: 2
        loadBalancerSku: standard
        outboundType: loadBalancer
      resourceGroupName: rg1
      resourceName: clustername1
      securityProfile:
        defender:
          logAnalyticsWorkspaceResourceId: /subscriptions/SUB_ID/resourcegroups/RG_NAME/providers/microsoft.operationalinsights/workspaces/WORKSPACE_NAME
          securityMonitoring:
            enabled: true
        workloadIdentity:
          enabled: true
      sku:
        name: Basic
        tier: Free
      tags:
        archv2: ""
        tier: production

The securityProfile.defender configuration enables Microsoft Defender for Containers, sending security telemetry to the specified Log Analytics workspace. The workloadIdentity.enabled property allows pods to authenticate to Azure services using Azure AD identities without managing credentials in code.

Beyond these examples

These snippets focus on specific cluster-level features: network egress (HTTP proxy, NAT gateway, load balancer), security and identity (Azure RBAC, Defender, workload identity, custom CAs), and service mesh (Istio with Key Vault integration). They’re intentionally minimal rather than full cluster deployments.

The examples may reference pre-existing infrastructure such as Azure resource group and location, service principal credentials or managed identity, SSH public keys for Linux node access, Log Analytics workspace (for Defender), Key Vault with certificates (for service mesh), and HTTP proxy servers (for proxy configuration). They focus on configuring the cluster rather than provisioning everything around it.

To keep things focused, common cluster patterns are omitted, including:

  • Node pool configuration (VM sizes, scaling, availability zones)
  • Network plugin selection (kubenet vs Azure CNI)
  • Storage and disk encryption settings
  • Windows node pool configuration
  • Addon configuration (monitoring, policy, ingress)
  • Private cluster and API server access controls

These omissions are intentional: the goal is to illustrate how each cluster feature is wired, not provide drop-in production clusters. See the ManagedCluster resource reference for all available configuration options.

Let's deploy Azure Kubernetes Service Clusters

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Agent Pool & Node Configuration
Why can't I update my cluster's agent pool configuration after creation?
The agentPoolProfiles property cannot be updated directly via the Azure API after cluster creation. To add agent pools, use the separate AgentPool resource. To modify the initial agent pool, either use the replaceOnChanges resource option to recreate the cluster, or make changes in Azure Portal then run pulumi refresh.
What's the minimum agent pool configuration required?
You must define at least one agent pool inline via agentPoolProfiles when creating a cluster. Each pool requires count, vmSize, mode, name, osType, and type properties.
Cluster Upgrades & Versioning
How does Kubernetes version upgrading work?
You can specify either <major.minor.patch> (e.g., 1.20.13) or <major.minor> (e.g., 1.20). When using <major.minor>, the latest GA patch is chosen automatically. Upgrades must be sequential by major version; you cannot skip minor versions (e.g., 1.14.x to 1.16.x is not allowed).
What's the default support plan for AKS clusters?
The default support plan is KubernetesOfficial if supportPlan is not specified.
Networking & Access
How do I create a private AKS cluster?
Set apiServerAccessProfile.enablePrivateCluster to true. You can optionally enable enablePrivateClusterPublicFQDN for public FQDN access, or specify a custom privateDNSZone for DNS configuration.
What cluster properties are immutable after creation?
The following properties cannot be changed after cluster creation: networkProfile, linuxProfile, windowsProfile, dnsPrefix, fqdnSubdomain, nodeResourceGroup, and diskEncryptionSetID. Changes to these require cluster recreation.
Authentication & Security
How do I enable Azure RBAC for Kubernetes authorization?
Set aadProfile.enableAzureRBAC to true and aadProfile.managed to true. This enables Azure Active Directory integration with Azure RBAC for Kubernetes authorization.
Can I disable local accounts on my cluster?
Yes, set disableLocalAccounts to true. This disables static credential access and must only be used on AAD-enabled clusters.
Cluster Autoscaling
How do I configure cluster autoscaling?
Use the autoScalerProfile property with settings like scaleDownDelayAfterAdd (e.g., “15m”) and scanInterval (e.g., “20s”) to control autoscaler behavior.

Commonly used with AKS cluster

Using a different cloud?

Explore containers guides for other cloud providers: