> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aviatrix.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Onboard AKS Clusters

> Step-by-step AKS onboarding for the Aviatrix Distributed Cloud Firewall. Three authentication paths: Azure Cloud Account with Entra ID (recommended), Azure Cloud Account with local accounts, and service-account kubeconfig.

Onboard a publicly accessible AKS cluster. For private AKS clusters, also see

<a href={"/docs/enterprise/" + "10.1" + "/guides/security/dcf/private-kubernetes-cluster-onboard"}>Onboarding Private Kubernetes Clusters</a>
.

## Before you start

Read

<a href={"/docs/enterprise/" + "10.1" + "/reference/dcf/kubernetes-prerequisites"}>Kubernetes Onboarding Prerequisites</a>
. Confirm DCF is enabled, Resource Discovery is on, the API server is reachable
from the Controller, and SNAT is disabled.

The Aviatrix cloud account for the Azure subscription hosting the cluster must
include the

<a href={"/docs/enterprise/" + "10.1" + "/reference/dcf/kubernetes-prerequisites#cloud-account-discovery-permissions"}>AKS discovery and onboarding permissions</a>
.

<Note>
  Starting in Controller 10.1, Path A supports Microsoft Entra ID authentication
  in addition to local accounts. See [Choose how the Controller
  authenticates](#choose-how-the-controller-authenticates) to pick the option
  that matches your cluster's configuration.
</Note>

## DCF policy requirements for cluster connectivity

When DCF is enabled, you are responsible for configuring DCF policies that allow
the AKS cluster to reach the outbound endpoints it needs for normal operation.
Without these policies, cluster components may fail to pull container images,
authenticate to Microsoft Entra ID, or reach Azure management endpoints.

For the full list of outbound destinations an AKS cluster requires, see
Microsoft's documentation on
[outbound network and FQDN rules for AKS clusters](https://learn.microsoft.com/azure/aks/outbound-rules-control-egress).
Use that list to plan SmartGroups and DCF rules that permit the required egress
while keeping the rest of your security posture intact.

## Choose how the Controller authenticates

Two paths, both supported equally:

* **Path A — Azure Cloud Account (recommended for managed AKS).** The Aviatrix
  service principal authenticates directly against the cluster. Path A has two
  authentication options:
  * **Entra ID (recommended).** The Controller requests a short-lived OAuth2
    token scoped to read-only Kubernetes RBAC. This is Microsoft's recommended
    posture for new AKS clusters and requires no local accounts or cluster-admin
    access.
  * **Local accounts.** The Aviatrix service principal calls
    `listClusterUserCredential` to obtain a kubeconfig. The returned kubeconfig
    contains a static client certificate mapped to the AKS local-account
    `masterclient` user, which has cluster-admin access.
* **Path B — Service-account kubeconfig.** A Kubernetes ServiceAccount in the
  cluster issues a bearer token; you assemble a kubeconfig and provide it to the
  Controller.

## Path A — Cloud Account

### Step 1: Confirm the service principal has the required permissions

See

<a href={"/docs/enterprise/" + "10.1" + "/reference/dcf/kubernetes-prerequisites#cloud-account-discovery-permissions"}>discovery permissions</a>
. The permissions required depend on which authentication option you choose in
Step 3 — Entra ID or local accounts.

### Step 2: Install the Aviatrix helm chart

Aviatrix recommends installing the helm chart on AKS clusters. Installing the
chart makes the Controller's RBAC explicit and auditable, prepares the cluster
for CRD-based DCF policy, and gives a uniform setup across providers. This is
required for Entra ID authentication and recommended for local accounts.

```bash theme={null}
helm repo add k8s-firewall https://aviatrixsystems.github.io/k8s-firewall-charts
helm repo update
helm install k8s-firewall k8s-firewall/k8s-firewall
```

<Note>
  If you plan to use Entra ID authentication, pass two additional values so
  the chart's `ClusterRoleBinding` targets the Azure service principal as a
  Kubernetes user:

  ```bash theme={null}
  helm install k8s-firewall k8s-firewall/k8s-firewall \
    --set role.subject.kind=User \
    --set role.subject.name=<SERVICE_PRINCIPAL_OBJECT_ID>
  ```

  * `role.subject.kind` must be `User` so the `ClusterRoleBinding` targets a
    Kubernetes user.
  * `role.subject.name` must be the object ID of the Azure service principal
    configured on the cloud account. Get it from the application ID with:

    ```bash theme={null}
    az ad sp show --id <CLOUD_ACCOUNT_APPLICATION_ID> | jq .id
    ```
</Note>

The chart installs the `avx-controller` ClusterRole and the Aviatrix CRDs needed
by

<a href={"/docs/enterprise/" + "10.1" + "/guides/security/dcf/dcf-kubernetes"}>Distributed Cloud Firewall for Kubernetes</a>
.

<Note>
  CRD-based policy is gated by the `k8s_dcf_policies` feature flag (default off;
  enabled by Aviatrix). AKS support for CRD-based policy is implemented in the
  Controller but does not have end-to-end test coverage as of 9.0 — flag any
  issues to support.
</Note>

### Step 3: Register the cluster

<Tabs>
  <Tab title="Terraform">
    ```hcl theme={null}
    data "azurerm_kubernetes_cluster" "this" {
      name                = "<CLUSTER_NAME>"
      resource_group_name = "<RESOURCE_GROUP>"
    }

    resource "aviatrix_kubernetes_cluster" "this" {
      cluster_id          = lower(data.azurerm_kubernetes_cluster.this.id)
      use_csp_credentials = true
    }
    ```

    <Warning>`cluster_id` must be lowercased — use `lower()`.</Warning>

    The Controller discovers the cluster's Entra ID configuration from Azure and
    automatically uses Entra ID authentication if the cluster has Entra ID
    configured, falling back to local accounts otherwise. `entra_id_authn` is a
    computed attribute for CSP-managed clusters such as AKS — it reflects what the
    Controller discovers from Azure and is not an input you set here. (The attribute
    is only settable as an input inside the `cluster_details` block when onboarding
    a custom, non-CSP-managed cluster.)

    When the Controller uses Entra ID, it requests a short-lived OAuth2 token scoped
    to read-only Kubernetes RBAC. Each token is valid for 60–90 minutes and
    refreshes automatically; the Controller does not persist long-lived credentials
    for the cluster.

    <Note>
      Local accounts require Kubernetes RBAC with local accounts enabled on the
      AKS cluster itself. These are properties on the cluster's
      `azurerm_kubernetes_cluster` resource, not on `aviatrix_kubernetes_cluster`:

      ```hcl theme={null}
      resource "azurerm_kubernetes_cluster" "aks_cluster" {
        local_account_disabled            = false
        role_based_access_control_enabled = true
      }
      ```

      The Aviatrix Controller cannot execute external auth binaries, so a cluster with
      Entra ID as its only authentication method cannot use local accounts — the
      kubeconfig returned by `listClusterUserCredential` for an Entra ID-only cluster
      relies on `exec` plugins and is rejected. Use
      [Path B — Service-account kubeconfig](#path-b--service-account-kubeconfig)
      instead.
    </Note>
  </Tab>

  <Tab title="CoPilot UI">
    1. Navigate to **Cloud Resources > Cloud Assets > Kubernetes Clusters**.
    2. Click **Onboard** next to the discovered AKS cluster.
    3. Select **Permissions on Cloud Account** to use the existing service
       principal.
    4. Click **Onboard**.

    The Controller automatically uses Entra ID authentication if the cluster has
    Entra ID configured, and falls back to local accounts otherwise.
  </Tab>
</Tabs>

## Path B — Service-account kubeconfig

The Controller authenticates to the cluster with a bearer token from a
Kubernetes ServiceAccount. The full canonical flow lives on

<a href={"/docs/enterprise/" + "10.1" + "/guides/security/dcf/kubernetes-onboard-custom"}>Onboard Self-Managed or Custom Clusters</a>
. AKS-specific notes follow.

### Step 1: Create the ServiceAccount and ClusterRoleBinding

Apply the

<a href={"/docs/enterprise/" + "10.1" + "/guides/security/dcf/kubernetes-onboard-custom#step-1-create-a-service-account-and-clusterrolebinding"}>Step 1 manifest</a>
and extract the token.

### Step 2: Get the cluster's CA cert and API endpoint

```bash theme={null}
az aks get-credentials \
  --name <CLUSTER_NAME> \
  --resource-group <RESOURCE_GROUP> \
  --file - | awk '/certificate-authority-data/ { print $2 }'

az aks get-credentials \
  --name <CLUSTER_NAME> \
  --resource-group <RESOURCE_GROUP> \
  --file - | awk '/server/ { print $2 }'
```

### Step 3: Assemble a kubeconfig and register

Follow

<a href={"/docs/enterprise/" + "10.1" + "/guides/security/dcf/kubernetes-onboard-custom#step-2-assemble-a-kubeconfig"}>Step 2</a>
and
<a href={"/docs/enterprise/" + "10.1" + "/guides/security/dcf/kubernetes-onboard-custom#step-3-register-the-cluster"}>Step 3</a>
on the custom-clusters page. AKS Terraform:

```hcl theme={null}
data "azurerm_kubernetes_cluster" "this" {
  name                = "<CLUSTER_NAME>"
  resource_group_name = "<RESOURCE_GROUP>"
}

resource "aviatrix_kubernetes_cluster" "this" {
  cluster_id  = lower(data.azurerm_kubernetes_cluster.this.id)
  kube_config = file("avx-kubeconfig.yaml")
}
```

## Verifying onboarding

On the **Kubernetes Clusters** tab, the cluster transitions through `No` →
`Onboarding` → `Yes`. From the controller pod:

```bash theme={null}
kubectl exec -ti deploy/cloudxd -- asset-cli status k8s
```

The cluster should reach `RUNNING` within roughly 30 seconds.

## Notes on Load Balancers

Network Load Balancers can be used but only when restricted to private subnets.
You are responsible for the authorization of NLBs and Application Load Balancers
in public subnets.

## Related Topics

* <a href={"/docs/enterprise/" + "10.1" + "/reference/dcf/kubernetes-prerequisites"}>Kubernetes Onboarding Prerequisites</a>
* <a href={"/docs/enterprise/" + "10.1" + "/guides/security/dcf/kubernetes-onboard"}>Onboarding Kubernetes Clusters</a>
* <a href={"/docs/enterprise/" + "10.1" + "/guides/security/dcf/dcf-kubernetes"}>Distributed Cloud Firewall for Kubernetes</a>
* <a href={"/docs/enterprise/" + "10.1" + "/reference/dcf/kubernetes-snat"}>Disable SNAT for Kubernetes Workloads</a>
* <a href={"/docs/enterprise/" + "10.1" + "/guides/security/dcf/kubernetes-onboard-custom"}>Onboard Self-Managed or Custom Clusters</a>
