> ## 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 EKS Clusters

> Step-by-step EKS onboarding for the Aviatrix Distributed Cloud Firewall. Two authentication paths: AWS Cloud Account (recommended) and service-account kubeconfig.

Onboard a publicly accessible EKS cluster to the Aviatrix Controller for
Distributed Cloud Firewall. For private EKS 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 on worker nodes.

The Aviatrix cloud account for the AWS account hosting the cluster must include
the

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

## DCF policy requirements for cluster connectivity

When DCF is enabled, you are responsible for configuring DCF policies that allow
the EKS cluster to reach the AWS services it needs for normal operation. Without
these policies, cluster components may fail to pull container images from Amazon
ECR, authenticate to IAM, or reach the EKS control plane.

For the list of AWS services an EKS cluster must reach (including the endpoints
required for private clusters), see AWS's documentation on
[deploying private clusters with limited internet access](https://docs.aws.amazon.com/eks/latest/userguide/private-clusters.html).
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 — AWS Cloud Account (recommended for managed EKS).** The Aviatrix IAM
  principal you onboarded in CoPilot authenticates to the cluster via an EKS
  access entry. The Controller refreshes a short-lived STS token per request; no
  long-lived credential to rotate.
* **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. Use this when you want explicit control over the principal or when
  the AWS-account path is not acceptable.

You can switch paths later by re-onboarding the cluster.

## Path A — Cloud Account

### Step 1: Identify the Controller's IAM principal

The Controller authenticates to AWS using the IAM identity from the Aviatrix
cloud account. The ARN format depends on how you onboarded the account:

* **IAM role (most common):** `arn:aws:iam::<ACCOUNT_ID>:role/aviatrix-role-app`
* **IAM user (access key + secret):**
  `arn:aws:iam::<ACCOUNT_ID>:user/<USERNAME>`

Find the ARN under **Cloud Resources > Cloud Account** in CoPilot, or in the AWS
IAM console under **Roles**.

### Step 2: Install the Aviatrix helm chart in the cluster

The chart creates the `avx-controller` ClusterRole, a ClusterRoleBinding to the
Kubernetes group `avx-controller`, and the Aviatrix CRDs.

```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
```

### Step 3: Map the IAM principal to the K8s group

Create an EKS access entry that binds the Controller's IAM principal to the K8s
group `avx-controller`. Choose any tool:

<Tabs>
  <Tab title="Terraform">
    ```hcl theme={null}
    resource "aws_eks_access_entry" "aviatrix" {
      cluster_name      = "<CLUSTER_NAME>"
      principal_arn     = "<CONTROLLER_PRINCIPAL_ARN>"
      kubernetes_groups = ["avx-controller"]
      type              = "STANDARD"
    }

    resource "aws_eks_access_policy_association" "aviatrix" {
      cluster_name  = aws_eks_access_entry.aviatrix.cluster_name
      policy_arn    = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy"
      principal_arn = aws_eks_access_entry.aviatrix.principal_arn

      access_scope {
        type = "cluster"
      }
    }
    ```

    The `AmazonEKSViewPolicy` association is belt-and-suspenders alongside the helm
    chart. The chart's ClusterRole grants every read the policy provides plus the
    CRD writes the policy does not.
  </Tab>

  <Tab title="aws CLI">
    ```bash theme={null}
    aws eks create-access-entry \
      --cluster-name <CLUSTER_NAME> \
      --principal-arn <CONTROLLER_PRINCIPAL_ARN> \
      --kubernetes-groups avx-controller \
      --type STANDARD

    aws eks associate-access-policy \
      --cluster-name <CLUSTER_NAME> \
      --principal-arn <CONTROLLER_PRINCIPAL_ARN> \
      --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy \
      --access-scope type=cluster
    ```
  </Tab>

  <Tab title="eksctl">
    ```yaml theme={null}
    # accessentry.yaml
    kind: ClusterConfig
    apiVersion: eksctl.io/v1alpha5
    metadata:
      name: <CLUSTER_NAME>
      region: <REGION>
    accessConfig:
      authenticationMode: API_AND_CONFIG_MAP
      accessEntries:
        - principalARN: "<CONTROLLER_PRINCIPAL_ARN>"
          type: STANDARD
          kubernetesGroups:
            - avx-controller
          accessPolicies:
            - policyARN: arn:aws:eks::aws:cluster-access-policy/AmazonEKSViewPolicy
              accessScope:
                type: cluster
    ```

    ```bash theme={null}
    eksctl create accessentry -f accessentry.yaml
    ```
  </Tab>
</Tabs>

### Step 4: Register the cluster

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

    resource "aviatrix_kubernetes_cluster" "this" {
      cluster_id          = data.aws_eks_cluster.this.arn
      use_csp_credentials = true

      depends_on = [
        aws_eks_access_policy_association.aviatrix,
      ]
    }
    ```

    `cluster_id` must be the full EKS ARN:
    `arn:aws:eks:<REGION>:<ACCOUNT_ID>:cluster/<CLUSTER_NAME>`.
  </Tab>

  <Tab title="CoPilot UI">
    1. Navigate to **Cloud Resources > Cloud Assets > Kubernetes Clusters**.
    2. Click **Onboard** next to the discovered EKS cluster.
    3. Select an authentication option:
       * **Terraform** — CoPilot generates HCL for the access entry and helm chart
         installation. Copy, run `terraform apply`, check the confirmation box, and
         click **Onboard**.
       * **Command Line** — CoPilot generates `eksctl` and `kubectl` YAML. Apply
         both, check the confirmation box, and click **Onboard**.
       * **Upload Kubeconfig** — switches to
         [Path B](#path-b--service-account-kubeconfig).
  </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>
. EKS-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}
aws eks describe-cluster --name <CLUSTER_NAME> --query cluster.certificateAuthority.data --output text
aws eks describe-cluster --name <CLUSTER_NAME> --query cluster.endpoint --output text
```

### Step 3: Assemble a kubeconfig and register the cluster

Follow

<a href={"/docs/enterprise/" + "10.1" + "/guides/security/dcf/kubernetes-onboard-custom#step-2-assemble-a-kubeconfig"}>Step 2: Assemble a kubeconfig</a>
and
<a href={"/docs/enterprise/" + "10.1" + "/guides/security/dcf/kubernetes-onboard-custom#step-3-register-the-cluster"}>Step 3: Register the cluster</a>
on the custom-clusters page. The Terraform `cluster_id` for an EKS cluster
registered via kubeconfig should still be the EKS ARN:

```hcl theme={null}
data "aws_eks_cluster" "this" {
  name = "<CLUSTER_NAME>"
}

resource "aviatrix_kubernetes_cluster" "this" {
  cluster_id  = data.aws_eks_cluster.this.arn
  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.

## CRD-based DCF policy on EKS

CRD-based policy is gated by the `k8s_dcf_policies` feature flag (default off;
enabled by Aviatrix). When the flag is on, the `avx-controller` ClusterRole the
helm chart installs grants the additional permissions needed
(`networking.aviatrix.com/*`, events, CRD existence check). See

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

## Troubleshooting

| Symptom                                          | Cause                                                    | Resolution                                                                                                                                                                                                                                                                          |
| ------------------------------------------------ | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Cluster not appearing on Kubernetes Clusters tab | Discovery off or cloud account missing perms             | Enable <a href={"/docs/enterprise/" + "10.1" + "/guides/security/dcf/kubernetes-resource-discovery"}>Resource Discovery</a>; check <a href={"/docs/enterprise/" + "10.1" + "/reference/dcf/kubernetes-prerequisites#cloud-account-discovery-permissions"}>discovery permissions</a> |
| Onboarding fails with "invalid content"          | Kubeconfig is malformed or uses `exec` auth              | See <a href={"/docs/enterprise/" + "10.1" + "/reference/dcf/kubernetes-prerequisites#kubeconfig-requirements"}>Kubeconfig requirements</a>                                                                                                                                          |
| Onboarded but 0 namespaces/services/pods         | Controller cannot reach API server, or RBAC insufficient | Verify network path; verify chart is installed and access entry binds to `avx-controller`                                                                                                                                                                                           |
| Status `Fail` with no useful error               | Controller's IAM principal has no EKS access entry       | Confirm access entry exists and `AmazonEKSViewPolicy` is associated                                                                                                                                                                                                                 |

## 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>
