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

# Cluster API

> Kubernetes cluster registration and management in Argo CD

## Overview

The Cluster Service API manages Kubernetes cluster configurations. Clusters represent deployment targets for Applications and must be registered with Argo CD before use.

**Base Path:** `/api/v1/clusters`

**gRPC Service:** `cluster.ClusterService`

## Cluster Resource

A Cluster represents a Kubernetes cluster that can be used as an Application destination.

### Cluster Spec

<ParamField path="server" type="string" required>
  Kubernetes API server URL

  ```yaml theme={null}
  server: https://kubernetes.default.svc  # In-cluster
  server: https://1.2.3.4:6443           # External cluster
  ```
</ParamField>

<ParamField path="name" type="string">
  Cluster name (unique identifier, alternative to server)

  ```yaml theme={null}
  name: prod-us-east-1
  ```
</ParamField>

<ParamField path="config" type="ClusterConfig" required>
  Authentication and connection configuration

  <Expandable title="ClusterConfig fields">
    <ResponseField name="bearerToken" type="string">
      Bearer token for authentication
    </ResponseField>

    <ResponseField name="tlsClientConfig" type="TLSClientConfig">
      TLS certificate configuration

      * `insecure`: Skip TLS verification
      * `caData`: Base64-encoded CA certificate
      * `certData`: Base64-encoded client certificate
      * `keyData`: Base64-encoded client key
    </ResponseField>

    <ResponseField name="awsAuthConfig" type="AWSAuthConfig">
      AWS IAM authentication configuration
    </ResponseField>

    <ResponseField name="execProviderConfig" type="ExecProviderConfig">
      External credential provider configuration
    </ResponseField>
  </Expandable>
</ParamField>

<ParamField path="namespaces" type="string[]">
  Allowed namespaces (empty = all namespaces)
</ParamField>

<ParamField path="clusterResources" type="boolean">
  Whether Argo CD can manage cluster-scoped resources
</ParamField>

<ParamField path="project" type="string">
  Project that owns this cluster
</ParamField>

<ParamField path="labels" type="map[string]string">
  Labels for cluster selection in ApplicationSets
</ParamField>

<ParamField path="annotations" type="map[string]string">
  Cluster annotations
</ParamField>

### Example Cluster

```yaml theme={null}
apiVersion: v1
kind: Secret
metadata:
  name: prod-cluster
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: cluster
type: Opaque
stringData:
  name: prod-us-east-1
  server: https://prod-cluster.example.com
  config: |
    {
      "bearerToken": "<token>",
      "tlsClientConfig": {
        "insecure": false,
        "caData": "<base64-ca-cert>"
      }
    }
  namespaces: production,staging
  clusterResources: "true"
  project: production
data:
  labels: |
    env: production
    region: us-east-1
```

## API Operations

### List Clusters

Retrieve a list of registered clusters.

```bash theme={null}
GET /api/v1/clusters
```

<ParamField query="server" type="string">
  Filter by server URL
</ParamField>

<ParamField query="name" type="string">
  Filter by cluster name
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl https://argocd-server/api/v1/clusters \
    -H "Authorization: Bearer $TOKEN"
  ```

  ```go Go theme={null}
  import clusterpkg "github.com/argoproj/argo-cd/v3/pkg/apiclient/cluster"

  clusterClient := clusterpkg.NewClusterServiceClient(conn)
  clusters, err := clusterClient.List(ctx, &clusterpkg.ClusterQuery{})
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://argocd-server/api/v1/clusters",
      headers={"Authorization": f"Bearer {token}"}
  )
  clusters = response.json()
  ```
</CodeGroup>

**Response:**

```json theme={null}
{
  "items": [
    {
      "server": "https://kubernetes.default.svc",
      "name": "in-cluster",
      "config": {
        "tlsClientConfig": {
          "insecure": false
        }
      },
      "connectionState": {
        "status": "Successful",
        "message": "cluster is reachable"
      },
      "serverVersion": "1.28",
      "info": {
        "serverVersion": "1.28.3",
        "applicationsCount": 5
      }
    }
  ]
}
```

### Get Cluster

Retrieve a specific cluster by server URL or name.

```bash theme={null}
GET /api/v1/clusters/{id.value}
```

<ParamField path="id.value" type="string" required>
  Cluster server URL or name (URL-encoded)
</ParamField>

<ParamField query="id.type" type="string">
  Identifier type: "server" (default) or "name"
</ParamField>

<CodeGroup>
  ```bash Get by server URL theme={null}
  SERVER=$(echo -n "https://kubernetes.default.svc" | jq -sRr @uri)
  curl "https://argocd-server/api/v1/clusters/${SERVER}" \
    -H "Authorization: Bearer $TOKEN"
  ```

  ```bash Get by name theme={null}
  curl "https://argocd-server/api/v1/clusters/prod-us-east-1?id.type=name" \
    -H "Authorization: Bearer $TOKEN"
  ```

  ```go Go theme={null}
  cluster, err := clusterClient.Get(ctx, &clusterpkg.ClusterQuery{
      Id: &clusterpkg.ClusterID{
          Type:  "name",
          Value: "prod-us-east-1",
      },
  })
  ```
</CodeGroup>

### Create Cluster

Register a new cluster with Argo CD.

```bash theme={null}
POST /api/v1/clusters
```

<ParamField body="cluster" type="Cluster" required>
  Complete Cluster configuration
</ParamField>

<ParamField body="upsert" type="boolean">
  Update if already exists (default: false)
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://argocd-server/api/v1/clusters \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "server": "https://prod-cluster.example.com",
      "name": "prod-us-east-1",
      "config": {
        "bearerToken": "eyJhbGc...",
        "tlsClientConfig": {
          "insecure": false,
          "caData": "LS0tLS1CRUdJTi..."
        }
      },
      "namespaces": ["production", "staging"],
      "labels": {
        "env": "production",
        "region": "us-east-1"
      }
    }'
  ```

  ```go Go theme={null}
  cluster, err := clusterClient.Create(ctx, &clusterpkg.ClusterCreateRequest{
      Cluster: &v1alpha1.Cluster{
          Server: "https://prod-cluster.example.com",
          Name:   "prod-us-east-1",
          Config: v1alpha1.ClusterConfig{
              BearerToken: "eyJhbGc...",
              TLSClientConfig: v1alpha1.TLSClientConfig{
                  Insecure: false,
                  CAData:   []byte("-----BEGIN CERTIFICATE-----..."),
              },
          },
          Namespaces: []string{"production", "staging"},
          Labels: map[string]string{
              "env":    "production",
              "region": "us-east-1",
          },
      },
      Upsert: false,
  })
  ```

  ```bash CLI (recommended) theme={null}
  # Using argocd CLI to add cluster from kubeconfig
  argocd cluster add prod-context \
    --name prod-us-east-1 \
    --label env=production \
    --label region=us-east-1
  ```
</CodeGroup>

### Update Cluster

Update an existing cluster configuration.

```bash theme={null}
PUT /api/v1/clusters/{id.value}
```

<ParamField path="id.value" type="string" required>
  Cluster server URL or name (URL-encoded)
</ParamField>

<ParamField body="cluster" type="Cluster" required>
  Updated Cluster configuration
</ParamField>

<ParamField body="updatedFields" type="string[]">
  List of fields to update (empty = update all)
</ParamField>

**Example:**

```bash theme={null}
curl -X PUT "https://argocd-server/api/v1/clusters/prod-us-east-1?id.type=name" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "cluster": {
      "server": "https://prod-cluster.example.com",
      "name": "prod-us-east-1",
      "labels": {
        "env": "production",
        "region": "us-east-1",
        "tier": "critical"
      }
    },
    "updatedFields": ["labels"]
  }'
```

### Delete Cluster

Remove a cluster from Argo CD.

```bash theme={null}
DELETE /api/v1/clusters/{id.value}
```

<ParamField path="id.value" type="string" required>
  Cluster server URL or name (URL-encoded)
</ParamField>

<ParamField query="id.type" type="string">
  Identifier type: "server" or "name"
</ParamField>

<Warning>
  Deleting a cluster does not affect the actual Kubernetes cluster, only Argo CD's registration of it. Applications deployed to the cluster will remain.
</Warning>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X DELETE "https://argocd-server/api/v1/clusters/prod-us-east-1?id.type=name" \
    -H "Authorization: Bearer $TOKEN"
  ```

  ```go Go theme={null}
  _, err := clusterClient.Delete(ctx, &clusterpkg.ClusterQuery{
      Id: &clusterpkg.ClusterID{
          Type:  "name",
          Value: "prod-us-east-1",
      },
  })
  ```
</CodeGroup>

## Cluster Operations

### Rotate Auth

Rotate the bearer token for a cluster.

```bash theme={null}
POST /api/v1/clusters/{id.value}/rotate-auth
```

<ParamField path="id.value" type="string" required>
  Cluster server URL or name
</ParamField>

<Info>
  This operation creates a new service account token and updates the cluster configuration. The old token remains valid for a grace period.
</Info>

**Example:**

```bash theme={null}
curl -X POST "https://argocd-server/api/v1/clusters/prod-us-east-1/rotate-auth?id.type=name" \
  -H "Authorization: Bearer $TOKEN"
```

### Invalidate Cache

Clear cached cluster information and force reconnection.

```bash theme={null}
POST /api/v1/clusters/{id.value}/invalidate-cache
```

<ParamField path="id.value" type="string" required>
  Cluster server URL or name
</ParamField>

**Example:**

```bash theme={null}
curl -X POST "https://argocd-server/api/v1/clusters/prod-us-east-1/invalidate-cache?id.type=name" \
  -H "Authorization: Bearer $TOKEN"
```

## Authentication Methods

### Bearer Token Authentication

Most common method using a Kubernetes service account token.

```json theme={null}
{
  "config": {
    "bearerToken": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ii...",
    "tlsClientConfig": {
      "caData": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
    }
  }
}
```

### TLS Client Certificate

Authenticate using client certificates.

```json theme={null}
{
  "config": {
    "tlsClientConfig": {
      "caData": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...",
      "certData": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...",
      "keyData": "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVkt..."
    }
  }
}
```

### AWS EKS Authentication

For Amazon EKS clusters.

```json theme={null}
{
  "config": {
    "awsAuthConfig": {
      "clusterName": "prod-cluster",
      "roleARN": "arn:aws:iam::123456789012:role/ArgoCDClusterRole"
    }
  }
}
```

### External Credential Provider

Use exec-based credential plugins.

```json theme={null}
{
  "config": {
    "execProviderConfig": {
      "command": "aws-iam-authenticator",
      "args": ["token", "-i", "prod-cluster"],
      "env": {
        "AWS_PROFILE": "production"
      },
      "apiVersion": "client.authentication.k8s.io/v1beta1"
    }
  }
}
```

## Connection State

Clusters report their connection status:

```json theme={null}
{
  "connectionState": {
    "status": "Successful",
    "message": "cluster is reachable",
    "attemptedAt": "2024-03-04T12:00:00Z"
  },
  "serverVersion": "1.28.3",
  "info": {
    "serverVersion": "1.28.3",
    "applicationsCount": 12,
    "cacheInfo": {
      "resourcesCount": 1534,
      "apisCount": 42
    }
  }
}
```

**Status Values:**

* `Successful`: Cluster is reachable and authenticated
* `Failed`: Connection or authentication failed
* `Unknown`: Status not yet determined

## Cluster Labels

Labels are used by ApplicationSet generators to select clusters.

### Setting Labels

```json theme={null}
{
  "labels": {
    "env": "production",
    "region": "us-east-1",
    "cloud": "aws",
    "tier": "critical"
  }
}
```

### Using Labels in ApplicationSets

```yaml theme={null}
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: cluster-apps
spec:
  generators:
  - clusters:
      selector:
        matchLabels:
          env: production
        matchExpressions:
        - key: region
          operator: In
          values: [us-east-1, us-west-2]
  template:
    # ...
```

## Namespace Restrictions

Limit which namespaces Argo CD can access:

```json theme={null}
{
  "namespaces": [
    "production",
    "staging",
    "argocd"
  ]
}
```

Empty list = all namespaces accessible.

## Security Best Practices

<AccordionGroup>
  <Accordion title="Use Dedicated Service Accounts">
    Create dedicated service accounts with minimal permissions for Argo CD.

    ```bash theme={null}
    kubectl create serviceaccount argocd-manager -n kube-system
    kubectl create clusterrolebinding argocd-manager-binding \
      --clusterrole=cluster-admin \
      --serviceaccount=kube-system:argocd-manager
    ```
  </Accordion>

  <Accordion title="Enable TLS Verification">
    Always verify TLS certificates in production:

    ```json theme={null}
    {
      "tlsClientConfig": {
        "insecure": false,
        "caData": "<base64-ca-cert>"
      }
    }
    ```
  </Accordion>

  <Accordion title="Rotate Credentials Regularly">
    Use the rotate-auth endpoint to refresh tokens periodically.
  </Accordion>

  <Accordion title="Restrict Cluster Resources">
    Set `clusterResources: false` if cluster-scoped access isn't needed.
  </Accordion>

  <Accordion title="Use Namespace Restrictions">
    Limit accessible namespaces to reduce attack surface.
  </Accordion>
</AccordionGroup>

## In-Cluster vs External

### In-Cluster

Argo CD's own cluster:

```yaml theme={null}
server: https://kubernetes.default.svc
name: in-cluster
```

* Automatically registered
* Uses in-cluster service account
* Cannot be deleted

### External Clusters

Remote clusters:

```yaml theme={null}
server: https://external-cluster.example.com:6443
name: prod-cluster
```

* Must be explicitly registered
* Requires authentication configuration
* Can be added via CLI or API

## Next Steps

<CardGroup cols={2}>
  <Card title="Application API" icon="rocket" href="/api/application">
    Deploy applications to clusters
  </Card>

  <Card title="ApplicationSet API" icon="layer-group" href="/api/applicationset">
    Use cluster generators
  </Card>

  <Card title="Project API" icon="folder" href="/api/appproject">
    Configure cluster destinations in projects
  </Card>
</CardGroup>
