> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/harness-platform/use-harness-platform/delegates/delegate/install-delegates/overview.md).

# Delegate installation options

Expand the section below for instructions on installing the default delegate for your Harness account. It can be either a Kubernetes delegate installed using a Helm chart, Terraform Helm Provider, or Kubernetes manifest or a Docker delegate using the `docker run` command. For more information, go to [Install Harness Delegate on Kubernetes or Docker](/harness-platform/troubleshooting-and-resources/tutorials/install-delegate.md).

<details>

<summary>Install the default delegate on Kubernetes or Docker</summary>

The [Harness Delegate](/harness-platform/use-harness-platform/delegates/delegate/delegate-concepts/delegate-overview.md) is a lightweight worker process that is installed on your infrastructure and communicates only via outbound HTTP/HTTPS to the Harness Platform. This enables the Harness Platform to leverage the delegate to execute the CI/CD and other tasks on your behalf, without any of your secrets leaving your network.

You can install the Harness Delegate on either Docker or Kubernetes.

### Install the default Harness Delegate <a href="#install-the-default-harness-delegate" id="install-the-default-harness-delegate"></a>

#### Create a new delegate token <a href="#create-a-new-delegate-token" id="create-a-new-delegate-token"></a>

You can install delegates from the Account, Project, or Org scope. In this example, we'll create a new token in the Account scope.

To create a new delegate token, do the following:

1. In Harness, select **Account Settings**, then select **Account Resources**. The Account Resources page opens.
2. Select **Delegates**. The Delegates list page opens.
3. Select the **Tokens** tab, then select **+New Token**. The **New Token** dialog opens.
4. Enter a token name, for example `firstdeltoken`.
5. Select **Apply**. Harness generates a new token for you.
6. Select **Copy** to copy and store the token in a temporary file.

   You will provide this token as an input parameter in the next installation step. The delegate will use this token to authenticate with the Harness Platform.

#### Get your Harness account ID <a href="#get-your-harness-account-id" id="get-your-harness-account-id"></a>

Along with the delegate token, you will also need to provide your Harness `accountId` as an input parameter during delegate installation. This `accountId` is present in every Harness URL. For example, in the following URL:

```
https://app.harness.io/ng/#/account/6_vVHzo9Qeu9fXvj-AcQCb/settings/overview
```

`6_vVHzo9Qeu9fXvj-AcQCb` is the `accountId`.

{% hint style="info" %}
**NOTE**

When you install a delegate via the Harness UI, several dependencies in this topic are prefilled for your convenience. This topic explains where to find the required information for CLI-based installation.
{% endhint %}

For more information, go to [View account info and subscribe to downtime alerts](/harness-platform/subscriptions-and-licenses/view-account-info-and-subscribe-to-alerts.md).

PrerequisiteEnsure that you have access to a Kubernetes cluster. For the purposes of this tutorial, we will use minikube.Install minikubeOn Windowschoco install minikubeFor Chocolatey installation instructions, go to Installing Chocolatey in the Chocolatey documentation.For additional options to install minikube on Windows, go to minikube start in the minikube documentation.On macOS:brew install minikubeFor Homebrew installation instructions, go to Installation in the Homebrew documentation.Now start minikube with the following config.minikube start --memory 4g --cpus 4Validate that you have kubectl access to your cluster.kubectl get pods -ANow that you have access to a Kubernetes cluster, you can install the delegate using any of the options below\.Install the Helm chartAs a prerequisite, you must have Helm v3 installed on the machine from which you connect to your Kubernetes cluster.You can now install the delegate using the delegate Helm chart. First, add the harness-delegate Helm chart repo to your local Helm registry.helm repo add harness-delegate <https://app.harness.io/storage/harness-download/delegate-helm-chart/helm> repo updatehelm search repo harness-delegateWe will use the harness-delegate/harness-delegate-ng chart in this tutorial.NAME CHART VERSION APP VERSION DESCRIPTIONharness-delegate/harness-delegate-ng 1.0.8 1.16.0 A Helm chart for deploying harness-delegateNow we are ready to install the delegate. The following example installs/upgrades firstk8sdel delegate (which is a Kubernetes workload) in the harness-delegate-ng namespace using the harness-delegate/harness-delegate-ng Helm chart.You can install delegates from the Account, Project, or Org scope. In this example, we'll install a delegate in the Account scope.To install a delegate, do the following:In Harness, select Account Settings, then select Account Resources. The Account Resources page opens.Select Delegates. The Delegates list page opens.Select New Delegate. The New Delegate dialog opens.Under Select where you want to install your Delegate, select Kubernetes.Under Install your Delegate, select Helm Chart.Copy the helm upgrade command.The command uses the default values.yaml file located in the delegate Helm chart GitHub repo. To make persistent changes to one or more values, you can download and update the values.yaml file according to your requirements. Once you have updated the file, you can use it by running the upgrade command below. helm upgrade -i firstk8sdel --namespace harness-delegate-ng --create-namespace \ harness-delegate/harness-delegate-ng \ -f values.yaml \ --set delegateName=firstk8sdel \ --set accountId=PUT\_YOUR\_HARNESS\_ACCOUNTID\_HERE \ --set delegateToken=PUT\_YOUR\_DELEGATE\_TOKEN\_HERE \ --set managerEndpoint=PUT\_YOUR\_MANAGER\_HOST\_AND\_PORT\_HERE \ --set delegateDockerImage=harness/delegate:yy.mm.verno \ --set replicas=1 --set upgrader.enabled=trueNOTETo install a Helm delegate for Harness Self-Managed Enterprise Edition in an air-gapped environment, you must pass your certificate when you add the Helm repo.helm repo add harness-delegate --ca-file <.PEM\_FILE\_PATH> \<HELM\_CHART\_URL\_FROM\_UI>For more information on requirements for air-gapped environments, go to Install in an air-gapped environment.Run the command.Create main.tf fileHarness uses a Terraform module for the Kubernetes delegate. This module uses the standard Terraform Helm provider to install the Helm chart onto a Kubernetes cluster whose config by default is stored in the same machine at the \~/.kube/config path. Copy the following into a main.tf file stored on a machine from which you want to install your delegate.module "delegate" { source = "harness/harness-delegate/kubernetes" version = "0.1.8" account\_id = "PUT\_YOUR\_HARNESS\_ACCOUNTID\_HERE" delegate\_token = "PUT\_YOUR\_DELEGATE\_TOKEN\_HERE" delegate\_name = "firstk8sdel" namespace = "harness-delegate-ng" manager\_endpoint = "PUT\_YOUR\_MANAGER\_HOST\_AND\_PORT\_HERE" delegate\_image = "harness/delegate:yy.mm.verno" replicas = 1 upgrader\_enabled = false # Additional optional values to pass to the helm chart values = yamlencode({ javaOpts: "-Xms64M" })}provider "helm" { kubernetes { config\_path = "\~/.kube/config" }}Now replace the variables in the file with your Harness account ID and delegate token values. Replace PUT\_YOUR\_MANAGER\_HOST\_AND\_PORT\_HERE with the Harness Manager Endpoint noted below. For Harness SaaS accounts, you can find your Harness Cluster Location on the Account Overview page under the Account Settings section of the left navigation.Run Terraform init, plan, and applyInitialize Terraform. This downloads the Terraform Helm provider to your machine.terraform initRun the following step to view the changes Terraform is going to make on your behalf.terraform planFinally, run this step to make Terraform install the Kubernetes delegate using the Helm provider.terraform applyWhen prompted by Terraform if you want to continue with the apply step, type yes, and then you will see output similar to the following.helm\_release.delegate: Creating...helm\_release.delegate: Still creating... \[10s elapsed]helm\_release.delegate: Still creating... \[20s elapsed]helm\_release.delegate: Still creating... \[30s elapsed]helm\_release.delegate: Still creating... \[40s elapsed]helm\_release.delegate: Still creating... \[50s elapsed]helm\_release.delegate: Still creating... \[1m0s elapsed]helm\_release.delegate: Creation complete after 1m0s \[id=firstk8sdel]Apply complete! Resources: 1 added, 0 changed, 0 destroyed.Download a Kubernetes manifest templatecurl -LO <https://raw.githubusercontent.com/harness/delegate-kubernetes-manifest/main/harness-delegate.yamlReplace> variables in the templateOpen the harness-delegate.yaml file in a text editor and replace PUT\_YOUR\_DELEGATE\_NAME\_HERE, PUT\_YOUR\_HARNESS\_ACCOUNTID\_HERE, and PUT\_YOUR\_DELEGATE\_TOKEN\_HERE with your delegate name (for example, firstk8sdel), Harness accountId, and delegate token values, respectively.Replace the PUT\_YOUR\_MANAGER\_HOST\_AND\_PORT\_HERE variable with the Harness Manager Endpoint noted below. For Harness SaaS accounts, you can find your Harness Cluster Location on the Account Overview page under the Account Settings section of the left navigation.Apply the Kubernetes manifestkubectl apply -f harness-delegate.yamlPrerequisitesEnsure that you have the Docker runtime installed on your host. If not, use one of the following options to install Docker:Docker for MacDocker for CentOSDocker for UbuntuDocker for DebianDocker for WindowsInstall on DockerYou can install delegates from the Account, Project, or Org scope. In this example, we'll install a delegate in the Project scope.To install a delegate, do the following:In Harness, select your project, then select Project Settings.Under Project-level resources, select Delegates.Select Install a Delegate to open the New Delegate dialog.Under Select where you want to install your Delegate, select Docker.Under Install your Delegate, enter a Delegate Name.Copy the docker run command.docker run --cpus=1 --memory=2g \ -e DELEGATE\_NAME=docker-delegate \ -e NEXT\_GEN="true" \ -e DELEGATE\_TYPE="DOCKER" \ -e ACCOUNT\_ID=YOUR\_HARNESS\_ACCOUNTID\_ \ -e DELEGATE\_TOKEN=YOUR\_DELEGATE\_TOKEN \ -e DELEGATE\_TAGS="" \ -e MANAGER\_HOST\_AND\_PORT=YOUR\_MANAGER\_HOST\_AND\_PORT \ harness/delegate:yy.mm.vernoThe docker run command doesn't allow you to select the delegate token. You can replace the token in the command with another token if required.Steps 6 and 7 are optional when installing a delegate using the CLI flow.(Optional) Replace the YOUR\_MANAGER\_HOST\_AND\_PORT\_HERE variable with the Harness Manager Endpoint noted below. For Harness SaaS accounts, to find your Harness cluster location, select Account Settings, and then select Overview. In Account Overview, look in Account Settings. It is listed next to Harness Cluster Hosting Account.For more information, go to View account info and subscribe to downtime alerts.For Harness CDCE, the endpoint varies based on the Docker vs. Helm installation options.Run the command.

### Ephemeral Storage in Delegate Helm Charts <a href="#ephemeral-storage-in-delegate-helm-charts" id="ephemeral-storage-in-delegate-helm-charts"></a>

To manage temporary disk space efficiently, you can configure ephemeral storage for the Harness Delegate using Helm charts. This guide walks you through defining custom volumes and applying the configuration during Helm installation.

The setup is cloud-agnostic and works across providers by adjusting the storage class as needed.

1. Create a `values.yaml` file and add the following configuration to it.

   ```yaml
      custom_mounts:
      - mountPath: "/scratch"
         name: scratch-volume

      custom_volumes:
      - name: scratch-volume
         ephemeral:
            volumeClaimTemplate:
            metadata:
               labels:
                  type: <YOUR-TYPE-REFERENCE>
            spec:
               accessModes: [ "ReadWriteOnce" ]
               storageClassName: "<YOUR-STORAGE-CLASS>"
               resources:
                  requests:
                  storage: <STORAGE-SIZE>
   ```

   <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p>Before proceeding with installation, ensure a suitable StorageClass exists in your cluster. This is required for provisioning ephemeral volumes as defined in your values.yaml.</p><p>You can check the available storage classes using:</p><pre class="language-bash"><code class="lang-bash">kubectl get storageclass
   </code></pre><p>If your cluster doesn’t have a suitable <code>StorageClass</code>, you can create one using:</p><pre class="language-bash"><code class="lang-bash">kubectl apply -f storage-class.yaml
   </code></pre><p>Example <code>storage-class.yaml</code>:</p><pre class="language-yaml"><code class="lang-yaml">apiVersion: storage.k8s.io/v1
   kind: StorageClass
   metadata:
   name: &#x3C;YOUR-STORAGE-CLASS-NAME>
   provisioner: &#x3C;YOUR-STORAGE-PROVISIONER>  # e.g., kubernetes.io/aws-ebs, pd.csi.storage.gke.io
   parameters:
   type: &#x3C;YOUR-VOLUME-TYPE>               # e.g., gp2 for AWS
   reclaimPolicy: &#x3C;YOUR-RECLAIM-POLICY>     # e.g., Retain or Delete
   volumeBindingMode: WaitForFirstConsumer
   </code></pre><p>After creating the <code>StorageClass</code>, configure it in the Helm chart by setting: <code>--set persistence.storageClass=&#x3C;YOUR-STORAGE-CLASS-NAME></code></p></div>
2. Install the Helm chart using the example below, which applies the configuration from `values.yaml` file we created earlier:

   ```yaml
      helm upgrade -i <YOUR-DELEGATE-NAME> --namespace harness-delegate-ng --create-namespace \
      harness-delegate/harness-delegate-ng \
      --set delegateName=<YOUR-DELEGATE-NAME> \
      --set accountId=XXXXXXXXXXXXXXXX \
      --set delegateToken=XXXXXXXXXXXXXXXXXXXXXX \
      --set managerEndpoint=https://<YOUR-URL>.harness.io \
      --set delegateDockerImage=us-west1-docker.pkg.dev/gar-setup/docker/delegate:<DELEGATE-TAG-VERSION> \
      --set replicas=1 --set upgrader.enabled=true \
      -f values.yaml
   ```
3. Verify that the ephemeral storage has been mounted correctly by inspecting the pod’s volume mounts.

   * Get the Pod Name

     ```bash
     kubectl get pods -n harness-delegate-ng
     ```

     Output:

     ```bash
     NAME                                  READY   STATUS    RESTARTS   AGE
     delegate-ephemeral-storage            1/1     Running   0          2m
     ```
   * Describe the Pod

     ```bash
     kubectl describe pod delegate-ephemeral-storage -n harness-delegate-ng
     ```

     Look for the similar section below in your output

     ```bash
     Volumes:
     scratch-volume:
        Type:       PersistentVolumeClaim (a reference to a PVC)
        ClaimName:  scratch-volume-delegate-ephemeral-storage
        ReadOnly:   false

     Mounts:
     /scratch from scratch-volume (rw)
     ```

     This confirms that your ephemeral volume (scratch-volume) is mounted to /scratch in the pod.

   <div data-gb-custom-block data-tag="hint" data-style="warning" class="hint hint-warning"><p><strong>IMPORTANT NOTE:</strong></p><p>Ephemeral storage is automatically deleted when the pod is terminated, and a new volume is created when a new pod starts. This ensures the storage is tied to the pod’s lifecycle and is not persistent.</p></div>

### Deploy using a custom role <a href="#deploy-using-a-custom-role" id="deploy-using-a-custom-role"></a>

During delegate installation, you have the option to deploy using a custom role. To use a custom role, you must edit the delegate YAML file.

Harness supports the following custom roles:

* `cluster-admin`
* `cluster-viewer`
* `namespace-admin`
* custom cluster roles

To deploy using a custom cluster role, do the following:

1. Open the delegate YAML file in your text editor.
2. Add the custom cluster role to the `roleRef` field in the delegate YAML.

   ```yaml
   ---
   apiVersion: rbac.authorization.k8s.io/v1beta1
   kind: ClusterRoleBinding
   metadata:
     name: harness-delegate-cluster-admin
   subjects:
     - kind: ServiceAccount
       name: default
       namespace: harness-delegate-ng
   roleRef:
     kind: ClusterRole
     name: cluster-admin
     apiGroup: rbac.authorization.k8s.io
   ---
   ```

   In this example, the `cluster-admin` role is defined.
3. Save the delegate YAML file.

### Verify delegate connectivity <a href="#verify-delegate-connectivity" id="verify-delegate-connectivity"></a>

Select **Continue**. After the health checks pass, your delegate is available for you to use. Select **Done** and verify your new delegate is listed.

#### Helm chart & Terraform Helm provider <a href="#helm-chart-and-terraform-helm-provider" id="helm-chart-and-terraform-helm-provider"></a>

#### Kubernetes manifest <a href="#kubernetes-manifest" id="kubernetes-manifest"></a>

#### Docker <a href="#docker" id="docker"></a>

You can now route communication to external systems in Harness connectors and pipelines by selecting this delegate via a delegate selector.

### Troubleshooting <a href="#troubleshooting" id="troubleshooting"></a>

The delegate installer provides troubleshooting information for each installation process. If the delegate cannot be verified, select **Troubleshoot** for steps you can use to resolve the problem. This section includes the same information.

Harness asks for feedback after the troubleshooting steps. You are asked, **Did the delegate come up?**

If the steps did not resolve the problem, select **No**, and use the form to describe the issue. You'll also find links to Harness Support and to [Delegate docs](/harness-platform/use-harness-platform/delegates/delegate/delegate-concepts/delegate-overview.md).

Use the following steps to troubleshoot your installation of the delegate using Helm.Verify that Helm is correctly installed:Check for Helm:helmAnd then check for the installed version of Helm:helm versionIf you receive the message Error: rendered manifests contain a resource that already exists..., delete the existing namespace, and retry the Helm upgrade command to deploy the delegate.For further instructions on troubleshooting your Helm installation, go to Helm troubleshooting guide.Check the status of the delegate on your cluster:kubectl describe pods -n \<NAMESPACE>If the pod did not start, check the delegate logs:kubectl logs -f \<DELEGATE\_NAME> -n \<NAMESPACE>If the state of the delegate pod is CrashLoopBackOff, check your allocation of compute resources (CPU and memory) to the cluster. A state of CrashLoopBackOff indicates insufficient Kubernetes cluster resources.If the delegate pod is not healthy, use the kubectl describe command to get more information:kubectl describe \<POD\_NAME> -n \<NAMESPACE>Use the following steps to troubleshoot your installation of the delegate using Terraform.Verify that Terraform is correctly installed:terraform -versionFor further instructions on troubleshooting your installation of Terraform, go to the Terraform troubleshooting guide.Check the status of the delegate on your cluster:kubectl describe pods -n \<namespace>If the pod did not start, check the delegate logs:kubectl logs -f \<DELEGATE\_NAME> -n \<NAMESPACE>If the state of the delegate pod is CrashLoopBackOff, check your allocation of compute resources (CPU and memory) to the cluster. A state of CrashLoopBackOff indicates insufficient Kubernetes cluster resources.If the delegate pod is not healthy, use the kubectl describe command to get more information:kubectl describe \<POD\_NAME> -n \<NAMESPACE>Use the following steps to troubleshoot your installation of the delegate using Kubernetes.Check the status of the delegate on your cluster:kubectl describe pods -n \<NAMESPACE>If the pod did not start, check the delegate logs:kubectl logs -f \<DELEGATE\_NAME> -n \<NAMESPACE>If the state of the delegate pod is CrashLoopBackOff, check your allocation of compute resources (CPU and memory) to the cluster. A state of CrashLoopBackOff indicates insufficient Kubernetes cluster resources.If the delegate pod is not healthy, use the kubectl describe command to get more information:kubectl describe \<POD\_NAME> -n \<NAMESPACE>Use the following steps to troubleshoot your installation of the delegate using Docker:Check the status of the delegate on your cluster:docker container ls -aIf the pod is not running, check the delegate logs:docker container logs \<DELEGATE\_NAME> -fRestart the delegate container. To stop the container:docker container stop \<DELEGATE\_NAME>To start the container:docker container start \<DELEGATE\_NAME>Make sure the container has sufficient CPU and memory resources. If not, remove the older containers:docker container rm \[container id]

</details>

This video shows how to install a delegate.

{% embed url="<https://www.loom.com/embed/a935f18296ee4156900efcf60f20f224>" %}

The default delegate image, denoted by the `yy.mm.verno` image tag, includes a set of pre-installed 3rd-party custom binaries for convenience. For the list of these binaries, go to [Third-party tools included in the delegate image type](/harness-platform/use-harness-platform/delegates/delegate/delegate-concepts/delegate-image-types.md#third-party-tools-included-in-the-delegate-image-type). If you are concerned about the security vulnerabilities that potentially come with these pre-installed binaries, Harness recommends that you use the minimal delegate explained below.

### Install minimal delegate with 3rd party custom binaries <a href="#install-minimal-delegate-with-3rd-party-custom-binaries" id="install-minimal-delegate-with-3rd-party-custom-binaries"></a>

The minimal delegate image, denoted by the `yy.mm.verno.minimal` image tag, does not include any pre-installed 3rd-party custom binaries for ensuring the lowest footprint and hence lowest number of security vulnerabilities.

#### Use INIT\_SCRIPT <a href="#use-initscript" id="use-initscript"></a>

This option installs the 3rd party custom binaries on a delegate container instance without changing the delegate image. Below is an inline tutorial that shows you how to use this option. You can also review the tutorial directly. Go to [Install a delegate with third-party tool custom binaries](/harness-platform/use-harness-platform/delegates/delegate/install-delegates/install-a-delegate-with-3-rd-party-tool-custom-binaries.md).

<details>

<summary>Use INIT_SCRIPT</summary>

The [Harness Delegate](/harness-platform/use-harness-platform/delegates/delegate/delegate-concepts/delegate-overview.md) is a lightweight worker process that is installed on your infrastructure and communicates only via outbound HTTP/HTTPS to the Harness Platform. This enables the Harness Platform to leverage the delegate for executing the CI/CD and other tasks on your behalf, without any of your secrets leaving your network.

The default delegates are packaged with third-party SDKs that support Kubernetes, Helm, and other Harness-integrated tools. The SDKs are included on the delegate image as binary files; depending on the tool, multiple versions are included. Harness also provides a "minimal" delegate image that doesn't include third-party SDKs.

You can modify the default and minimal Harness Delegate images. You might customize the delegate image if:

* You want to use binaries that reduce your attack surface. Vulnerability scans detect unresolved vulnerabilities in older binary versions.
* You want to use tools or versions of tools that Harness doesn't include on the default delegate image. You can install all kinds of tools, such as Git client, Helm, Terraform, PowerShell, Docker, AWS CLI, and so on.
* You need to modify where certain tools run. For example, connecting to external systems usually requires a third-party client tool or library to be present locally, and some of the Harness CD and Platform tasks require these client tools to be present in the same container instance where the delegate runs.

There are two primary ways to modify the Harness Delegate image:

* Install additional client tools along with the delegate by modifying the delegate YAML to install the tools and versions that you specify in the `INIT_SCRIPT` environment variable. This approach works best when you are still building your CI/CD pipelines and you don't yet have the final list of required client tools. This approach is explained in this topic.
* Create a custom delegate image (using the Harness-provided delegate image as a base image). This approach works best when you know all the client tools ahead of time. For instructions on building custom delegate images, go to [Build custom delegate images with third-party tools](/harness-platform/use-harness-platform/delegates/delegate/install-delegates/build-custom-delegate-images-with-third-party-tools.md).

{% hint style="info" %}
**NOTE**

You might need additional permissions to execute commands in delegate scripts and create Harness users.
{% endhint %}

### Edit the delegate YAML <a href="#edit-the-delegate-yaml" id="edit-the-delegate-yaml"></a>

To install a delegate, you download its YAML file and run it in your target environment, such as a Kubernetes cluster. For example purposes, this topic uses a delegate installed on a Kubernetes cluster created on Google Cloud.

To modify the delegate image, you need to edit the delegate YAML file to specify delegate environment variables, the delegate base image, [Harness-required SDKs](#add-harness-required-sdks) (depending on the selected base image), and [third-party tools to install](#add-your-custom-tools).

You can modify the delegate YAML before or after you install the delegate. To get the delegate YAML, follow the steps to [Install a delegate](/harness-platform/troubleshooting-and-resources/tutorials/install-delegate.md). To follow along with the examples in this topic, use the **Kubernetes Manifest** option for delegate installation.

Since the delegate is declaratively defined in YAML, it is easy to add custom scripts and customize the delegate in other ways too. SDKs and additional tools are specified in the `INIT_SCRIPT`, with the exception of [delegate Helm chart deployments](#delegate-helm-chart-deployments). For more examples, go to [Common delegate initialization scripts](/harness-platform/use-harness-platform/delegates/delegate/delegate-reference/common-delegate-profile-scripts.md).

#### Delegate Helm chart deployments <a href="#delegate-helm-chart-deployments" id="delegate-helm-chart-deployments"></a>

For delegate Helm chart deployments, add your third-party tool custom binaries to `initScript` in your `values.yaml` file to run them before delegate installation. You can find the default `values.yaml` file in the Delegate Helm chart [GitHub repo](https://github.com/harness/delegate-helm-chart/blob/main/harness-delegate-ng/values.yaml).

For example, the following `values.yaml` file entry installs Kubectl on amd64 architecture. The exact install URL depends on your architecture. For additional architecture installation commands, go to the Kubernetes documentation on [Installing kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl).

```yaml
# Script to run before delegate installation <a href="#script-to-run-before-delegate-installation" id="script-to-run-before-delegate-installation"></a>
initScript: "
            curl -L0 https://dl.k8s.io/release/v1.24.3/bin/linux/amd64/kubectl -o kubectl
            chmod +x ./kubectl
            mv kubectl /usr/local/bin/"
```

### Add Harness-required SDKs <a href="#add-harness-required-sdks" id="add-harness-required-sdks"></a>

The toolset you install on the delegate minimal image must include the SDKs that Harness requires to perform tasks.

In the delegate container `spec`, use the `INIT_SCRIPT` environment variable to download the certified SDK versions that Harness requires.

The SDKs you need to add depend on the type of deployment. For a list of SDK versions certified for different deployment types, go to [Delegate-required SDKs](/harness-platform/use-harness-platform/delegates/delegate/delegate-reference/delegate-required-sdks.md).

#### Private Cloud Foundry (PCF) deployments <a href="#private-cloud-foundry-pcf-deployments" id="private-cloud-foundry-pcf-deployments"></a>

PCF deployments require CLI 7. For installation instructions, go to [Install Cloud Foundry CLI versions on the Harness Delegate](https://developer.harness.io/harness-platform/use-harness-platform/delegates/delegate/install-delegates/pages/nMTQVskX4BjgZapkkE5B#cloud-foundry-cli).

### Add your custom tools <a href="#add-your-custom-tools" id="add-your-custom-tools"></a>

Open the delegate YAML file and locate the `INIT_SCRIPT` in the delegate container `spec`. To install additional tools on the delegate, add your custom scripts to the `INIT_SCRIPT`.

{% hint style="info" %}
**IMPORTANT**

Several tools require `unzip` in the manifest. Add the following YAML before you add any of the below scripts.

```yaml
  - name: INIT_SCRIPT
    value: |
        microdnf install -y zip unzip
```

{% endhint %}

These examples show how to install some common tools.

The following INIT\_SCRIPT installs the AWS CLI: - name: INIT\_SCRIPT value: | microdnf install -y zip unzip curl "<https://awscli.amazonaws.com/awscli-exe-linux-x86\\_64.zip>" -o "awscliv2.zip" unzip awscliv2.zip ./aws/installThe following INIT\_SCRIPT installs kubectl: - name: INIT\_SCRIPT value: | curl -L0 <https://dl.k8s.io/release/v1.24.3/bin/linux/amd64/kubectl> -o kubectl chmod +x ./kubectl mv kubectl /opt/harness-delegate/custom-client-tools/kubectlThe following INIT\_SCRIPT installs Terraform: - name: INIT\_SCRIPT value: | microdnf install -y zip unzip curl -O -L <https://releases.hashicorp.com/terraform/0.12.25/terraform\\_0.12.25\\_linux\\_amd64.zip> unzip terraform\_0.12.25\_linux\_amd64.zip mv ./terraform /usr/bin/The following INIT\_SCRIPT installs Helm 3: - name: INIT\_SCRIPT value: | curl -fsSL -o get\_helm.sh <https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3> chmod 700 get\_helm.sh ./get\_helm.sh

#### Install Azure CLI <a href="#install-azure-cli" id="install-azure-cli"></a>

To install the Azure CLI, run the following.

```
## Install Azure CLI <a href="#install-azure-cli" id="install-azure-cli"></a>
rpm --import <https://packages.microsoft.com/keys/microsoft.asc>
rpm -ivh <https://packages.microsoft.com/config/rhel/8/packages-microsoft-prod.rpm>
microdnf install -y azure-cli
```

#### Install multiple tools at once <a href="#install-multiple-tools-at-once" id="install-multiple-tools-at-once"></a>

To install multiple tools, you can add all the install scripts to the `INIT_SCRIPT`, for example:

```yaml
  - name: INIT_SCRIPT
    value: |
        microdnf install -y zip unzip
        ## Install AWS CLI
        curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
        unzip awscliv2.zip
        ./aws/install

        ## Install kubectl
        curl -L0 https://dl.k8s.io/release/v1.24.3/bin/linux/amd64/kubectl -o kubectl
        chmod +x ./kubectl
        mv kubectl /opt/harness-delegate/custom-client-tools/kubectl

        ## Install Terraform
        curl -O -L  https://releases.hashicorp.com/terraform/0.12.25/terraform_0.12.25_linux_amd64.zip
        unzip terraform_0.12.25_linux_amd64.zip
        mv ./terraform /usr/bin/

        ## Install Helm3
        curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
        chmod 700 get_helm.sh
        ./get_helm.sh
```

#### Install credentials plugin for GKE and AKS infrastructure types <a href="#install-credentials-plugin-for-gke-and-aks-infrastructure-types" id="install-credentials-plugin-for-gke-and-aks-infrastructure-types"></a>

Add the following install scripts to the `INIT_SCRIPT` to install the credentials plugin for GKE and AKS infrastructure types if you're using `kubectl` version 1.26.x or later.

{% hint style="info" %}
If you're using a custom delegate with `kubelogin` and certificate type of authentication, then you must install Azure CLI. Alternatively, you can install the `harness-credentials-plugin` to take care of this flow without Azure CLI.
{% endhint %}

```yaml
  - name: INIT_SCRIPT
    value: |

        ## for AKS
        mkdir -m 777 -p client-tools/kubelogin/v0.1.1 \
        && curl -s -L -o client-tools/kubelogin/v0.1.1/kubelogin https://app.harness.io/public/shared/tools/kubelogin/release/v0.1.1/bin/linux/amd64/kubelogin
        export PATH=/opt/harness-delegate/client-tools/kubelogin/v0.1.1/:$PATH

        ## for GKE or AKS with certificate auth type
        mkdir -m 777 -p client-tools/harness-credentials-plugin/v0.1.0 \
        && curl -s -L -o client-tools/harness-credentials-plugin/v0.1.0/harness-credentials-plugin https://app.harness.io/public/shared/tools/harness-credentials-plugin/release/v0.1.0/bin/linux/amd64/harness-credentials-plugin 
        export PATH=/opt/harness-delegate/client-tools/harness-credentials-plugin/v0.1.0/:$PATH
```

### Apply the changes <a href="#apply-the-changes" id="apply-the-changes"></a>

You can modify the delegate YAML before or after you install the delegate.

If you haven't yet installed the delegate, finish [Installing the delegate](/harness-platform/troubleshooting-and-resources/tutorials/install-delegate.md) in your target environment.

If you already installed the delegate, you need to apply the updated delegate YAML and restart the delegate. For example, if your delegate is in a Kubernetes cluster, run the kubectl command to apply it:

```
kubectl apply -f harness-delegate.yml
```

Wait a few minutes for the delegate to start up. You can check the delegate status in the Harness Platform.

![List of delegates and their status.](/files/tcXqRHjjZJs2emPN8t1k)

### Test your tools <a href="#test-your-tools" id="test-your-tools"></a>

You can either run an existing pipeline that requires one of the tools you installed, or create a test pipeline with a simple script to confirm that a tool was installed.

1. Create a pipeline and add a **Custom** stage.
2. Add a **Shell Script** step.
3. Enter a simple script, such as a version check, for the tool that you installed.

   For example, if you installed the Git client, you could run `git --version`, or if you installed the AWS CLI, you could run `aws --version`.

   ![Shell Script step with the git version command.](/files/32M5UfCn7lYgIForDtqx)

   You can modify this step to test any command for the tool. For example, if you installed Helm, you could run a test to deploy a Helm chart:

   ```
   helm create my-new-chart
   helm install my-new-chart ./my-new-chart
   helm ls
   ```
4. Set the **Execution Target** to **On Delegate**.
5. On the **Advanced** tab, select the delegate you just modified.

   ![Selecting the delegate for the Shell Script step.](/files/TOYc2rWAA7XfTKxAHKOj)
6. Save and run the pipeline. If the tool was installed on the delegate successfully, you should see the output of your script in the execution logs.

   ![Git command execution logs.](/files/AHxQuZF9OnxLLMbGbbV0)

</details>

#### Build a custom image <a href="#build-a-custom-image" id="build-a-custom-image"></a>

This option installs the 3rd party custom binaries on a new custom delegate image that uses the Harness minimal delegate image as its base image. Below is an inline tutorial that shows you how to use this option. You can also review the tutorial directly. Go to [Build custom delegate images with third-party tools](/harness-platform/use-harness-platform/delegates/delegate/install-delegates/build-custom-delegate-images-with-third-party-tools.md).

<details>

<summary>Build a custom image</summary>

Harness Manager installs and configures delegates with the binaries that most CI/CD pipelines require. In some cases, however, a preconfigured image isn't the right fit. For example, preconfigured images can:

* Introduce the vulnerabilities of the binaries they include.
* Restrict you to the use of the included third-party tools and versions.

This document explains how you can:

* Build and host a custom delegate image that includes the tools you select.
* Use your custom delegate in CI/CD pipelines.

{% hint style="info" %}
Delegates with an immutable image type (image tag `yy.mm.xxxxx`) include non-root user privileges and are compatible with OpenShift. For information on delegate types, go to [Delegate image types](/harness-platform/use-harness-platform/delegates/delegate/delegate-concepts/delegate-image-types.md).
{% endhint %}

### About the Harness Delegate minimal image <a href="#about-the-harness-delegate-minimal-image" id="about-the-harness-delegate-minimal-image"></a>

Harness recommends that you use the Harness Delegate minimal image (*`yy.mm.xxxxx.minimal`*) when you set up the Harness Platform for production use. This image has been thoroughly scanned and is free of any high or critical vulnerabilities. Users focused on security tend to prefer this option.

However, the minimal delegate image lacks some binaries that are required for Continuous Delivery (CD) steps to function properly and remain vulnerability-free from third-party tools. Consequently, using the minimal delegate image requires you to configure your delegates and install necessary binaries. For information on delegate types, go to [Delegate image types](/harness-platform/use-harness-platform/delegates/delegate/delegate-concepts/delegate-image-types.md).

The Harness Delegate minimal image (*`yy.mm.xxxxx.minimal`*) is a lighter, more secure version of the default Harness Delegate image. Its main purpose is to provide an enhanced security profile for users, especially those who prioritize their systems' security. The Harness Delegate minimal images includes the following features.

* **Security Scanned:** The image undergoes rigorous scanning processes to ensure that it is devoid of any high-risk or critical vulnerabilities. This makes it an optimal choice for organizations or users who have stringent security requirements. Harness aims to minimize critical/high vulnerabilities within this image. Achieving complete mitigation isn't always possible due to the continual discovery of vulnerabilities in third-party libraries/tools without immediate remediation.
* **Limited Binaries:** Unlike the standard delegate, the minimal image does not include all of the default binaries. While this contributes to its lightweight nature and security, it also means that users have additional responsibilities. They must manually configure and add any necessary binaries to make their setup functional.
* **User Responsibilities:** Because the minimal delegate image is devoid of the default binaries, users are in charge of tailoring it to their needs. This includes installing specific binaries essential for their CD steps. This level of control also allows users to maintain an updated environment. By installing the latest versions of necessary binaries, they can ensure that the delegate remains free from potential vulnerabilities found in outdated third-party tools.
* **Preferred by Security-Conscious Users:** Due to its clean security slate, many users who prioritize system security gravitate towards the minimal delegate image. By starting with a minimal setup and adding only what is necessary, they can maintain a tighter control over the software and tools present, thus minimizing potential security risks.

### Use the delegate minimal image to create a custom delegate image <a href="#use-the-delegate-minimal-image-to-create-a-custom-delegate-image" id="use-the-delegate-minimal-image-to-create-a-custom-delegate-image"></a>

#### Select the delegate minimal image <a href="#select-the-delegate-minimal-image" id="select-the-delegate-minimal-image"></a>

You can build on either of the following Harness-provided images.

| **Image**                             | **Description**                                                                                          |
| ------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| Harness Delegate Docker image         | A publicly available Docker image providing Harness Delegate.                                            |
| Harness Minimal Delegate Docker image | A minimal delegate image is available in Docker Hub at <https://hub.docker.com/r/harness/delegate/tags>. |

Use the last published `yy.mm.xxxxx` version of the minimal image from the Docker repository.

![](/files/sXdjCtWylqLenfpl8nUU)

#### Build the delegate image <a href="#build-the-delegate-image" id="build-the-delegate-image"></a>

When you build a custom delegate image, you modify the image you select with user privileges and binaries. This section explains the build script used for the process. In this example, the script builds a custom image for deployment by Kubernetes and by Terraform.

The first lines of the script provide information about the base image and user privileges. This example uses the minimal image with delegate minor version 77029.

```
FROM harness/delegate:24.04.82804.minimal
USER root
```

The delegate container is granted root user privileges.

The first `RUN` block installs or updates the `unzip` and `yum-utils` tools. The `--nodocs` option prevents the installation of documentation on the image.

```
RUN microdnf update \
  && microdnf install --nodocs \
    unzip \
    yum-utils
```

The second `RUN` block uses the `yum` utility to create a configuration file for the HashiCorp repository, and then uses the `microdnf` package manager to install the required Terraform components:

```
RUN yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo \
  && microdnf install -y terraform
```

The final `RUN` block retrieves the Kubernetes `kubectl` command-line tool that is required to manipulate clusters. The Linux `chmod +x` instruction makes the utility executable:

```
RUN mkdir /opt/harness-delegate/tools && cd /opt/harness-delegate/tools \
  && curl -LO "https://dl.k8s.io/release/$(curl> -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" && chmod +x kubectl
```

The `ENV` instruction defines the Linux `$PATH` environment variable that provides the location of the tools to be installed:

```
ENV PATH=/opt/harness-delegate/tools/:$PATH
```

The final instruction switches the user back to `harness` to ensure the custom image does not run as root:

```
USER harness
```

The complete script is as follows:

```
FROM harness/delegate:24.04.82804.minimal
USER root

RUN microdnf update \
  && microdnf install --nodocs \
    unzip \
    yum-utils

RUN yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo \
  && microdnf install -y terraform

RUN mkdir /opt/harness-delegate/tools && cd /opt/harness-delegate/tools \
  && curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" && chmod +x kubectl

ENV PATH=/opt/harness-delegate/tools/:$PATH

USER harness
```

The following example Dockerfile adds all the tools necessary for the Harness platform that are not part of the base image to the minimal delegate. You can remove tools for features you don't use or update versions for your requirements.

#### Upload the image to Docker Hub <a href="#upload-the-image-to-docker-hub" id="upload-the-image-to-docker-hub"></a>

The next step is to upload your custom image to Docker Hub. For information on working with Docker repositories, go to [Manage repositories](https://docs.docker.com/docker-hub/repos/) in the Docker documentation.

#### Modify the delegate manifest <a href="#modify-the-delegate-manifest" id="modify-the-delegate-manifest"></a>

Before you can deploy a delegate, you must:

* Update the image path to the repository location of the custom image.
* Suspend delegate auto-upgrade functionality.

Delegate auto-upgrade is not compatible with custom images.

**Upgrade the image path**

Open the delegate manifest file and locate the container `spec` (`spec.containers`). Change the image path to reflect the repository location of your uploaded image as shown in the following YAML.

```yaml
 spec:
     terminationGracePeriodSeconds: 600
     restartPolicy: Always
     containers:
     - image: example/org:custom-delegate
       imagePullPolicy: Always
       name: delegate
       securityContext:
         allowPrivilegeEscalation: false
         runAsUser: 0
```

For purposes of this example, the image was uploaded to `example/org:custom-delegate`.

**Suspend delegate auto-upgrade**

Before you deploy a custom delegate, you must suspend its auto-upgrade functionality. This step prevents your image from being automatically upgraded and the installed binaries removed.

To suspend auto-upgrade, in the delegate manifest, locate the `CronJob` resource. In the resource `spec`, set the `suspend` field to `true` as shown in the following YAML:

```yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
 labels:
   harness.io/name: custom-del-upgrader-job
 name: custom-del-upgrader-job
 namespace: harness-delegate-ng
spec:
 suspend: true
 schedule: "0 */1 * * *"
 concurrencyPolicy: Forbid
 startingDeadlineSeconds: 20
```

#### Deploy the delegate <a href="#deploy-the-delegate" id="deploy-the-delegate"></a>

You can deploy the delegate from Harness Manager or by applying the modified delegate manifest file to your cluster.

![](/files/uTwPTLZBk8MFXLgVyHhs)

You can confirm the successful deployment and registration of the delegate in Harness Manager. Check the delegate information to ensure that auto-upgrade is not enabled.

### Use your custom delegate image in pipelines <a href="#use-your-custom-delegate-image-in-pipelines" id="use-your-custom-delegate-image-in-pipelines"></a>

You can use your registered delegate to run Kubernetes and Terraform pipelines. It is a good idea to run a pipeline to validate the delegate image. Harness steps in your pipelines use the installed tooling on the delegate to perform builds or deployments.

For information about creating a Kubernetes pipeline, go to [Kubernetes deployment tutorial](/continuous-delivery/use-continuous-delivery/deploy-services-on-different-platforms/kubernetes/kubernetes-cd-quickstart.md).

For information about creating a Terraform Plan, go to [Provision with the Terraform Apply Step](/continuous-delivery/use-continuous-delivery/provision-infrastructure/terraform-infra/run-a-terraform-plan-with-the-terraform-apply-step.md).

</details>

### Configure options <a href="#configure-options" id="configure-options"></a>

#### Network proxy <a href="#network-proxy" id="network-proxy"></a>

For network proxy details, go to [Configure delegate proxy settings](/harness-platform/use-harness-platform/delegates/delegate/manage-delegates/configure-delegate-proxy-settings.md).

#### CI-specific variables <a href="#ci-specific-variables" id="ci-specific-variables"></a>

Delegate variables specific to CI are described where necessary, such as in [Set up a local runner build infrastructure](/continuous-integration/use-harness-ci/use-harness-ci/set-up-build-infrastructure/define-a-docker-build-infrastructure.md) and [Set up VM build infrastructures](/continuous-integration/use-harness-ci/use-harness-ci/set-up-build-infrastructure/vm-build-infrastructure.md).

#### Custom certificates <a href="#custom-certificates" id="custom-certificates"></a>

For custom certificates, go to [Install delegates with custom certificates](/harness-platform/use-harness-platform/delegates/delegate/secure-delegates/install-delegates-with-custom-certs.md).

#### Group names <a href="#group-names" id="group-names"></a>

The legacy delegate used `DELEGATE_GROUP_NAME` for group names. This environment is not valid in NextGen. Use `DELEGATE_NAME` for group names.

### Additional installation approaches <a href="#additional-installation-approaches" id="additional-installation-approaches"></a>

#### Install Docker delegate to Amazon ECS Fargate <a href="#install-docker-delegate-to-amazon-ecs-fargate" id="install-docker-delegate-to-amazon-ecs-fargate"></a>

You can install the Docker delegate into Amazon ECS Fargate. For more information, go to [Deploy a Docker delegate to Amazon ECS or AWS Fargate](/harness-platform/use-harness-platform/delegates/delegate/install-delegates/docker-delegate-to-ecs-fargate.md).

#### Install Docker delegate using Podman <a href="#install-docker-delegate-using-podman" id="install-docker-delegate-using-podman"></a>

You can install the Docker delegate using Podman by adding Podman commands to your Dockerfile.

To install the Docker delegate using Podman, do the following:

1. In Harness, select **Deployments**, then select your project.
2. Under **Project Setup**, select **Delegates**.
3. Select **Install a Delegate** to open the **New Delegate** dialog.

   ![](/files/a0qv0ulyv0pWKxKCfSL1)
4. Under **Select where you want to install your Delegate**, select **Docker**.
5. Copy the Docker installation command.
6. Paste the Docker installation command from the UI in your CLI, and replace the `docker run` command with the `podman run` command below.

   ```bash
   podman run --restart=always --hostname="$(hostname -f)"
   -e DELEGATE_NAME=docker-delegate \
   -e NEXT_GEN="true" \
   -e DELEGATE_TYPE="DOCKER" \
   -e ACCOUNT_ID=<ACCOUNT_ID_COPIED_FROM_THE_UI_COMMAND> \
   -e DELEGATE_TOKEN=<DELEGATE_TOKEN_COPIED_FROM_THE_UI_COMMAND>= \
   -e MANAGER_HOST_AND_PORT=https://app.harness.io harness/delegate:yy.mm.verno
   ```
7. Run the command.
