---
title: "Create a Calico Enterprise management cluster"
description: "Install a self-managed Calico Enterprise management cluster with Helm 3 to consolidate control of multiple managed clusters from a single plane."
product: "Calico Enterprise"
version: "3.23 (latest)"
section: "Multi-cluster management"
canonical_url: "https://docs.tigera.io/calico-enterprise/latest/multicluster/set-up-multi-cluster-management/helm-install/create-a-management-cluster-helm"
---

# Create a Calico Enterprise management cluster

## Big picture

Create a Calico Enterprise management cluster to manage multiple clusters from a single management plane using Helm 3.

## Value

Helm charts are a way to package up an application for Kubernetes (similar to `apt` or `yum` for operating systems). Helm is also used by tools like ArgoCD to manage applications in a cluster, taking care of install, upgrade (and rollback if needed), etc.

## Before you begin

**Required**

- Install Helm 3
- `kubeconfig` is configured to work with your cluster (check by running `kubectl get nodes`)
- [Credentials for the Tigera private registry and a license key](https://docs.tigera.io/calico-enterprise/latest/getting-started/install-on-clusters/calico-enterprise.md)

## Concepts

### Operator-based installation

In this guide, you install the Tigera Calico operator and custom resource definitions using the Helm 3 chart. The Tigera Operator provides lifecycle management for Calico Enterprise exposed via the Kubernetes API defined as a custom resource definition.

## How to

### Get the Helm chart

```bash
helm repo add tigera-ee https://downloads.tigera.io/ee/charts
helm repo update
helm pull tigera-ee/tigera-operator --version v3.23.2
helm pull tigera-ee/crd.projectcalico.org.v1 --version v3.23.2
```

### Prepare the Installation Configuration

You **must** provide the desired configuration for your cluster via the `values.yaml`, otherwise installation will use the default settings based on the auto-detected provider. The configurations you need to provide depends on your cluster's settings and your desired state.

Some important configurations you might need to provide to the installer (via `values.yaml`) includes (but not limited to): *kubernetesProvider*, *cni type*, or if you need to customize *TLS certificates*.

Here are some examples for updating `values.yaml` with your configurations:

Example 1. Providing `kubernetesProvider`: if you are installing on a cluster installed by EKS, set the `kubernetesProvider` as described in the [Installation reference](https://docs.tigera.io/calico-enterprise/latest/reference/installation/api.md#provider)

```bash
echo '{ installation: {kubernetesProvider: EKS }}' > values.yaml
```

Example 2. Providing custom settings in `values.yaml` for Azure AKS cluster with no Kubernetes CNI pre-installed:

```bash
cat > values.yaml <<EOF
installation:
  kubernetesProvider: AKS
  cni:
    type: Calico
  calicoNetwork:
    bgp: Disabled
    ipPools:
    - cidr: 10.244.0.0/16
      encapsulation: VXLAN
EOF
```

For more information about configurable options via `values.yaml` please see [Helm installation reference](https://docs.tigera.io/calico-enterprise/latest/reference/installation/helm_customization.md).

### Install Calico Enterprise

<!-- tabs -->

**Tab: NodePort**

To install a Calico Enterprise [management](https://docs.tigera.io/calico-enterprise/latest/multicluster/set-up-multi-cluster-management/helm-install/create-a-management-cluster-helm.md#value) cluster with Helm, using a NodePort service:

1. [Configure a storage class for Calico Enterprise](https://docs.tigera.io/calico-enterprise/latest/operations/logstorage/create-storage.md).

2. Export the service node port number

```bash
export EXT_SERVICE_NODE_PORT=30449
```

Export the public address or host of the management cluster. (Ex. "example.com:1234" or "10.0.0.10:1234".)

```bash
export MANAGEMENT_CLUSTER_ADDR=<your-management-cluster-addr>:$EXT_SERVICE_NODE_PORT
```

1. Export one or more managed clusters.

Generate the base64 encoded CRT and KEY for a managed cluster:

```bash
openssl genrsa 2048 | base64 -w 0 > my-managed-cluster.key.base64
openssl req -new -key <(base64 -d my-managed-cluster.key.base64) -subj "/CN=my-managed-cluster" | \
openssl x509 -req -signkey <(base64 -d my-managed-cluster.key.base64) -days 365 | base64 -w 0 > my-managed-cluster.crt.base64
```

Export the managed cluster variables:

```bash
export MANAGED_CLUSTER_NAME=my-managed-cluster
export MANAGED_CLUSTER_OPERATOR_NAMESPACE=tigera-operator
export MANAGED_CLUSTER_CERTIFICATE=$(cat my-managed-cluster.crt.base64)
```

1. Append the management cluster context to your `values.yaml`:

```bash
echo "
managementCluster:
  enabled: true
  address: $MANAGEMENT_CLUSTER_ADDR
  service:
    enabled: true
    annotations:
    type: NodePort
    port: 9449
    targetPort: 9449
    protocol: TCP
    nodePort: $EXT_SERVICE_NODE_PORT

managedClusters:
  enabled: true
  clusters:
  - name: $MANAGED_CLUSTER_NAME
    operatorNamespace: $MANAGED_CLUSTER_OPERATOR_NAMESPACE
    certificate: $MANAGED_CLUSTER_CERTIFICATE" >> values.yaml
```

1. Install the necessary custom resource definitions.

```bash
helm template calico-crds crd.projectcalico.org.v1-v3.23.2-0.tgz | kubectl apply --server-side -f -
```

1. Install the Tigera Operator using the Helm 3 chart:

```bash
helm install calico-enterprise tigera-operator-v3.23.2-0.tgz -f values.yaml \
--set-file imagePullSecrets.tigera-pull-secret=<path/to/pull/secret>,tigera-prometheus-operator.imagePullSecrets.tigera-pull-secret=<path/to/pull/secret> \
--set-file licenseKeyContent=<path/to/license/file/yaml> \
--namespace tigera-operator \
--create-namespace
```

1. You can now monitor progress with the following command:

```bash
watch kubectl get tigerastatus
```

**Tab: LoadBalancer**

To install a Calico Enterprise [management](https://docs.tigera.io/calico-enterprise/latest/multicluster/set-up-multi-cluster-management/helm-install/create-a-management-cluster-helm.md#value) cluster with Helm, using a LoadBalancer service:

#### Meet cloud provider requirements

Ensure that you have met the requirements for your cloud provider to provision a load balancer in your environment.

For example, if you are using EKS, you must meet the requirements defined in [create a network load balancer for AWS](https://docs.aws.amazon.com/eks/latest/userguide/network-load-balancing.html)

#### Install the management cluster

1. [Configure a storage class for Calico Enterprise](https://docs.tigera.io/calico-enterprise/latest/operations/logstorage/create-storage.md).

2. Export one or more managed clusters.

Generate the base64 encoded CRT and KEY for a managed cluster:

```bash
openssl genrsa 2048 | base64 -w 0 > my-managed-cluster.key.base64
openssl req -new -key <(base64 -d my-managed-cluster.key.base64) -subj "/CN=my-managed-cluster" | \
openssl x509 -req -signkey <(base64 -d my-managed-cluster.key.base64) -days 365 | base64 -w 0 > my-managed-cluster.crt.base64
```

Export the managed cluster variables:

```bash
export MANAGED_CLUSTER_NAME=my-managed-cluster
export MANAGED_CLUSTER_OPERATOR_NAMESPACE=tigera-operator
export MANAGED_CLUSTER_CERTIFICATE=$(cat my-managed-cluster.crt.base64)
```

1. Append the management cluster context to your `values.yaml`:

```bash
echo "
managementCluster:
  enabled: true
  service:
    enabled: true
    annotations:
    type: LoadBalancer
    port: 9449
    targetPort: 9449
    protocol: TCP

managedClusters:
  enabled: true
  clusters:
  - name: $MANAGED_CLUSTER_NAME
    operatorNamespace: $MANAGED_CLUSTER_OPERATOR_NAMESPACE
    certificate: $MANAGED_CLUSTER_CERTIFICATE" >> values.yaml
```

If you are using EKS, make sure your management cluster has the following annotations:

```yaml
managementCluster:
  service:
    annotations:
    - key: service.beta.kubernetes.io/aws-load-balancer-type
      value: "external"
    - key: service.beta.kubernetes.io/aws-load-balancer-nlb-target-type
      value: "instance"
    - key: service.beta.kubernetes.io/aws-load-balancer-scheme
      value: "internet-facing"
```

1. Install the necessary custom resource definitions.

```bash
helm template calico-crds crd.projectcalico.org.v1-v3.23.2-0.tgz | kubectl apply --server-side -f -
```

1. Install the Tigera Operator using the Helm 3 chart:

```bash
helm install calico-enterprise tigera-operator-v3.23.2-0.tgz -f values.yaml \
--set-file imagePullSecrets.tigera-pull-secret=<path/to/pull/secret>,tigera-prometheus-operator.imagePullSecrets.tigera-pull-secret=<path/to/pull/secret> \
--set-file licenseKeyContent=<path/to/license/file/yaml> \
--namespace tigera-operator \
--create-namespace
```

1. You can now monitor progress with the following command:

```bash
watch kubectl get tigerastatus
```

#### Update the ManagementCluster address

1. Export the service port number

```bash
export EXT_LB_PORT=<your-external-load-balancer-port>
```

Export the public address or host of the management cluster, in this case the load-balancer's external IP (Ex. "example.com:1234" or "10.0.0.10:1234".)

```bash
export MANAGEMENT_CLUSTER_ADDR=<your-load-balancer-external-addr>:$EXT_LB_PORT
```

Replace the `address` field in the ManagementCluster resource.

```bash
kubectl patch managementcluster tigera-secure --type merge -p "{\"spec\":{\"address\":\"${MANAGEMENT_CLUSTER_ADDR}\"}}"
```

<!-- /tabs -->

#### Create an admin user and verify management cluster connection

To access resources in a managed cluster from the Calico Enterprise web console within the management cluster, the logged-in user must have appropriate permissions defined in that managed cluster (clusterrole bindings).

Create an admin user, `mcm-user`, in the default namespace with full permissions, and token.

```bash
kubectl create sa mcm-user
kubectl create clusterrolebinding mcm-user-admin --clusterrole=tigera-network-admin --serviceaccount=default:mcm-user
kubectl create token mcm-user -n default
```

Use the generated token, to connect to the UI. In the top right banner in the UI, your management cluster is displayed as the first entry in the cluster selection drop-down menu with the fixed name, `management cluster`.

Congratulations! You have now installed Calico Enterprise for a management cluster using the Helm 3 chart.

## Next steps

**Recommended**

- [Configure access to the Calico Enterprise web console](https://docs.tigera.io/calico-enterprise/latest/operations/cnx/access-the-manager.md)
- [Authentication quickstart](https://docs.tigera.io/calico-enterprise/latest/operations/cnx/authentication-quickstart.md)
- [Configure your own identity provider](https://docs.tigera.io/calico-enterprise/latest/operations/cnx/configure-identity-provider.md)

**Recommended - Networking**

- The default networking is IP in IP encapsulation using BGP routing. For all networking options, see [Determine best networking option](https://docs.tigera.io/calico-enterprise/latest/networking/determine-best-networking.md).

**Recommended - Security**

- [Get started with Calico Enterprise tiered network policy](https://docs.tigera.io/calico-enterprise/latest/network-policy/policy-tiers/tiered-policy.md)
