Connect Azure Kubernetes Clusters

The azure-native:kubernetes:ConnectedCluster resource, part of the Pulumi Azure Native provider, registers external Kubernetes clusters with Azure Arc, establishing the management connection and identity for Azure Resource Manager operations. This guide focuses on three capabilities: basic cluster registration, Private Link network isolation, and Azure AD authentication with agent auto-upgrade.

Connected clusters represent Kubernetes clusters running outside Azure (on-premises, other clouds, or edge). The resource establishes the Arc connection after you install Arc agents on the cluster. The examples are intentionally small. Combine them with your own cluster infrastructure, networking, and access policies.

Register a Kubernetes cluster with Azure Arc

Teams running Kubernetes outside Azure register clusters with Arc to enable centralized management and policy enforcement through Azure Resource Manager.

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

const connectedCluster = new azure_native.kubernetes.ConnectedCluster("connectedCluster", {
    agentPublicKeyCertificate: "MIICYzCCAcygAwIBAgIBADANBgkqhkiG9w0BAQUFADAuMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMREwDwYDVQQLEwhMb2NhbCBDQTAeFw05OTEyMjIwNTAwMDBaFw0wMDEyMjMwNDU5NTlaMC4xCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNJQk0xETAPBgNVBAsTCExvY2FsIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD2bZEo7xGaX2/0GHkrNFZvlxBou9v1Jmt/PDiTMPve8r9FeJAQ0QdvFST/0JPQYD20rH0bimdDLgNdNynmyRoS2S/IInfpmf69iyc2G0TPyRvmHIiOZbdCd+YBHQi1adkj17NDcWj6S14tVurFX73zx0sNoMS79q3tuXKrDsxeuwIDAQABo4GQMIGNMEsGCVUdDwGG+EIBDQQ+EzxHZW5lcmF0ZWQgYnkgdGhlIFNlY3VyZVdheSBTZWN1cml0eSBTZXJ2ZXIgZm9yIE9TLzM5MCAoUkFDRikwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ3+ocRyCTJw067dLSwr/nalx6YMMA0GCSqGSIb3DQEBBQUAA4GBAMaQzt+zaj1GU77yzlr8iiMBXgdQrwsZZWJo5exnAucJAEYQZmOfyLiM D6oYq+ZnfvM0n8G/Y79q8nhwvuxpYOnRSAXFp6xSkrIOeZtJMY1h00LKp/JX3Ng1svZ2agE126JHsQ0bhzN5TKsYfbwfTwfjdWAGy6Vf1nYi/rO+ryMO",
    azureHybridBenefit: azure_native.kubernetes.AzureHybridBenefit.NotApplicable,
    clusterName: "testCluster",
    distribution: "AKS",
    distributionVersion: "1.0",
    identity: {
        type: azure_native.kubernetes.ResourceIdentityType.SystemAssigned,
    },
    location: "East US",
    resourceGroupName: "k8sc-rg",
    tags: {},
});
import pulumi
import pulumi_azure_native as azure_native

connected_cluster = azure_native.kubernetes.ConnectedCluster("connectedCluster",
    agent_public_key_certificate="MIICYzCCAcygAwIBAgIBADANBgkqhkiG9w0BAQUFADAuMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMREwDwYDVQQLEwhMb2NhbCBDQTAeFw05OTEyMjIwNTAwMDBaFw0wMDEyMjMwNDU5NTlaMC4xCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNJQk0xETAPBgNVBAsTCExvY2FsIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD2bZEo7xGaX2/0GHkrNFZvlxBou9v1Jmt/PDiTMPve8r9FeJAQ0QdvFST/0JPQYD20rH0bimdDLgNdNynmyRoS2S/IInfpmf69iyc2G0TPyRvmHIiOZbdCd+YBHQi1adkj17NDcWj6S14tVurFX73zx0sNoMS79q3tuXKrDsxeuwIDAQABo4GQMIGNMEsGCVUdDwGG+EIBDQQ+EzxHZW5lcmF0ZWQgYnkgdGhlIFNlY3VyZVdheSBTZWN1cml0eSBTZXJ2ZXIgZm9yIE9TLzM5MCAoUkFDRikwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ3+ocRyCTJw067dLSwr/nalx6YMMA0GCSqGSIb3DQEBBQUAA4GBAMaQzt+zaj1GU77yzlr8iiMBXgdQrwsZZWJo5exnAucJAEYQZmOfyLiM D6oYq+ZnfvM0n8G/Y79q8nhwvuxpYOnRSAXFp6xSkrIOeZtJMY1h00LKp/JX3Ng1svZ2agE126JHsQ0bhzN5TKsYfbwfTwfjdWAGy6Vf1nYi/rO+ryMO",
    azure_hybrid_benefit=azure_native.kubernetes.AzureHybridBenefit.NOT_APPLICABLE,
    cluster_name="testCluster",
    distribution="AKS",
    distribution_version="1.0",
    identity={
        "type": azure_native.kubernetes.ResourceIdentityType.SYSTEM_ASSIGNED,
    },
    location="East US",
    resource_group_name="k8sc-rg",
    tags={})
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := kubernetes.NewConnectedCluster(ctx, "connectedCluster", &kubernetes.ConnectedClusterArgs{
			AgentPublicKeyCertificate: pulumi.String("MIICYzCCAcygAwIBAgIBADANBgkqhkiG9w0BAQUFADAuMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMREwDwYDVQQLEwhMb2NhbCBDQTAeFw05OTEyMjIwNTAwMDBaFw0wMDEyMjMwNDU5NTlaMC4xCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNJQk0xETAPBgNVBAsTCExvY2FsIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD2bZEo7xGaX2/0GHkrNFZvlxBou9v1Jmt/PDiTMPve8r9FeJAQ0QdvFST/0JPQYD20rH0bimdDLgNdNynmyRoS2S/IInfpmf69iyc2G0TPyRvmHIiOZbdCd+YBHQi1adkj17NDcWj6S14tVurFX73zx0sNoMS79q3tuXKrDsxeuwIDAQABo4GQMIGNMEsGCVUdDwGG+EIBDQQ+EzxHZW5lcmF0ZWQgYnkgdGhlIFNlY3VyZVdheSBTZWN1cml0eSBTZXJ2ZXIgZm9yIE9TLzM5MCAoUkFDRikwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ3+ocRyCTJw067dLSwr/nalx6YMMA0GCSqGSIb3DQEBBQUAA4GBAMaQzt+zaj1GU77yzlr8iiMBXgdQrwsZZWJo5exnAucJAEYQZmOfyLiM D6oYq+ZnfvM0n8G/Y79q8nhwvuxpYOnRSAXFp6xSkrIOeZtJMY1h00LKp/JX3Ng1svZ2agE126JHsQ0bhzN5TKsYfbwfTwfjdWAGy6Vf1nYi/rO+ryMO"),
			AzureHybridBenefit:        pulumi.String(kubernetes.AzureHybridBenefitNotApplicable),
			ClusterName:               pulumi.String("testCluster"),
			Distribution:              pulumi.String("AKS"),
			DistributionVersion:       pulumi.String("1.0"),
			Identity: &kubernetes.ConnectedClusterIdentityArgs{
				Type: kubernetes.ResourceIdentityTypeSystemAssigned,
			},
			Location:          pulumi.String("East US"),
			ResourceGroupName: pulumi.String("k8sc-rg"),
			Tags:              pulumi.StringMap{},
		})
		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 connectedCluster = new AzureNative.Kubernetes.ConnectedCluster("connectedCluster", new()
    {
        AgentPublicKeyCertificate = "MIICYzCCAcygAwIBAgIBADANBgkqhkiG9w0BAQUFADAuMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMREwDwYDVQQLEwhMb2NhbCBDQTAeFw05OTEyMjIwNTAwMDBaFw0wMDEyMjMwNDU5NTlaMC4xCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNJQk0xETAPBgNVBAsTCExvY2FsIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD2bZEo7xGaX2/0GHkrNFZvlxBou9v1Jmt/PDiTMPve8r9FeJAQ0QdvFST/0JPQYD20rH0bimdDLgNdNynmyRoS2S/IInfpmf69iyc2G0TPyRvmHIiOZbdCd+YBHQi1adkj17NDcWj6S14tVurFX73zx0sNoMS79q3tuXKrDsxeuwIDAQABo4GQMIGNMEsGCVUdDwGG+EIBDQQ+EzxHZW5lcmF0ZWQgYnkgdGhlIFNlY3VyZVdheSBTZWN1cml0eSBTZXJ2ZXIgZm9yIE9TLzM5MCAoUkFDRikwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ3+ocRyCTJw067dLSwr/nalx6YMMA0GCSqGSIb3DQEBBQUAA4GBAMaQzt+zaj1GU77yzlr8iiMBXgdQrwsZZWJo5exnAucJAEYQZmOfyLiM D6oYq+ZnfvM0n8G/Y79q8nhwvuxpYOnRSAXFp6xSkrIOeZtJMY1h00LKp/JX3Ng1svZ2agE126JHsQ0bhzN5TKsYfbwfTwfjdWAGy6Vf1nYi/rO+ryMO",
        AzureHybridBenefit = AzureNative.Kubernetes.AzureHybridBenefit.NotApplicable,
        ClusterName = "testCluster",
        Distribution = "AKS",
        DistributionVersion = "1.0",
        Identity = new AzureNative.Kubernetes.Inputs.ConnectedClusterIdentityArgs
        {
            Type = AzureNative.Kubernetes.ResourceIdentityType.SystemAssigned,
        },
        Location = "East US",
        ResourceGroupName = "k8sc-rg",
        Tags = null,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.kubernetes.ConnectedCluster;
import com.pulumi.azurenative.kubernetes.ConnectedClusterArgs;
import com.pulumi.azurenative.kubernetes.inputs.ConnectedClusterIdentityArgs;
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 connectedCluster = new ConnectedCluster("connectedCluster", ConnectedClusterArgs.builder()
            .agentPublicKeyCertificate("MIICYzCCAcygAwIBAgIBADANBgkqhkiG9w0BAQUFADAuMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMREwDwYDVQQLEwhMb2NhbCBDQTAeFw05OTEyMjIwNTAwMDBaFw0wMDEyMjMwNDU5NTlaMC4xCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNJQk0xETAPBgNVBAsTCExvY2FsIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD2bZEo7xGaX2/0GHkrNFZvlxBou9v1Jmt/PDiTMPve8r9FeJAQ0QdvFST/0JPQYD20rH0bimdDLgNdNynmyRoS2S/IInfpmf69iyc2G0TPyRvmHIiOZbdCd+YBHQi1adkj17NDcWj6S14tVurFX73zx0sNoMS79q3tuXKrDsxeuwIDAQABo4GQMIGNMEsGCVUdDwGG+EIBDQQ+EzxHZW5lcmF0ZWQgYnkgdGhlIFNlY3VyZVdheSBTZWN1cml0eSBTZXJ2ZXIgZm9yIE9TLzM5MCAoUkFDRikwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ3+ocRyCTJw067dLSwr/nalx6YMMA0GCSqGSIb3DQEBBQUAA4GBAMaQzt+zaj1GU77yzlr8iiMBXgdQrwsZZWJo5exnAucJAEYQZmOfyLiM D6oYq+ZnfvM0n8G/Y79q8nhwvuxpYOnRSAXFp6xSkrIOeZtJMY1h00LKp/JX3Ng1svZ2agE126JHsQ0bhzN5TKsYfbwfTwfjdWAGy6Vf1nYi/rO+ryMO")
            .azureHybridBenefit("NotApplicable")
            .clusterName("testCluster")
            .distribution("AKS")
            .distributionVersion("1.0")
            .identity(ConnectedClusterIdentityArgs.builder()
                .type("SystemAssigned")
                .build())
            .location("East US")
            .resourceGroupName("k8sc-rg")
            .tags(Map.ofEntries(
            ))
            .build());

    }
}
resources:
  connectedCluster:
    type: azure-native:kubernetes:ConnectedCluster
    properties:
      agentPublicKeyCertificate: MIICYzCCAcygAwIBAgIBADANBgkqhkiG9w0BAQUFADAuMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMREwDwYDVQQLEwhMb2NhbCBDQTAeFw05OTEyMjIwNTAwMDBaFw0wMDEyMjMwNDU5NTlaMC4xCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNJQk0xETAPBgNVBAsTCExvY2FsIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD2bZEo7xGaX2/0GHkrNFZvlxBou9v1Jmt/PDiTMPve8r9FeJAQ0QdvFST/0JPQYD20rH0bimdDLgNdNynmyRoS2S/IInfpmf69iyc2G0TPyRvmHIiOZbdCd+YBHQi1adkj17NDcWj6S14tVurFX73zx0sNoMS79q3tuXKrDsxeuwIDAQABo4GQMIGNMEsGCVUdDwGG+EIBDQQ+EzxHZW5lcmF0ZWQgYnkgdGhlIFNlY3VyZVdheSBTZWN1cml0eSBTZXJ2ZXIgZm9yIE9TLzM5MCAoUkFDRikwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ3+ocRyCTJw067dLSwr/nalx6YMMA0GCSqGSIb3DQEBBQUAA4GBAMaQzt+zaj1GU77yzlr8iiMBXgdQrwsZZWJo5exnAucJAEYQZmOfyLiM D6oYq+ZnfvM0n8G/Y79q8nhwvuxpYOnRSAXFp6xSkrIOeZtJMY1h00LKp/JX3Ng1svZ2agE126JHsQ0bhzN5TKsYfbwfTwfjdWAGy6Vf1nYi/rO+ryMO
      azureHybridBenefit: NotApplicable
      clusterName: testCluster
      distribution: AKS
      distributionVersion: '1.0'
      identity:
        type: SystemAssigned
      location: East US
      resourceGroupName: k8sc-rg
      tags: {}

The agentPublicKeyCertificate contains the base64-encoded certificate generated when you install Arc agents on your cluster. The identity property creates a system-assigned managed identity that Arc agents use to authenticate with Azure services. The distribution and distributionVersion properties document what Kubernetes variant you’re running.

Organizations with strict network security requirements route Arc agent traffic through Private Link to avoid public internet exposure.

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

const connectedCluster = new azure_native.kubernetes.ConnectedCluster("connectedCluster", {
    agentPublicKeyCertificate: "MIICYzCCAcygAwIBAgIBADANBgkqhkiG9w0BAQUFADAuMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMREwDwYDVQQLEwhMb2NhbCBDQTAeFw05OTEyMjIwNTAwMDBaFw0wMDEyMjMwNDU5NTlaMC4xCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNJQk0xETAPBgNVBAsTCExvY2FsIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD2bZEo7xGaX2/0GHkrNFZvlxBou9v1Jmt/PDiTMPve8r9FeJAQ0QdvFST/0JPQYD20rH0bimdDLgNdNynmyRoS2S/IInfpmf69iyc2G0TPyRvmHIiOZbdCd+YBHQi1adkj17NDcWj6S14tVurFX73zx0sNoMS79q3tuXKrDsxeuwIDAQABo4GQMIGNMEsGCVUdDwGG+EIBDQQ+EzxHZW5lcmF0ZWQgYnkgdGhlIFNlY3VyZVdheSBTZWN1cml0eSBTZXJ2ZXIgZm9yIE9TLzM5MCAoUkFDRikwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ3+ocRyCTJw067dLSwr/nalx6YMMA0GCSqGSIb3DQEBBQUAA4GBAMaQzt+zaj1GU77yzlr8iiMBXgdQrwsZZWJo5exnAucJAEYQZmOfyLiM D6oYq+ZnfvM0n8G/Y79q8nhwvuxpYOnRSAXFp6xSkrIOeZtJMY1h00LKp/JX3Ng1svZ2agE126JHsQ0bhzN5TKsYfbwfTwfjdWAGy6Vf1nYi/rO+ryMO",
    azureHybridBenefit: azure_native.kubernetes.AzureHybridBenefit.NotApplicable,
    clusterName: "testCluster",
    distribution: "AKS",
    distributionVersion: "1.0",
    identity: {
        type: azure_native.kubernetes.ResourceIdentityType.SystemAssigned,
    },
    location: "East US",
    privateLinkScopeResourceId: "/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.HybridCompute/privateLinkScopes/privateLinkScopeName",
    privateLinkState: azure_native.kubernetes.PrivateLinkState.Enabled,
    resourceGroupName: "k8sc-rg",
    tags: {},
});
import pulumi
import pulumi_azure_native as azure_native

connected_cluster = azure_native.kubernetes.ConnectedCluster("connectedCluster",
    agent_public_key_certificate="MIICYzCCAcygAwIBAgIBADANBgkqhkiG9w0BAQUFADAuMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMREwDwYDVQQLEwhMb2NhbCBDQTAeFw05OTEyMjIwNTAwMDBaFw0wMDEyMjMwNDU5NTlaMC4xCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNJQk0xETAPBgNVBAsTCExvY2FsIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD2bZEo7xGaX2/0GHkrNFZvlxBou9v1Jmt/PDiTMPve8r9FeJAQ0QdvFST/0JPQYD20rH0bimdDLgNdNynmyRoS2S/IInfpmf69iyc2G0TPyRvmHIiOZbdCd+YBHQi1adkj17NDcWj6S14tVurFX73zx0sNoMS79q3tuXKrDsxeuwIDAQABo4GQMIGNMEsGCVUdDwGG+EIBDQQ+EzxHZW5lcmF0ZWQgYnkgdGhlIFNlY3VyZVdheSBTZWN1cml0eSBTZXJ2ZXIgZm9yIE9TLzM5MCAoUkFDRikwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ3+ocRyCTJw067dLSwr/nalx6YMMA0GCSqGSIb3DQEBBQUAA4GBAMaQzt+zaj1GU77yzlr8iiMBXgdQrwsZZWJo5exnAucJAEYQZmOfyLiM D6oYq+ZnfvM0n8G/Y79q8nhwvuxpYOnRSAXFp6xSkrIOeZtJMY1h00LKp/JX3Ng1svZ2agE126JHsQ0bhzN5TKsYfbwfTwfjdWAGy6Vf1nYi/rO+ryMO",
    azure_hybrid_benefit=azure_native.kubernetes.AzureHybridBenefit.NOT_APPLICABLE,
    cluster_name="testCluster",
    distribution="AKS",
    distribution_version="1.0",
    identity={
        "type": azure_native.kubernetes.ResourceIdentityType.SYSTEM_ASSIGNED,
    },
    location="East US",
    private_link_scope_resource_id="/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.HybridCompute/privateLinkScopes/privateLinkScopeName",
    private_link_state=azure_native.kubernetes.PrivateLinkState.ENABLED,
    resource_group_name="k8sc-rg",
    tags={})
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := kubernetes.NewConnectedCluster(ctx, "connectedCluster", &kubernetes.ConnectedClusterArgs{
			AgentPublicKeyCertificate: pulumi.String("MIICYzCCAcygAwIBAgIBADANBgkqhkiG9w0BAQUFADAuMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMREwDwYDVQQLEwhMb2NhbCBDQTAeFw05OTEyMjIwNTAwMDBaFw0wMDEyMjMwNDU5NTlaMC4xCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNJQk0xETAPBgNVBAsTCExvY2FsIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD2bZEo7xGaX2/0GHkrNFZvlxBou9v1Jmt/PDiTMPve8r9FeJAQ0QdvFST/0JPQYD20rH0bimdDLgNdNynmyRoS2S/IInfpmf69iyc2G0TPyRvmHIiOZbdCd+YBHQi1adkj17NDcWj6S14tVurFX73zx0sNoMS79q3tuXKrDsxeuwIDAQABo4GQMIGNMEsGCVUdDwGG+EIBDQQ+EzxHZW5lcmF0ZWQgYnkgdGhlIFNlY3VyZVdheSBTZWN1cml0eSBTZXJ2ZXIgZm9yIE9TLzM5MCAoUkFDRikwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ3+ocRyCTJw067dLSwr/nalx6YMMA0GCSqGSIb3DQEBBQUAA4GBAMaQzt+zaj1GU77yzlr8iiMBXgdQrwsZZWJo5exnAucJAEYQZmOfyLiM D6oYq+ZnfvM0n8G/Y79q8nhwvuxpYOnRSAXFp6xSkrIOeZtJMY1h00LKp/JX3Ng1svZ2agE126JHsQ0bhzN5TKsYfbwfTwfjdWAGy6Vf1nYi/rO+ryMO"),
			AzureHybridBenefit:        pulumi.String(kubernetes.AzureHybridBenefitNotApplicable),
			ClusterName:               pulumi.String("testCluster"),
			Distribution:              pulumi.String("AKS"),
			DistributionVersion:       pulumi.String("1.0"),
			Identity: &kubernetes.ConnectedClusterIdentityArgs{
				Type: kubernetes.ResourceIdentityTypeSystemAssigned,
			},
			Location:                   pulumi.String("East US"),
			PrivateLinkScopeResourceId: pulumi.String("/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.HybridCompute/privateLinkScopes/privateLinkScopeName"),
			PrivateLinkState:           pulumi.String(kubernetes.PrivateLinkStateEnabled),
			ResourceGroupName:          pulumi.String("k8sc-rg"),
			Tags:                       pulumi.StringMap{},
		})
		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 connectedCluster = new AzureNative.Kubernetes.ConnectedCluster("connectedCluster", new()
    {
        AgentPublicKeyCertificate = "MIICYzCCAcygAwIBAgIBADANBgkqhkiG9w0BAQUFADAuMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMREwDwYDVQQLEwhMb2NhbCBDQTAeFw05OTEyMjIwNTAwMDBaFw0wMDEyMjMwNDU5NTlaMC4xCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNJQk0xETAPBgNVBAsTCExvY2FsIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD2bZEo7xGaX2/0GHkrNFZvlxBou9v1Jmt/PDiTMPve8r9FeJAQ0QdvFST/0JPQYD20rH0bimdDLgNdNynmyRoS2S/IInfpmf69iyc2G0TPyRvmHIiOZbdCd+YBHQi1adkj17NDcWj6S14tVurFX73zx0sNoMS79q3tuXKrDsxeuwIDAQABo4GQMIGNMEsGCVUdDwGG+EIBDQQ+EzxHZW5lcmF0ZWQgYnkgdGhlIFNlY3VyZVdheSBTZWN1cml0eSBTZXJ2ZXIgZm9yIE9TLzM5MCAoUkFDRikwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ3+ocRyCTJw067dLSwr/nalx6YMMA0GCSqGSIb3DQEBBQUAA4GBAMaQzt+zaj1GU77yzlr8iiMBXgdQrwsZZWJo5exnAucJAEYQZmOfyLiM D6oYq+ZnfvM0n8G/Y79q8nhwvuxpYOnRSAXFp6xSkrIOeZtJMY1h00LKp/JX3Ng1svZ2agE126JHsQ0bhzN5TKsYfbwfTwfjdWAGy6Vf1nYi/rO+ryMO",
        AzureHybridBenefit = AzureNative.Kubernetes.AzureHybridBenefit.NotApplicable,
        ClusterName = "testCluster",
        Distribution = "AKS",
        DistributionVersion = "1.0",
        Identity = new AzureNative.Kubernetes.Inputs.ConnectedClusterIdentityArgs
        {
            Type = AzureNative.Kubernetes.ResourceIdentityType.SystemAssigned,
        },
        Location = "East US",
        PrivateLinkScopeResourceId = "/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.HybridCompute/privateLinkScopes/privateLinkScopeName",
        PrivateLinkState = AzureNative.Kubernetes.PrivateLinkState.Enabled,
        ResourceGroupName = "k8sc-rg",
        Tags = null,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.kubernetes.ConnectedCluster;
import com.pulumi.azurenative.kubernetes.ConnectedClusterArgs;
import com.pulumi.azurenative.kubernetes.inputs.ConnectedClusterIdentityArgs;
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 connectedCluster = new ConnectedCluster("connectedCluster", ConnectedClusterArgs.builder()
            .agentPublicKeyCertificate("MIICYzCCAcygAwIBAgIBADANBgkqhkiG9w0BAQUFADAuMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMREwDwYDVQQLEwhMb2NhbCBDQTAeFw05OTEyMjIwNTAwMDBaFw0wMDEyMjMwNDU5NTlaMC4xCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNJQk0xETAPBgNVBAsTCExvY2FsIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD2bZEo7xGaX2/0GHkrNFZvlxBou9v1Jmt/PDiTMPve8r9FeJAQ0QdvFST/0JPQYD20rH0bimdDLgNdNynmyRoS2S/IInfpmf69iyc2G0TPyRvmHIiOZbdCd+YBHQi1adkj17NDcWj6S14tVurFX73zx0sNoMS79q3tuXKrDsxeuwIDAQABo4GQMIGNMEsGCVUdDwGG+EIBDQQ+EzxHZW5lcmF0ZWQgYnkgdGhlIFNlY3VyZVdheSBTZWN1cml0eSBTZXJ2ZXIgZm9yIE9TLzM5MCAoUkFDRikwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ3+ocRyCTJw067dLSwr/nalx6YMMA0GCSqGSIb3DQEBBQUAA4GBAMaQzt+zaj1GU77yzlr8iiMBXgdQrwsZZWJo5exnAucJAEYQZmOfyLiM D6oYq+ZnfvM0n8G/Y79q8nhwvuxpYOnRSAXFp6xSkrIOeZtJMY1h00LKp/JX3Ng1svZ2agE126JHsQ0bhzN5TKsYfbwfTwfjdWAGy6Vf1nYi/rO+ryMO")
            .azureHybridBenefit("NotApplicable")
            .clusterName("testCluster")
            .distribution("AKS")
            .distributionVersion("1.0")
            .identity(ConnectedClusterIdentityArgs.builder()
                .type("SystemAssigned")
                .build())
            .location("East US")
            .privateLinkScopeResourceId("/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.HybridCompute/privateLinkScopes/privateLinkScopeName")
            .privateLinkState("Enabled")
            .resourceGroupName("k8sc-rg")
            .tags(Map.ofEntries(
            ))
            .build());

    }
}
resources:
  connectedCluster:
    type: azure-native:kubernetes:ConnectedCluster
    properties:
      agentPublicKeyCertificate: MIICYzCCAcygAwIBAgIBADANBgkqhkiG9w0BAQUFADAuMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMREwDwYDVQQLEwhMb2NhbCBDQTAeFw05OTEyMjIwNTAwMDBaFw0wMDEyMjMwNDU5NTlaMC4xCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNJQk0xETAPBgNVBAsTCExvY2FsIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD2bZEo7xGaX2/0GHkrNFZvlxBou9v1Jmt/PDiTMPve8r9FeJAQ0QdvFST/0JPQYD20rH0bimdDLgNdNynmyRoS2S/IInfpmf69iyc2G0TPyRvmHIiOZbdCd+YBHQi1adkj17NDcWj6S14tVurFX73zx0sNoMS79q3tuXKrDsxeuwIDAQABo4GQMIGNMEsGCVUdDwGG+EIBDQQ+EzxHZW5lcmF0ZWQgYnkgdGhlIFNlY3VyZVdheSBTZWN1cml0eSBTZXJ2ZXIgZm9yIE9TLzM5MCAoUkFDRikwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ3+ocRyCTJw067dLSwr/nalx6YMMA0GCSqGSIb3DQEBBQUAA4GBAMaQzt+zaj1GU77yzlr8iiMBXgdQrwsZZWJo5exnAucJAEYQZmOfyLiM D6oYq+ZnfvM0n8G/Y79q8nhwvuxpYOnRSAXFp6xSkrIOeZtJMY1h00LKp/JX3Ng1svZ2agE126JHsQ0bhzN5TKsYfbwfTwfjdWAGy6Vf1nYi/rO+ryMO
      azureHybridBenefit: NotApplicable
      clusterName: testCluster
      distribution: AKS
      distributionVersion: '1.0'
      identity:
        type: SystemAssigned
      location: East US
      privateLinkScopeResourceId: /subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.HybridCompute/privateLinkScopes/privateLinkScopeName
      privateLinkState: Enabled
      resourceGroupName: k8sc-rg
      tags: {}

The privateLinkScopeResourceId references an existing Azure Private Link Scope resource. When privateLinkState is set to Enabled, Arc agents communicate with Azure services through private endpoints in your virtual network rather than public endpoints.

Configure Azure RBAC and agent auto-upgrade

Provisioned clusters benefit from Azure Active Directory integration for access control and automated agent version management.

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

const connectedCluster = new azure_native.kubernetes.ConnectedCluster("connectedCluster", {
    aadProfile: {
        adminGroupObjectIDs: ["56f988bf-86f1-41af-91ab-2d7cd011db47"],
        enableAzureRBAC: true,
        tenantID: "82f988bf-86f1-41af-91ab-2d7cd011db47",
    },
    agentPublicKeyCertificate: "",
    arcAgentProfile: {
        agentAutoUpgrade: azure_native.kubernetes.AutoUpgradeOptions.Enabled,
        desiredAgentVersion: "0.1.0",
        systemComponents: [{
            majorVersion: 0,
            type: "Strato",
            userSpecifiedVersion: "0.1.1",
        }],
    },
    azureHybridBenefit: azure_native.kubernetes.AzureHybridBenefit.NotApplicable,
    clusterName: "testCluster",
    distribution: "AKS",
    distributionVersion: "1.0",
    identity: {
        type: azure_native.kubernetes.ResourceIdentityType.SystemAssigned,
    },
    kind: azure_native.kubernetes.ConnectedClusterKind.ProvisionedCluster,
    location: "East US",
    resourceGroupName: "k8sc-rg",
    tags: {},
});
import pulumi
import pulumi_azure_native as azure_native

connected_cluster = azure_native.kubernetes.ConnectedCluster("connectedCluster",
    aad_profile={
        "admin_group_object_ids": ["56f988bf-86f1-41af-91ab-2d7cd011db47"],
        "enable_azure_rbac": True,
        "tenant_id": "82f988bf-86f1-41af-91ab-2d7cd011db47",
    },
    agent_public_key_certificate="",
    arc_agent_profile={
        "agent_auto_upgrade": azure_native.kubernetes.AutoUpgradeOptions.ENABLED,
        "desired_agent_version": "0.1.0",
        "system_components": [{
            "major_version": 0,
            "type": "Strato",
            "user_specified_version": "0.1.1",
        }],
    },
    azure_hybrid_benefit=azure_native.kubernetes.AzureHybridBenefit.NOT_APPLICABLE,
    cluster_name="testCluster",
    distribution="AKS",
    distribution_version="1.0",
    identity={
        "type": azure_native.kubernetes.ResourceIdentityType.SYSTEM_ASSIGNED,
    },
    kind=azure_native.kubernetes.ConnectedClusterKind.PROVISIONED_CLUSTER,
    location="East US",
    resource_group_name="k8sc-rg",
    tags={})
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := kubernetes.NewConnectedCluster(ctx, "connectedCluster", &kubernetes.ConnectedClusterArgs{
			AadProfile: &kubernetes.AadProfileArgs{
				AdminGroupObjectIDs: pulumi.StringArray{
					pulumi.String("56f988bf-86f1-41af-91ab-2d7cd011db47"),
				},
				EnableAzureRBAC: pulumi.Bool(true),
				TenantID:        pulumi.String("82f988bf-86f1-41af-91ab-2d7cd011db47"),
			},
			AgentPublicKeyCertificate: pulumi.String(""),
			ArcAgentProfile: &kubernetes.ArcAgentProfileArgs{
				AgentAutoUpgrade:    pulumi.String(kubernetes.AutoUpgradeOptionsEnabled),
				DesiredAgentVersion: pulumi.String("0.1.0"),
				SystemComponents: kubernetes.SystemComponentArray{
					&kubernetes.SystemComponentArgs{
						MajorVersion:         pulumi.Int(0),
						Type:                 pulumi.String("Strato"),
						UserSpecifiedVersion: pulumi.String("0.1.1"),
					},
				},
			},
			AzureHybridBenefit:  pulumi.String(kubernetes.AzureHybridBenefitNotApplicable),
			ClusterName:         pulumi.String("testCluster"),
			Distribution:        pulumi.String("AKS"),
			DistributionVersion: pulumi.String("1.0"),
			Identity: &kubernetes.ConnectedClusterIdentityArgs{
				Type: kubernetes.ResourceIdentityTypeSystemAssigned,
			},
			Kind:              pulumi.String(kubernetes.ConnectedClusterKindProvisionedCluster),
			Location:          pulumi.String("East US"),
			ResourceGroupName: pulumi.String("k8sc-rg"),
			Tags:              pulumi.StringMap{},
		})
		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 connectedCluster = new AzureNative.Kubernetes.ConnectedCluster("connectedCluster", new()
    {
        AadProfile = new AzureNative.Kubernetes.Inputs.AadProfileArgs
        {
            AdminGroupObjectIDs = new[]
            {
                "56f988bf-86f1-41af-91ab-2d7cd011db47",
            },
            EnableAzureRBAC = true,
            TenantID = "82f988bf-86f1-41af-91ab-2d7cd011db47",
        },
        AgentPublicKeyCertificate = "",
        ArcAgentProfile = new AzureNative.Kubernetes.Inputs.ArcAgentProfileArgs
        {
            AgentAutoUpgrade = AzureNative.Kubernetes.AutoUpgradeOptions.Enabled,
            DesiredAgentVersion = "0.1.0",
            SystemComponents = new[]
            {
                new AzureNative.Kubernetes.Inputs.SystemComponentArgs
                {
                    MajorVersion = 0,
                    Type = "Strato",
                    UserSpecifiedVersion = "0.1.1",
                },
            },
        },
        AzureHybridBenefit = AzureNative.Kubernetes.AzureHybridBenefit.NotApplicable,
        ClusterName = "testCluster",
        Distribution = "AKS",
        DistributionVersion = "1.0",
        Identity = new AzureNative.Kubernetes.Inputs.ConnectedClusterIdentityArgs
        {
            Type = AzureNative.Kubernetes.ResourceIdentityType.SystemAssigned,
        },
        Kind = AzureNative.Kubernetes.ConnectedClusterKind.ProvisionedCluster,
        Location = "East US",
        ResourceGroupName = "k8sc-rg",
        Tags = null,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.kubernetes.ConnectedCluster;
import com.pulumi.azurenative.kubernetes.ConnectedClusterArgs;
import com.pulumi.azurenative.kubernetes.inputs.AadProfileArgs;
import com.pulumi.azurenative.kubernetes.inputs.ArcAgentProfileArgs;
import com.pulumi.azurenative.kubernetes.inputs.ConnectedClusterIdentityArgs;
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 connectedCluster = new ConnectedCluster("connectedCluster", ConnectedClusterArgs.builder()
            .aadProfile(AadProfileArgs.builder()
                .adminGroupObjectIDs("56f988bf-86f1-41af-91ab-2d7cd011db47")
                .enableAzureRBAC(true)
                .tenantID("82f988bf-86f1-41af-91ab-2d7cd011db47")
                .build())
            .agentPublicKeyCertificate("")
            .arcAgentProfile(ArcAgentProfileArgs.builder()
                .agentAutoUpgrade("Enabled")
                .desiredAgentVersion("0.1.0")
                .systemComponents(SystemComponentArgs.builder()
                    .majorVersion(0)
                    .type("Strato")
                    .userSpecifiedVersion("0.1.1")
                    .build())
                .build())
            .azureHybridBenefit("NotApplicable")
            .clusterName("testCluster")
            .distribution("AKS")
            .distributionVersion("1.0")
            .identity(ConnectedClusterIdentityArgs.builder()
                .type("SystemAssigned")
                .build())
            .kind("ProvisionedCluster")
            .location("East US")
            .resourceGroupName("k8sc-rg")
            .tags(Map.ofEntries(
            ))
            .build());

    }
}
resources:
  connectedCluster:
    type: azure-native:kubernetes:ConnectedCluster
    properties:
      aadProfile:
        adminGroupObjectIDs:
          - 56f988bf-86f1-41af-91ab-2d7cd011db47
        enableAzureRBAC: true
        tenantID: 82f988bf-86f1-41af-91ab-2d7cd011db47
      agentPublicKeyCertificate: ""
      arcAgentProfile:
        agentAutoUpgrade: Enabled
        desiredAgentVersion: 0.1.0
        systemComponents:
          - majorVersion: 0
            type: Strato
            userSpecifiedVersion: 0.1.1
      azureHybridBenefit: NotApplicable
      clusterName: testCluster
      distribution: AKS
      distributionVersion: '1.0'
      identity:
        type: SystemAssigned
      kind: ProvisionedCluster
      location: East US
      resourceGroupName: k8sc-rg
      tags: {}

The aadProfile enables Azure AD authentication by specifying your tenant ID and admin group object IDs. When enableAzureRBAC is true, cluster access is controlled through Azure role assignments. The arcAgentProfile configures automatic agent updates: agentAutoUpgrade set to Enabled keeps Arc agents current, while desiredAgentVersion and systemComponents let you pin specific component versions when needed.

Beyond these examples

These snippets focus on specific connected cluster features: cluster registration and identity configuration, Private Link networking, and Azure AD integration and agent lifecycle management. They’re intentionally minimal rather than full cluster onboarding workflows.

The examples reference pre-existing infrastructure such as Kubernetes clusters running outside Azure, Azure resource groups, Private Link Scopes for network isolation, and Azure AD tenants and admin groups. They focus on establishing the Arc connection rather than provisioning the underlying cluster or installing agents.

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

  • Initial agent installation and certificate generation
  • Cluster onboarding prerequisites (kubectl access, permissions)
  • Azure Policy and GitOps configuration extensions
  • Monitoring and logging integration (Azure Monitor, Log Analytics)

These omissions are intentional: the goal is to illustrate how the Arc connection is configured, not provide complete cluster management solutions. See the ConnectedCluster resource reference for all available configuration options.

Let's connect Azure Kubernetes Clusters

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Cluster Configuration & Identity
What's required to create a connected cluster?
You must provide agentPublicKeyCertificate (Base64 encoded public certificate), identity (typically SystemAssigned), and location. The resourceGroupName and clusterName are also required for resource identification.
What properties can't be changed after creation?
The location, clusterName, and resourceGroupName properties are immutable and cannot be modified after the cluster is created.
What identity type should I use?
All examples use SystemAssigned identity type. Configure this in the identity property with type set to ResourceIdentityType.SystemAssigned.
Security & Access Control
How do I enable private link for my connected cluster?
Set privateLinkScopeResourceId to your private link scope resource ID and privateLinkState to Enabled. By default, private link is disabled.
How do I enable Azure RBAC for the cluster?
Configure aadProfile with enableAzureRBAC set to true, along with adminGroupObjectIDs (array of admin group IDs) and tenantID.
Agent Management
How do I enable automatic agent upgrades?
Set arcAgentProfile.agentAutoUpgrade to Enabled. You can optionally specify desiredAgentVersion and configure systemComponents for version control.
Resource Properties
What are the default values for optional properties?
azureHybridBenefit defaults to NotApplicable, and privateLinkState defaults to Disabled.
How can I use a different API version?
Generate a local SDK package using the CLI command pulumi package add azure-native kubernetes [ApiVersion]. Available versions include 2021-04-01-preview, 2021-10-01, 2022-05-01-preview, and many others.

Using a different cloud?

Explore containers guides for other cloud providers: