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

Configuration & Setup
What are the required properties for creating a connected cluster?
You must provide agentPublicKeyCertificate (Base64 encoded public certificate for agent handshake), identity (cluster identity configuration), and location (geo-location where the resource lives).
What properties can't be changed after creating a connected cluster?
The location, clusterName, and resourceGroupName properties are immutable and cannot be modified after cluster creation.
What type of managed identity should I use for my connected cluster?
The examples demonstrate using SystemAssigned as the identity type for connected clusters.
Security & Connectivity
How do I enable private link connectivity for my connected cluster?
Set privateLinkState to Enabled and provide a privateLinkScopeResourceId pointing to your Azure private link scope resource.
How do I enable Azure RBAC for my connected cluster?
Configure the aadProfile with enableAzureRBAC set to true, along with tenantID and adminGroupObjectIDs for the admin groups.
Agent Management
How do I enable automatic agent upgrades?
Set arcAgentProfile.agentAutoUpgrade to Enabled. You can optionally specify a desiredAgentVersion and configure systemComponents with specific versions.
API Versions
How can I use a different Azure API version for this resource?
Generate a local SDK package using the Pulumi CLI command pulumi package add azure-native kubernetes [ApiVersion]. The resource supports multiple API versions including 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: