# Change an Admin Console password
When you install for the first time with Replicated kURL, the Replicated KOTS Admin Console is secured with a single shared password that is set automatically for all users. Replicated recommends that you change this to a new, unique password for security purposes as this automated password is displayed to the user in plain text.
The Admin Console password is salted and one-way hashed using bcrypt. The irreversible hash is stored in a Secret named `kotsadm-password`. The password is not retrievable if lost. If you lose your Admin Console password, reset your password to access the Admin Console.
For more information about bcrypt, see [bcrypt](https://en.wikipedia.org/wiki/Bcrypt) on Wikipedia.
To change your Admin Console password:
1. Log in to the Admin Console using your current password.
1. In the drop-down in the top right of any page, click **Change password**.
1. In the Change Admin Console Password dialog, edit the fields.
- The new password must be at least 6 characters and must not be the same as your current password.
- The **New Password** and **Confirm New Password** fields must match each other.
1. Click **Change Password**.
If there are any issues with changing the password, an error message displays the specific problem.
When the password change succeeds, the current session closes and you are redirected to the Log In page.
1. Log in with the new password.
:::note
Replicated KOTS is available only for existing customers. For supporting installations into customer managed clusters, we recommend Helm. For more information, see [About Helm Installations with Replicated](/vendor/helm-install-overview).
KOTS is a Generally Available (GA) product for existing customers. For more information about the Replicated product lifecycle phases, see [Support Lifecycle Policy](/vendor/policies-support-lifecycle).
:::
---
# Add nodes to kURL clusters
:::note
Replicated kURL is available only for existing customers. If you are not an existing kURL user, use Replicated Embedded Cluster instead. For more information, see [Use Embedded Cluster](/embedded-cluster/v3/embedded-overview).
kURL is a Generally Available (GA) product for existing customers. For more information about the Replicated product lifecycle phases, see [Support Lifecycle Policy](/vendor/policies-support-lifecycle).
:::
This topic describes how to add primary and secondary nodes to a Replicated kURL cluster.
## Overview
You can generate commands in the Replicated KOTS Admin Console to join additional primary and secondary nodes to kURL clusters. Primary nodes run services that control the cluster. Secondary nodes run services that control the pods that host the application containers. Adding nodes can help manage resources to ensure that the application runs smoothly.
For high availability clusters, Kubernetes recommends using at least three primary nodes, and that you use an odd number of nodes to help with leader selection if machine or zone failure occurs. For more information, see [Creating Highly Available Clusters with kubeadm](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/high-availability/) in the Kubernetes documentation.
## Join primary and secondary nodes
You can join primary and secondary nodes on the Admin Console **Cluster management** page.
To add primary and secondary nodes:
1. (Air Gap Only) For air gapped environments, download and extract the `.tar.gz` bundle on the remote node before running the join command.
1. In the Admin Console, click **Cluster Management > Add a node**.
1. Copy the command that displays in the text box and run it on the node that you are joining to the cluster.

[View a larger image](/images/join-node.png)
---
# Delete the Admin Console and remove applications
This topic describes how to remove installed applications and delete the Replicated KOTS Admin Console. The information in this topic applies to existing cluster installations with KOTS.
:::note
Replicated KOTS is available only for existing customers. For supporting installations into customer managed clusters, we recommend Helm. For more information, see [About Helm Installations with Replicated](/vendor/helm-install-overview).
KOTS is a Generally Available (GA) product for existing customers. For more information about the Replicated product lifecycle phases, see [Support Lifecycle Policy](/vendor/policies-support-lifecycle).
:::
## Remove an application
The Replicated KOTS CLI `kots remove` command removes the reference to an installed application from the Admin Console. When you use `kots remove`, the Admin Console no longer manages the application because the record of that application’s installation is removed. This means that you can no longer manage the application through the Admin Console or through the KOTS CLI.
By default, `kots remove` does not delete any of the installed Kubernetes resources for the application from the cluster. To remove both the reference to an application from the Admin Console and remove any resources for the application from the cluster, you can run `kots remove` with the `--undeploy` flag.
It can be useful to remove only the reference to an application from the Admin Console if you want to reinstall the application, but you do not want to recreate the namespace or other Kubernetes resources. For example, if you installed an application using an incorrect license file and need to reinstall with the correct license.
To remove an application:
1. Run the following command to list the installed applications for a namespace:
```
kubectl kots get apps -n NAMESPACE
```
Replace `NAMESPACE` with the name of the namespace where the Admin Console is installed.
In the output of this command, note the slug for the application that you want to remove.
1. Run _one_ of the following commands:
* Remove only the reference to the application from the Admin Console:
```
kubectl kots remove APP_SLUG -n NAMESPACE
```
Replace:
* `APP_SLUG` with the slug for the application that you want to remove.
* `NAMESPACE` with the name of the namespace where the Admin Console is installed.
* Remove the reference to the application from the Admin Console and remove its resources from the cluster:
```
kubectl kots remove APP_SLUG -n NAMESPACE --undeploy
```
:::note
Optionally, use the `--force` flag to remove the application reference from the Admin Console when the application has already been deployed. The `--force` flag is implied when `--undeploy` is used. For more information, see [remove](/reference/kots-cli-remove) in _KOTS CLI_.
:::
## Delete the Admin Console
When you install an application, KOTS creates the Kubernetes resources for the Admin Console itself on the cluster. The Admin Console includes Deployments and Services, Secrets, and other resources such as StatefulSets and PersistentVolumeClaims.
By default, KOTS also creates Kubernetes ClusterRole and ClusterRoleBinding resources that grant permissions to the Admin Console on the cluster level. These `kotsadm-role` and `kotsadm-rolebinding` resources are managed outside of the namespace where the Admin Console is installed. Alternatively, when the Admin Console is installed with namespace-scoped access, KOTS creates Role and RoleBinding resources inside the namespace where the Admin Console is installed.
In existing cluster installations, if the Admin Console is not installed in the `default` namespace, then you delete the Admin Console by deleting the namespace where it is installed.
If you installed the Admin Console with namespace-scoped access, then the Admin Console Role and RoleBinding RBAC resources are also deleted when you delete the namespace. Alternatively, if you installed with the default cluster-scoped access, then you manually delete the Admin Console ClusterRole and ClusterRoleBindings resources from the cluster. For more information, see [supportMinimalRBACPrivileges](/reference/custom-resource-application#supportminimalrbacprivileges) and [requireMinimalRBACPrivileges](/reference/custom-resource-application#requireminimalrbacprivileges) in _Application_.
For more information about installing with cluster- or namespace-scoped access, see [RBAC Requirements](/enterprise/installing-general-requirements#rbac-requirements) in _Installation Requirements_.
To completely delete the Admin Console from an existing cluster:
1. Run the following command to delete the namespace where the Admin Console is installed:
:::important
This command deletes everything inside the specified namespace, including the Admin Console Role and RoleBinding resources if you installed with namespace-scoped access.
:::
```
kubectl delete ns NAMESPACE
```
Replace `NAMESPACE` with the name of the namespace where the Admin Console is installed.
:::note
You cannot delete the `default` namespace.
:::
1. (Cluster-scoped Access Only) If you installed the Admin Console with the default cluster-scoped access, run the following commands to delete the Admin Console ClusterRole and ClusterRoleBinding from the cluster:
```
kubectl delete clusterrole kotsadm-role
```
```
kubectl delete clusterrolebinding kotsadm-rolebinding
```
1. (Optional) To uninstall the KOTS CLI, see [Uninstall](https://docs.replicated.com/reference/kots-cli-getting-started#uninstall) in _Installing the KOTS CLI_.
---
# Work with the kURL image registry
:::note
Replicated kURL is available only for existing customers. If you are not an existing kURL user, use Replicated Embedded Cluster instead. For more information, see [Use Embedded Cluster](/embedded-cluster/v3/embedded-overview).
kURL is a Generally Available (GA) product for existing customers. For more information about the Replicated product lifecycle phases, see [Support Lifecycle Policy](/vendor/policies-support-lifecycle).
:::
This topic describes the Replicated kURL registry for kURL clusters.
## Overview
The kURL Registry add-on can be used to host application images. For air gap installations, this kURL registry is automatically used to host all application images.
With every application update, new images are pushed to the kURL registry.
To keep the registry from running out of storage, images that are no longer used are automatically deleted from the registry.
For more information about the kURL Registry add-on, see [Registry Add-On](https://kurl.sh/docs/add-ons/registry) in the kURL documentation.
:::note
Users can also configure their own private registry for kURL installations instead of using the kURL registry. For more information, see [Configure Local Image Registries](/enterprise/image-registry-settings).
:::
## Trigger garbage collection
Every time the application instance is upgraded, image garbage collection automatically deletes images that are no longer used.
You can also manually trigger image garbage collection. To manually run garbage collection:
```bash
kubectl kots admin-console garbage-collect-images -n NAMESPACE
```
Where `NAMESPACE` is the namespace where the application is installed.
For more information, see [admin-console garbage-collect-images](/reference/kots-cli-admin-console-garbage-collect-images/).
## Disable image garbage collection
Image garbage collection is enabled by default for kURL clusters that use the kURL registry.
To disable image garbage collection:
```bash
kubectl patch configmaps kotsadm-confg --type merge -p "{\"data\":{\"enable-image-deletion\":\"false\"}}"
```
To enable garbage collection again:
```bash
kubectl patch configmaps kotsadm-confg --type merge -p "{\"data\":{\"enable-image-deletion\":\"true\"}}"
```
## Restore deleted images
Deleted images can be reloaded from air gap bundles using the `admin-console push-images` command. For more information, see [admin-console push-images](/reference/kots-cli-admin-console-push-images/) in the KOTS CLI documentation.
The registry address and namespace can be found on the **Registry Settings** page in the Replicated KOTS Admin Console.
The registry username and password can be found in the `registry-creds` secret in the default namespace.
## Limitations
The kURL registry image garbage collection feature has following limitations:
* **Optional components**: Some applications define Kubernetes resources that can be enabled or disabled dynamically. For example, template functions can be used to conditionally deploy a StatefulSet based on configuration from the user.
If a resource is disabled and no longer deployed, its images can be included in the garbage collection.
To prevent this from happening, include the optional images in the `additionalImages` list of the Application custom resource. For more information, see [`additionalImages`](/reference/custom-resource-application#additionalimages) in _Application_.
* **Shared Image Registries**: The image garbage collection process assumes that the registry is not shared with any other instances of Replicated KOTS, nor shared with any external applications. If the built-in kURL registry is used by another external application, disable garbage collection to prevent image loss.
* **Customer-Supplied Registries**: Image garbage collection is supported only when used with the built-in kURL registry. If the KOTS instance is configured to use a different registry, disable garbage collection to prevent image loss. For more information about configuring an image registry in the Admin Console, see [Configure Local Image Registries](/enterprise/image-registry-settings).
* **Application Rollbacks**: Image garbage collection has no effect when the `allowRollback` field in the Replicated Application custom resource is set to `true`. For more information, see [Application](/reference/custom-resource-application).
---
# Avoid Docker Hub rate limits
This topic describes how to avoid rate limiting for anonymous and free authenticated use of Docker Hub by providing a Docker Hub username and password to the `kots docker ensure-secret` command.
:::note
Replicated KOTS is available only for existing customers. For supporting installations into customer managed clusters, we recommend Helm. For more information, see [About Helm Installations with Replicated](/vendor/helm-install-overview).
KOTS is a Generally Available (GA) product for existing customers. For more information about the Replicated product lifecycle phases, see [Support Lifecycle Policy](/vendor/policies-support-lifecycle).
:::
## Overview
On November 20, 2020, rate limits for anonymous and free authenticated use of Docker Hub went into effect.
Anonymous and Free Docker Hub users are limited to 100 and 200 container image pull requests per six hours, respectively.
Docker Pro and Docker Team accounts continue to have unlimited access to pull container images from Docker Hub.
For more information on rate limits, see [Understanding Docker Hub rate limiting](https://www.docker.com/increase-rate-limits) on the Docker website.
If the application that you are installing or upgrading has public Docker Hub images that are rate limited, then an error occurs when the rate limit is reached.
## Provide Docker Hub credentials
To avoid errors caused by reaching the Docker Hub rate limit, a Docker Hub username and password can be passed to the `kots docker ensure-secret` command. The Docker Hub username and password are used only to increase rate limits and do not need access to any private repositories on Docker Hub.
Example:
```bash
kubectl kots docker ensure-secret --dockerhub-username sentrypro --dockerhub-password password --namespace sentry-pro
```
The `kots docker ensure-secret` command creates an image pull secret that KOTS can use when pulling images.
KOTS then creates a new release sequence for the application to apply the image pull secret to all Kubernetes manifests that have images. After running the `kots docker ensure-secret` command, deploy this new release sequence either from the Admin Console or the KOTS CLI.
For more information, see [docker ensure-secret](/reference/kots-cli-docker-ensure-secret) in the KOTS CLI documentation.
---
# Configure local image registries
This topic describes how to configure private registry settings in the Replicated KOTS Admin Console.
The information in this topic applies to existing cluster installations with KOTS and installations with Replicated kURL. This topic does _not_ apply to Replicated Embedded Cluster installations.
:::note
Replicated KOTS is available only for existing customers. For supporting installations into customer managed clusters, we recommend Helm. For more information, see [About Helm Installations with Replicated](/vendor/helm-install-overview).
KOTS is a Generally Available (GA) product for existing customers. For more information about the Replicated product lifecycle phases, see [Support Lifecycle Policy](/vendor/policies-support-lifecycle).
:::
## Overview
Using a private registry lets you create a custom image pipeline. Any proprietary configurations that you make to the application are shared only with the groups that you allow access, such as your team or organization. You also have control over the storage location, logging messages, load balancing requests, and other configuration options. Private registries can be used with online or air gap clusters.
## Requirement
The domain of the image registry must support a Docker V2 protocol. KOTS has been tested for compatibility with the following registries:
- Docker Hub
:::note
To avoid the November 20, 2020 Docker Hub rate limits, use the `kots docker ensure-secret` CLI command. For more information, see [Avoiding Docker Hub Rate Limits](image-registry-rate-limits).
:::
- Quay
- Amazon Elastic Container Registry (ECR)
- Google Container Registry (GCR)
- Azure Container Registry (ACR)
- Harbor
- Sonatype Nexus
## Configure local private registries in online clusters
In online (internet-connected) installations, you can optionally use a local private image registry. You can also disable the connection or remove the registry settings if needed.
To configure private registry settings in an online cluster:
1. In the Admin Console, on the **Registry settings** tab, edit the fields:
[View a larger version of this image](/images/registry-settings.png)
The following table describes the fields:
| Field | Description |
|---|---|
| Hostname | Specify a registry domain that uses the Docker V2 protocol. |
| Username | Specify the username for the domain. |
| Password | Specify the password for the domain. |
| Registry Namespace | Specify the registry namespace. The registry namespace is the path between the registry and the image name. For example, `my.registry.com/namespace/image:tag`. For air gap environments, this setting overwrites the registry namespace where images where pushed when KOTS was installed. |
| Disable Pushing Images to Registry | (Optional) Select this option to disable KOTS from pushing images. Make sure that an external process is configured to push images to your registry instead. Your images are still read from your registry when the application is deployed. |
| Field | Description |
|---|---|
| Hostname | Specify a registry domain that uses the Docker V2 protocol. |
| Username | Specify the username for the domain. |
| Password | Specify the password for the domain. |
| Registry Namespace | Specify the registry namespace. For air gap environments, this setting overwrites the registry namespace that you pushed images to when you installed KOTS. |
[View a larger version of this image](/images/release-history-link.png)

[View a larger version of this image](/images/release-history-build-airgap-bundle.png)
1. | Domain | Description |
|---|---|
| Docker Hub | Some dependencies of KOTS are hosted as public images in Docker Hub. The required domains for this service are `index.docker.io`, `cdn.auth0.com`, `*.docker.io`, and `*.docker.com.` |
| `proxy.replicated.com` * | Private Docker images are proxied through `proxy.replicated.com`. This domain is owned by Replicated, Inc., which is headquartered in Los Angeles, CA. For the range of IP addresses for `proxy.replicated.com`, see [replicatedhq/ips](https://github.com/replicatedhq/ips/blob/main/ip_addresses.json#L52-L57) in GitHub. |
| `replicated.app` | Upstream application YAML and metadata is pulled from `replicated.app`. The current running version of the application (if any), as well as a license ID and application ID to authenticate, are all sent to `replicated.app`. This domain is owned by Replicated, Inc., which is headquartered in Los Angeles, CA. For the range of IP addresses for `replicated.app`, see [replicatedhq/ips](https://github.com/replicatedhq/ips/blob/main/ip_addresses.json#L60-L65) in GitHub. |
| `registry.replicated.com` ** | Some applications host private images in the Replicated registry at this domain. The on-prem docker client uses a license ID to authenticate to `registry.replicated.com`. This domain is owned by Replicated, Inc which is headquartered in Los Angeles, CA. For the range of IP addresses for `registry.replicated.com`, see [replicatedhq/ips](https://github.com/replicatedhq/ips/blob/main/ip_addresses.json#L20-L25) in GitHub. |
| `kots.io` | Requests are made to this domain when installing the Replicated KOTS CLI. This domain is owned by Replicated, Inc., which is headquartered in Los Angeles, CA. |
| `github.com` | Requests are made to this domain when installing the Replicated KOTS CLI. For information about retrieving GitHub IP addresses, see [About GitHub's IP addresses](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/about-githubs-ip-addresses) in the GitHub documentation. |
[View a larger version of this image](/images/release-history-link.png)

[View a larger version of this image](/images/release-history-build-airgap-bundle.png)
1. | Domain | Description |
|---|---|
| Docker Hub | Some dependencies of KOTS are hosted as public images in Docker Hub. The required domains for this service are `index.docker.io`, `cdn.auth0.com`, `*.docker.io`, and `*.docker.com.` |
| `proxy.replicated.com` * | Private Docker images are proxied through `proxy.replicated.com`. This domain is owned by Replicated, Inc., which is headquartered in Los Angeles, CA. For the range of IP addresses for `proxy.replicated.com`, see [replicatedhq/ips](https://github.com/replicatedhq/ips/blob/main/ip_addresses.json#L52-L57) in GitHub. |
| `replicated.app` | Upstream application YAML and metadata is pulled from `replicated.app`. The current running version of the application (if any), as well as a license ID and application ID to authenticate, are all sent to `replicated.app`. This domain is owned by Replicated, Inc., which is headquartered in Los Angeles, CA. For the range of IP addresses for `replicated.app`, see [replicatedhq/ips](https://github.com/replicatedhq/ips/blob/main/ip_addresses.json#L60-L65) in GitHub. |
| `registry.replicated.com` ** | Some applications host private images in the Replicated registry at this domain. The on-prem docker client uses a license ID to authenticate to `registry.replicated.com`. This domain is owned by Replicated, Inc which is headquartered in Los Angeles, CA. For the range of IP addresses for `registry.replicated.com`, see [replicatedhq/ips](https://github.com/replicatedhq/ips/blob/main/ip_addresses.json#L20-L25) in GitHub. |
`k8s.kurl.sh` `s3.kurl.sh` |
kURL installation scripts and artifacts are served from [kurl.sh](https://kurl.sh). An application identifier is sent in a URL path, and bash scripts and binary executables are served from kurl.sh. This domain is owned by Replicated, Inc., which is headquartered in Los Angeles, CA. For the range of IP addresses for `k8s.kurl.sh`, see [replicatedhq/ips](https://github.com/replicatedhq/ips/blob/main/ip_addresses.json#L34-L39) in GitHub. The range of IP addresses for `s3.kurl.sh` are the same as IP addresses for the `kurl.sh` domain. For the range of IP address for `kurl.sh`, see [replicatedhq/ips](https://github.com/replicatedhq/ips/blob/main/ip_addresses.json#L28-L31) in GitHub. |
| `amazonaws.com` | `tar.gz` packages are downloaded from Amazon S3 during installations with kURL. For information about dynamically scraping the IP ranges to allowlist for accessing these packages, see [AWS IP address ranges](https://docs.aws.amazon.com/general/latest/gr/aws-ip-ranges.html#aws-ip-download) in the AWS documentation. |
[View a larger version of this image](/images/kotsadm-dashboard-graph.png)
## Configure Prometheus monitoring
For existing cluster installations with KOTS, users can install Prometheus in the cluster and then connect the Admin Console to the Prometheus endpoint to enable monitoring.
### Step 1: Install Prometheus in the cluster {#configure-existing}
Replicated recommends that you use CoreOS's Kube-Prometheus distribution for installing and configuring highly available Prometheus on an existing cluster. For more information, see the [kube-prometheus](https://github.com/coreos/kube-prometheus) GitHub repository.
This repository collects Kubernetes manifests, Grafana dashboards, and Prometheus rules combined with documentation and scripts to provide easy to operate end-to-end Kubernetes cluster monitoring with Prometheus using the Prometheus Operator.
To install Prometheus using the recommended Kube-Prometheus distribution:
1. Clone the [kube-prometheus](https://github.com/coreos/kube-prometheus) repository to the device where there is access to the cluster.
1. Use `kubectl` to create the resources on the cluster:
```bash
# Create the namespace and CRDs, and then wait for them to be available before creating the remaining resources
kubectl create -f manifests/setup
until kubectl get servicemonitors --all-namespaces ; do date; sleep 1; echo ""; done
kubectl create -f manifests/
```
For advanced and cluster-specific configuration, you can customize Kube-Prometheus by compiling the manifests using jsonnet. For more information, see the [jsonnet website](https://jsonnet.org/).
For more information about advanced Kube-Prometheus configuration options, see [Customize Kube-Prometheus](https://github.com/coreos/kube-prometheus#customizing-kube-prometheus) in the kube-prometheus GitHub repository.
### Step 2: Connect to a Prometheus endpoint
To view graphs on the Admin Console dashboard, provide the address of a Prometheus instance installed in the cluster.
To connect the Admin Console to a Prometheus endpoint:
1. On the Admin Console dashboard, under Monitoring, click **Configure Prometheus Address**.
1. Enter the address for the Prometheus endpoint in the text box and click **Save**.

Graphs appear on the dashboard shortly after saving the address.
---
# Consume Prometheus metrics externally
:::note
Replicated kURL is available only for existing customers. If you are not an existing kURL user, use Replicated Embedded Cluster instead. For more information, see [Use Embedded Cluster](/embedded-cluster/v3/embedded-overview).
kURL is a Generally Available (GA) product for existing customers. For more information about the Replicated product lifecycle phases, see [Support Lifecycle Policy](/vendor/policies-support-lifecycle).
:::
This topic describes how to consume Prometheus metrics in Replicated kURL clusters from a monitoring service that is outside the cluster.
For information about how to access Prometheus, Grafana, and Alertmanager, see [Accessing Dashboards Using Port Forwarding](/enterprise/monitoring-access-dashboards).
## Overview
The KOTS Admin Console can use the open source systems monitoring tool Prometheus to collect metrics on an application and the cluster where the application is installed. Prometheus components include the main Prometheus server, which scrapes and stores time series data, an Alertmanager for alerting on metrics, and Grafana for visualizing metrics. For more information about Prometheus, see [What is Prometheus?](https://prometheus.io/docs/introduction/overview/) in the Prometheus documentation.
The Admin Console exposes graphs with key metrics collected by Prometheus in the **Monitoring** section of the dashboard. By default, the Admin Console displays the following graphs:
* Cluster disk usage
* Pod CPU usage
* Pod memory usage
In addition to these default graphs, application developers can also expose business and application level metrics and alerts on the dashboard.
The following screenshot shows an example of the **Monitoring** section on the Admin Console dashboard with the Disk Usage, CPU Usage, and Memory Usage default graphs:
[View a larger version of this image](/images/kotsadm-dashboard-graph.png)
For kURL installations, if the [kURL Prometheus add-on](https://kurl.sh/docs/add-ons/prometheus) is included in the kURL installer spec, then the Prometheus monitoring system is installed alongside the application. No additional configuration is required to collect metrics and view any default and custom graphs on the Admin Console dashboard.
Prometheus is deployed in kURL clusters as a NodePort service named `prometheus-k8s` in the `monitoring` namespace. The `prometheus-k8s` service is exposed on the IP address for each node in the cluster at port 30900.
You can run the following command to view the `prometheus-k8s` service in your cluster:
```
kubectl get services -l app=kube-prometheus-stack-prometheus -n monitoring
```
The output of the command includes details about the Prometheus service, including the type of service and the ports where the service is exposed. For example:
```
NAME TYPE CLUSTER_IP EXTERNAL_IP PORT(S) AGE
prometheus-k8s NodePort 10.96.2.229 | Deployment | StatefulSet | Service | Ingress | PVC | DaemonSet | |
|---|---|---|---|---|---|---|
| Ready | Ready replicas equals desired replicas | Ready replicas equals desired replicas | All desired endpoints are ready, any load balancers have been assigned | All desired backend service endpoints are ready, any load balancers have been assigned | Claim is bound | Ready daemon pods equals desired scheduled daemon pods |
| Updating | The deployed replicas are from a different revision | The deployed replicas are from a different revision | N/A | N/A | N/A | The deployed daemon pods are from a different revision |
| Degraded | At least 1 replica is ready, but more are desired | At least 1 replica is ready, but more are desired | At least one endpoint is ready, but more are desired | At least one backend service endpoint is ready, but more are desired | N/A | At least one daemon pod is ready, but more are desired |
| Unavailable | No replicas are ready | No replicas are ready | No endpoints are ready, no load balancer has been assigned | No backend service endpoints are ready, no load balancer has been assigned | Claim is pending or lost | No daemon pods are ready |
| Missing | Missing is an initial deployment status indicating that informers have not reported their status because the application has just been deployed and the underlying resource has not been created yet. After the resource is created, the status changes. However, if a resource changes from another status to Missing, then the resource was either deleted or the informers failed to report a status. | |||||
| Resource Statuses | Aggregate Application Status |
|---|---|
| No status available for any resource | Missing |
| One or more resources Unavailable | Unavailable |
| One or more resources Degraded | Degraded |
| One or more resources Updating | Updating |
| All resources Ready | Ready |
[View a larger version of this image](/images/send-bundle-to-vendor.png)
1. (Optional) Click **Download bundle** to download the support bundle. You can send the bundle to your vendor for assistance.
---
# Perform updates in existing clusters
This topic describes how to perform updates in existing cluster installations with Replicated KOTS. It includes information about how to update applications and the version of KOTS running in the cluster.
It also includes information about how the Admin Console determines version precendence. See [How the Admin Console Determines Version Precendence](/enterprise/updating-app-manager#how-the-admin-console-determines-version-precedence).
:::note
Replicated KOTS is available only for existing customers. For supporting installations into customer managed clusters, we recommend Helm. For more information, see [About Helm Installations with Replicated](/vendor/helm-install-overview).
KOTS is a Generally Available (GA) product for existing customers. For more information about the Replicated product lifecycle phases, see [Support Lifecycle Policy](/vendor/policies-support-lifecycle).
:::
## Update an application
You can perform an application update using the KOTS Admin Console or the KOTS CLI. You can also set up automatic updates. See [Configure Automatic Updates](/enterprise/updating-apps).
### Using the Admin Console
#### Online environments
To perform an update from the Admin Console:
1. In the Admin Console, go to the **Version History** tab.
1. Click **Check for updates**.
A new upstream version displays in the list of available versions.
[View a larger version of this image](/images/new-version-available.png)
1. (Optional) When there are multiple versions of an application, you can compare
the changes between them by clicking **Diff releases** in the right corner.
You can review changes between any two arbitrary releases by clicking the icon in the header
of the release column. Select the two versions to compare, and click **Diff releases**
to show the relative changes between the two releases.
[View a larger version of this image](/images/diff-releases.png)
[View a larger version of this image](/images/new-changes.png)
1. (Optional) Click the **View preflight checks** icon to view or re-run the preflight checks.
[View a larger version of this image](/images/preflight-checks.png)
1. Return to the **Version History** tab and click **Deploy** next to the target version.
#### Air gap environments
import BuildAirGapBundle from "../install/_airgap-bundle-build.mdx"
import DownloadAirGapBundle from "../install/_airgap-bundle-download.mdx"
import ViewAirGapBundle from "../install/_airgap-bundle-view-contents.mdx"
To perform an air gap update from the Admin Console:
1. In the [Vendor Portal](https://vendor.replicated.com), go the channel where the target release is promoted to build and download the new `.airgap` bundle:
* If the **Automatically create airgap builds for newly promoted releases in this channel** setting is enabled on the channel, watch for the build status to complete.
* If automatic air gap builds are not enabled, go to the **Release history** page for the channel and build the air gap bundle manually.
[View a larger version of this image](/images/release-history-link.png)

[View a larger version of this image](/images/release-history-build-airgap-bundle.png)
1.
[View a larger version of this image](/images/release-history-link.png)

[View a larger version of this image](/images/release-history-build-airgap-bundle.png)
1.
[View a larger version of this image](/images/new-version-available.png)
1. (Optional) When there are multiple versions of an application, you can compare
the changes between them by clicking **Diff releases** in the right corner.
You can review changes between any two arbitrary releases by clicking the icon in the header
of the release column. Select the two versions to compare, and click **Diff releases**
to show the relative changes between the two releases.
[View a larger version of this image](/images/diff-releases.png)
[View a larger version of this image](/images/new-changes.png)
1. (Optional) Click the **View preflight checks** icon to view or re-run the preflight checks.
[View a larger version of this image](/images/preflight-checks.png)
1. Return to the **Version History** tab and click **Deploy** next to the target version.
### Air gap environments
import BuildAirGapBundle from "../install/_airgap-bundle-build.mdx"
import DownloadAirGapBundle from "../install/_airgap-bundle-download.mdx"
import ViewAirGapBundle from "../install/_airgap-bundle-view-contents.mdx"
To perform an air gap update from the Admin Console:
1. In the [Vendor Portal](https://vendor.replicated.com), go the channel where the target release is promoted to build and download the new `.airgap` bundle:
| Directory | Changes Persist? | Description |
|---|---|---|
upstream |
No, except for the userdata subdirectory |
The Contains the template functions, preflight checks, support bundle, config options, license, and so on. Contains a |
| Directory | Changes Persist? | Description |
|---|---|---|
base |
No | After KOTS processes and renders the Only the deployable application files, such as files deployable with Any non-deployable manifests, such as template functions, preflight checks, and configuration options, are removed. |
| Subdirectory | Changes Persist? | Description |
|---|---|---|
midstream |
No | Contains KOTS-specific kustomizations, such as:
|
downstream |
Yes | Contains user-defined kustomizations that are applied to the Only one To add kustomizations, see Patch an Application. |
midstream/charts |
No | Appears only when the Contains a subdirectory for each Helm chart. Each Helm chart has its own kustomizations because each chart is rendered and deployed separately from other charts and manifests. The subcharts of each Helm chart also have their own kustomizations and are rendered separately. However, these subcharts are included and deployed as part of the parent chart. |
downstream/charts |
Yes | Appears only when the Contains a subdirectory for each Helm chart. Each Helm chart has its own kustomizations because each chart is rendered and deployed separately from other charts and manifests. The subcharts of each Helm chart also have their own kustomizations and are rendered separately. However, these subcharts are included and deployed as part of the parent chart. |
| Directory | Changes Persist? | Description |
|---|---|---|
rendered |
No | Contains the final rendered application manifests that are deployed to the cluster. The rendered files are created when KOTS processes the |
rendered/charts |
No | Appears only when the Contains a subdirectory for each rendered Helm chart. Each Helm chart is deployed separately from other charts and manifests. The rendered subcharts of each Helm chart are included and deployed as part of the parent chart. |
[View a larger version of this image](/images/kots-installation-overview.png)
As shown in the diagram above:
* For installations in existing online (internet-connected) clusters, users run a command to install KOTS in their cluster.
* For installations on VMs or bare metal servers, users run an Embedded Cluster or kURL installation script that both provisions a cluster in their environment and installs KOTS in the cluster.
* For installations in air-gapped clusters, users download air gap bundles for KOTS and the application from the Replicated Download Portal and then provide the bundles during installation.
All users must have a valid license file to install with KOTS. After KOTS is installed in the cluster, users can access the KOTS Admin Console to provide their license and deploy the application.
For more information about how to install applications with KOTS, see the [Installing an Application](/enterprise/installing-overview) section.
## KOTS user interfaces
This section describes the KOTS interfaces available to users for installing and managing applications.
### KOTS Admin Console
KOTS provides an Admin Console to make it easy for users to install, manage, update, configure, monitor, backup and restore, and troubleshoot their application instance from a GUI.
The following shows an example of the Admin Console dashboard for an application:

[View a larger version of this image](/images/guides/kots/application.png)
For applications installed with Replicated Embedded Cluster in a VM or bare metal server, the Admin Console also includes a **Cluster Management** tab where users can add and manage nodes in the embedded cluster, as shown below:

[View a larger version of this image](/images/gitea-ec-ready.png)
### KOTS CLI
The KOTS command-line interface (CLI) is a kubectl plugin. Customers can run commands with the KOTS CLI to install and manage their application instances with KOTS programmatically.
For information about getting started with the KOTS CLI, see [Installing the KOTS CLI](/reference/kots-cli-getting-started).
The KOTS CLI can also be used to install an application without needing to access the Admin Console. This can be useful for automating installations and upgrades, such as in CI/CD pipelines. For information about how to perform headless installations from the command line, see [Install with the KOTS CLI](/enterprise/installing-existing-cluster-automation).
---
---
pagination_prev: null
---
# About the Replicated Platform
This topic provides an introduction to the Replicated Platform, including a platform overview and a list of key features. It also describes the Commercial Software Distribution Lifecycle and how Replicated features support each phase of the lifecycle.
## Platform overview
Replicated is a commercial software distribution platform.
ISVs can use Replicated Platform features to distribute modern commercial software into complex, customer-controlled environments, including on-prem and air gap.
The Replicated Platform features support ISVs during each phase of the Commercial Software Distribution Lifecycle.
For more information, see [Commercial Software Distribution Lifecycle](#csdl) on this page.
The following diagram shows how the Replicated Platform supports the full application lifecycle,
from distribution and installation with Embedded Cluster to post-installation support:

[View a larger version of this image](/images/replicated-platform.png)
The diagram shows how software vendors use CI/CD pipelines to test releases in environments provisioned by [Replicated Compatibility Matrix (CMX)](/vendor/testing-about).
Vendors then promote releases to a customer-facing or internal channel in the [Vendor Portal](/vendor/releases-about).
Customers can install application releases that vendors promote to the channel to which they subscribe.
To install, the customer logs in to the [Replicated Enterprise Portal](/vendor/enterprise-portal-about) to download their license,
which grants proxy access to the application images through the [Replicated proxy registry](/vendor/private-images-about).
They also download the installation assets for the [Replicated Embedded Cluster](/vendor/embedded-overview) installer.
Customers can access the Enterprise Portal at any time to get installation and update instructions, upload [support bundles](/vendor/preflight-support-bundle-about#support-bundles), view security information from the [Security Center](/vendor/security-center-about), and more.
During installation, Embedded Cluster runs [preflight checks](/vendor/preflight-support-bundle-about) on the host to verify that the environment meets the installation requirements.
Then, it creates a Kubernetes cluster in the VM and deploys a UI. From the UI, the customer enters application-specific configurations, runs application preflight checks, optionally joins nodes to the cluster, and deploys the application.
Embedded Cluster also deploys the [Replicated SDK](/vendor/replicated-sdk-overview) in the cluster, if the vendor included the SDK as a dependency of their application.
The SDK's in-cluster API sends [instance data](/vendor/instance-insights-event-data) and custom metrics from the customer environment to the Vendor Portal.
Vendors can configure [event notifications](/vendor/event-notifications) to email or webhook destinations.
These notifications alert vendors to key events: customer support bundle uploads, instances unhealthy for an extended period, or trial licenses about to expire.
## Replicated Platform features
The following describes the key features of the Replicated Platform.
### Helm CLI installations
Replicated distributes your application as Helm charts through the Replicated proxy registry. Customers with existing Kubernetes clusters install your application using the Helm CLI, authenticating with their unique license ID.
For more information, see [About installation options](/vendor/concepts-installers).
### Embedded Cluster
Replicated Embedded Cluster is a Kubernetes installer based on the open source Kubernetes distribution k0s. With Embedded Cluster, users install and manage both the cluster and the application together as a single appliance on a VM or bare metal server.
For more information, see [Embedded Cluster overview](/embedded-cluster/v3/embedded-overview).
### Preflight checks and support bundles
Preflight checks and support bundles are provided by the Troubleshoot open source project, which is maintained by Replicated. Troubleshoot is a kubectl plugin that provides diagnostic tools for Kubernetes applications. For more information, see the open source [Troubleshoot](https://troubleshoot.sh/docs/collect/) documentation.
Preflight checks and support bundles analyze data from customer environments to provide insights that help users to avoid or troubleshoot common issues with an application:
* **Preflight checks** run before an application is installed to check that the customer environment meets the application requirements.
* **Support bundles** collect troubleshooting data from customer environments to help users diagnose problems with application deployments.
For more information, see [About preflight checks and support bundles](/vendor/preflight-support-bundle-about).
### Proxy registry
The Replicated proxy registry grants proxy access to an application's images using the customer's unique license.
This means that customers can get access to application images during installation without the vendor needing to provide registry credentials.
For more information, see [About the Replicated proxy registry](/vendor/private-images-about).
### Replicated SDK
The Replicated SDK is a Helm chart that you can install as a small service alongside your application.
It provides an in-cluster API that communicates with the Vendor Portal.
For example, the SDK API can return details about the customer's license or report telemetry on the application instance back to the Vendor Portal.
For more information, see [About the Replicated SDK](/vendor/replicated-sdk-overview).
### Vendor Portal
The Replicated Vendor Portal is the web-based interface for configuring Replicated features, managing application releases, viewing customer insights and reporting, and managing teams.
You can also interact with the Vendor Portal programmatically using the following developer tools:
* **Replicated CLI**: Use the Replicated CLI to complete tasks programmatically, including all tasks for packaging and managing applications, and managing artifacts such as teams, license files, and so on. For more information, see [Installing the Replicated CLI](/reference/replicated-cli-installing).
* **Vendor API v3**: Use the Vendor API to complete tasks programmatically, including all tasks for packaging and managing applications, and managing artifacts such as teams and license files. For more information, see [Using the Vendor API v3](/reference/vendor-api-using).
### Enterprise Portal
The Enterprise Portal is a customizable, web-based portal where customers can view install and update instructions, upload support bundles, view instance insights, and more.
For more information, see [About the Enteprise Portal](/vendor/enterprise-portal-about).
The following shows an example of the Enterprise Portal dashboard:

[View a larger version of this image](/images/enterprise-portal-dashboard.png)
### Compatibility matrix
Use Replicated Compatibility Matrix (CMX) to create VMs or Kubernetes clusters within minutes.
Interact with CMX through the Vendor Portal or the Replicated CLI to integrate CMX into your existing CI/CD workflows and programmatically create test environments.
For more information, see [About CMX](/vendor/testing-about).
The following shows the CMX page for creating a cluster:
[View a larger version of this image](/images/create-a-cluster.png)
## Commercial software distribution lifecycle {#csdl}
Replicated Platform features support ISVs in each phase of the Commercial Software Distribution Lifecycle, shown in the following diagram:

[View a larger version of this image](/images/software-dev-lifecycle.png)
Commercial software distribution is the business process that ISVs use to enable enterprise customers to self-host a private application instance in their own environment.
Replicated developed the Commercial Software Distribution Lifecycle to represent the stages essential for delivering software securely and reliably to customer-controlled environments.
Replicated based this lifecycle on the DevOps lifecycle and the Software Development Lifecycle (SDLC),
but it focuses on what ISVs must do to distribute third-party commercial software to tens, hundreds, or thousands of enterprise customers.
For more information about to download a copy of The Commercial Software Distribution Handbook,
see [The Commercial Software Distribution Handbook](https://www.replicated.com/the-commercial-software-distribution-handbook).
The following describes the phases of the software distribution lifecycle:
* **[Develop](#develop)**: Application design and architecture decisions align with customer needs, and development teams can quickly iterate on new features.
* **[Test](#test)**: Run automated tests in several customer-representative environments as part of continuous integration and continuous delivery (CI/CD) workflows.
* **[License](#license)**: Customize licenses for each customer and issue, manage, and update them as needed.
* **[Release](#release)**: Use channels to share releases with external and internal users, publish release artifacts securely, and use consistent versioning.
* **[Install](#install)**: Provide unique installation options depending on customers' preferences and experience levels.
* **[Report](#report)**: Make more informed prioritization decisions by collecting usage and performance metadata for application instances running in customer environments.
* **[Support](#support)**: Diagnose and resolve support issues quickly.
For more information about the Replicated features that support each phase, see the following sections.
### Develop
The Replicated SDK exposes an in-cluster API that you can develop against to quickly integrate and test core functionality with an application.
For example, use the in-cluster API to send custom metrics to the Replicated Vendor Portal after installing the SDK alongside your application.
For more information about using the Replicated SDK, see [About the Replicated SDK](/vendor/replicated-sdk-overview).
### Test
Use CMX to quickly provision ephemeral VMs and Kubernetes clusters.
When integrated into CI/CD workflows, CMX automatically creates a variety of customer-representative environments for testing code changes.
For more information, see [About CMX](/vendor/testing-about).
### License
Create customers in the Replicated Vendor Portal to handle licensing for your application in both online and air gap environments.
For example:
* License free trials and different tiers of product plans
* Create and manage custom license entitlements
* Verify license entitlements both before installation and during runtime
* Measure and report usage
For more information about working with customers and custom license fields, see [About customers](/vendor/licenses-about).
### Release
Release channels in the Replicated Vendor Portal allow ISVs to make different application versions available to different customers,
without needing to maintain separate code bases.
For example, use a "Beta" channel to share beta releases with only a subset of customers.
For more information about working with channels, see [About channels and releases](/vendor/releases-about).
Additionally, the Replicated proxy registry grants proxy access to private application images using the customers' license.
This ensures customers have appropriate access to images based on their assigned channel.
For more information about using the proxy registry, see [About the Replicated proxy registry](/vendor/private-images-about).
### Install
Applications distributed with the Replicated Platform can support different installation methods from the same application release, helping you to meet your customers where they are.
Customers new to Kubernetes, or who prefer a dedicated cluster, can install on a VM or bare metal server with the Embedded Cluster installer.
For more information, see [Embedded Cluster overview](/embedded-cluster/v2/embedded-overview).
Customers familiar with Kubernetes and Helm can install in their own existing cluster using the Helm CLI.
For more information, see [Installing with Helm](/vendor/install-with-helm).
Customers in environments with limited or no outbound internet access can securely push images to their own internal registry,
then install using the Helm CLI or a Replicated installer.
Additionally, the Enterprise Portal provides a customizable, web-based portal where customers can view install and update instructions, upload support bundles, view instance insights, and more.
For more information, see [About the Enteprise Portal](/vendor/enterprise-portal-about).
### Report
When installed alongside an application, the Replicated SDK automatically sends instance data from the customer environment to the Replicated Vendor Portal.
This instance data includes health and status indicators, adoption metrics, and performance metrics.
For more information, see [About instance and event data](/vendor/instance-insights-event-data).
ISVs can also set up notifications to get alerted of important instance issues or performance trends.
For more information, see [About Event Notifications](/vendor/event-notifications).
### Support
Support teams can use Replicated features to more quickly diagnose and resolve application issues.
For example:
- Customize and generate support bundles, which collect and analyze redacted information from the customer's cluster, environment, and application instance. See [About preflight checks and support bundles](/vendor/preflight-support-bundle-about).
- Provision customer-representative environments with CMX to recreate and diagnose issues. See [About CMX](/vendor/testing-about).
- Get insights into an instance's status by accessing telemetry data, which covers the health of the application, the current application version, and details about the infrastructure and cluster where the application is running. For more information, see [Customer reporting](/vendor/customer-reporting). For more information, see [Customer reporting](/vendor/customer-reporting).
---
---
slug: /
pagination_next: null
title: Home
hide_table_of_contents: true
hide_title: true
---
Learn how to use the Replicated Platform to secure and distribute your software to enterprise customers
Custom license fields allow you to define application-specific entitlements and add other types of metadata to customer licenses.
Learn more →Manage team members, RBAC, API tokens, and more
Manage your application in the Vendor Portal
Create and promote application versions
Manage customer records and license entitlements
Alias Replicated domains
Get telemetry and event data from customer instances
Use the CLI to manage applications, releases, and more
Integrate Vendor Platform functionality into your workflows
Distribute a Kubernetes cluster and your application together as a single appliance
Embedded Cluster Config resource
Install with internet access using Embedded Cluster
Install in environments without internet access
Update an application and the cluster infrastructure
An introduction to Helm CLI installations for applications distributed with Replicated
Install your application using Helm CLI
Use Helm in environments without internet access
Give customers access to releases and instance data
Configure branding and appearance for customers
Invite and manage customer portal users
Access and use the Enterprise Portal
Enable self-service access to trial or community licenses for customers
Test your application across customer-representative environments
Learn about pricing for CMX clusters and VMs
Simulate networks with no outbound internet access
Create and manage virtual machines for testing
Create and manage Kubernetes clusters for testing
Automate testing workflows with continuous integration
Grant proxy access to private images
Connect external image registries
Proxy images for Embedded Cluster installations
Proxy images for Helm CLI installations
Pull images from public registries
In-cluster service and API to integrate key Replicated functionality into your application
Install alongside an application or as a standalone component
Develop against the SDK API to test changes locally
API reference for Replicated SDK endpoints
Customize RBAC, set environment variables, add tolerations, and more
Learn about troubleshooting tools for customer environments
Verify that customer environments meet application requirements
Configure support bundles for troubleshooting
Collect support bundles in customer environments
Analyze support bundles to troubleshoot issues
Contact Replicated support for assistance
| Required Field | Allowed Values | Allowed Special Characters |
|---|---|---|
| Minute | 0 through 59 | , - * |
| Hour | 0 through 23 | , - * |
| Day-of-month | 1 through 31 | , - * ? |
| Month | 1 through 12 or JAN through DEC | , - * |
| Day-of-week | 1 through 7 or SUN through SAT | , - * ? |
| Special Character | Description |
|---|---|
| Comma (,) | Specifies a list or multiple values, which can be consecutive or not. For example, 1,2,4 in the Day-of-week field signifies every Monday, Tuesday, and Thursday. |
| Dash (-) | Specifies a contiguous range. For example, 4-6 in the Month field signifies April through June. |
| Asterisk (*) | Specifies that all of the values for the field are used. For example, using * in the Month field means that all of the months are included in the schedule. |
| Question mark (?) | Specifies that one or another value can be used. For example, enter 5 for Day-of-the-month and ? for Day-of-the-week to check for updates on the 5th day of the month, regardless of which day of the week it is. |
| Schedule Value | Description | Equivalent Cron Expression |
|---|---|---|
| @yearly (or @annually) | Runs once a year, at midnight on January 1. | 0 0 1 1 * |
| @monthly | Runs once a month, at midnight on the first of the month. | 0 0 1 * * |
| @weekly | Run once a week, at midnight on Saturday. | 0 0 * * 0 |
| @daily (or @midnight) | Runs once a day, at midnight. | 0 0 * * * |
| @hourly | Runs once an hour, at the beginning of the hour. | 0 * * * * |
| @never | Disables the schedule completely. Only used by KOTS. This value can be useful when you are calling the API directly or are editing the KOTS configuration manually. |
0 * * * * |
| @default | Selects the default schedule option (every 4 hours). Begins when the Admin Console starts up. This value can be useful when you are calling the API directly or are editing the KOTS configuration manually. |
0 * * * * |
| API Group/Version | Kind | Description |
| app.k8s.io/v1beta1 | [SIG Application](https://github.com/kubernetes-sigs/application#kubernetes-applications) | Defines metadata about the application |
| embeddedcluster.replicated.com/v1beta1 | [Config](/embedded-cluster/v3/embedded-config) | Defines a Replicated Embedded Cluster distribution |
| cluster.kurl.sh/v1beta1 | [Installer](https://kurl.sh/docs/create-installer/) | Defines a Replicated kURL distribution |
| kots.io/v1beta1 | [Application](custom-resource-application) | Adds metadata to the user-facing UI for installations with a Replicated installer |
| kots.io/v1beta1 | [Config](custom-resource-config) | Defines a user-facing configuration screen for installations with a Replicated installer |
| kots.io/v1beta2 | [HelmChart](custom-resource-helmchart-v2) | Identifies an instantiation of a Helm chart |
| kots.io/v1beta1 | [LintConfig](custom-resource-lintconfig) | Customizes the default rule levels for the release linter |
| troubleshoot.sh/v1beta2 | [Preflight](custom-resource-preflight) | Defines collectors and analyzers for preflight checks |
| troubleshoot.sh/v1beta2 | [Redactor](https://troubleshoot.sh/docs/redact/) | Defines custom redactors for support bundles and preflight checks |
| troubleshoot.sh/v1beta2 | [Support Bundle](custom-resource-preflight) | Defines collectors and analyzers for support bundles |
| velero.io/v1 | [Backup](https://velero.io/docs/v1.17/api-types/backup/) | Defines a Velero backup request |
[View a larger version of this image](/images/embedded-cluster-v3-install-wizard-login.png)
### `icon`
A file with the icon to use in the customer-facing UI. Typically, this is the application's logo.
The icon can be a remote URL or a Base64 encoded image. Air gap installations require Base64 encoded images.
#### Limitation
The `icon` property doesn't support Go templating.
#### Examples
##### Remote URL
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: your-application
spec:
icon: https://support.io/img/logo.png
```
##### Base64-encoded image
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: your-application
spec:
icon: data:image/svg+xml;base64,PHNy4xMDwM...# based64-encoded image
```
### `releaseNotes`
The release notes for this application version. You can also set the release notes from the Vendor Portal or Replicated CLI when you promote a release. For more information, see [Managing releases with the Vendor Portal](/vendor/releases-creating-releases) or [Managing releases with the CLI](/vendor/releases-creating-cli).
For Embedded Cluster v2, KOTS existing cluster, and kURL installations, customers can access release notes from the Admin Console.
For Embedded Cluster v3, you can optionally include these release notes in your application using the Replicated [ReleaseNotes](/reference/template-functions-license-context#releasenotes) template function.
#### Limitation
The `releaseNotes` property doesn't support Go templating.
#### Example
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: your-application
spec:
releaseNotes: Fixes a bug and adds a new feature.
```
### `allowRollback`
Enable this flag to create a **Rollback** button on the Admin Console **Version History** page. By default, `allowRollback` is false.
If your application does not introduce backwards-incompatible versions, such as through database migrations, you can use `allowRollback`. This flag lets end users roll back to previous versions from the Admin Console.
Rollback does not revert any state. Rather, it recovers the YAML manifests applied to the cluster.
#### Limitations
* The `allowRollback` property doesn't support Go templating.
* Embedded Cluster v3 doesn't support the `allowRollback` property.
* Embedded Cluster v2 supports rolling back the application version only. It doesn't support rolling back the Embedded Cluster version. Users can roll back to an earlier application version only when the Embedded Cluster version stays the same. For example, after upgrading to 1.1.0, users can roll back to version 1.0.0 only if both 1.0.0 and 1.1.0 use the same Embedded Cluster version.
#### Example
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: your-application
spec:
allowRollback: true
```
### `additionalNamespaces`
An array of additional namespaces as strings that the installer creates in the cluster. One common use case for `additionalNamespaces` is Operators, which often need to be able to manage resources in multiple namespaces in the cluster.
For Embedded Cluster v3 installations, Embedded Cluster ensures that the private CA ConfigMap exists in each additional namespace. This allows Embedded Cluster to manage resources in the namespace. For more information about the ConfigMap, see [PrivatCACert](/reference/template-functions-static-context#privatecacert).
For Embedded Cluster v2, KOTS existing cluster, and kURL installations, KOTS creates a Role and RoleBinding in each namespace. This ensures that the Admin Console has full access to manage resources in the namespace. KOTS also ensures that the application pull secret exists in each namespace, and that this secret has access to pull application images.
#### Limitations
* The `additionalNamespaces` property doesn't support Go templating.
* If the current user account does not have access to create the additional namespaces, the installer will show an error and fail.
#### Examples
##### Array of multiple additional namespaces
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: my-operator
spec:
additionalNamespaces:
- namespace1
- namespace2
```
##### Dynamically-created namespaces
For dynamically-created namespaces, specify `"*"`.
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: your-application
spec:
additionalNamespaces:
- "*"
```
### `additionalImages`
An array of strings that reference images to include in air gap bundles and push to the local registry during installation. One common use case for `additionalImages` is Operators, which might need to include additional images that are not referenced until runtime.
For more information about setting `additionalImages` for Embedded Cluster v2, KOTS existing cluster, or kURL installations, see [Defining Additional Images](/vendor/operator-defining-additional-images).
#### Limitations
* The `additionalImages` property doesn't support Go templating.
* Supported for Embedded Cluster v2, KOTS existing cluster, and kURL installations only. Embedded Cluster v3 doesn't support the `additionalImages` property.
#### Example
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: my-app
spec:
additionalImages:
- elasticsearch:7.6.0
- quay.io/orgname/private-image:v1.2.3
- registry.replicated.com/my-operator/my-private-image:abd123f
```
### `excludedImages`
An array of strings that reference images to exclude from air gap bundles.
#### Limitations
* The `excludedImages` property doesn't support Go templating.
* Supported for Embedded Cluster v2, KOTS existing cluster, and kURL installations only. Embedded Cluster v3 doesn't support the `excludedImages` property.
#### Example
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: your-application
spec:
excludedImages:
- auto # This image does not exist but is imported by the Istio Gateway chart
```
### `requireMinimalRBACPrivileges`
When true, `requireMinimalRBACPrivileges` requires minimal role-based access control (RBAC) for KOTS. When set to `true`, KOTS creates a namespace-scoped Role and RoleBinding instead of the default cluster-scoped ClusterRole and ClusterRoleBinding. By default, `requireMinimalRBACPrivileges` is false.
For additional requirements and limitations related to using namespace-scoped RBAC, see [About Namespace-scoped RBAC](/vendor/packaging-rbac#min-rbac) in _Configuring KOTS RBAC_.
#### Limitations
* The `requireMinimalRBACPrivileges` property doesn't support Go templating.
* Supported for KOTS existing cluster installations only. Embedded Cluster doesn't support the `requireMinimalRBACPrivileges` property.
#### Example
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: your-application
spec:
requireMinimalRBACPrivileges: true
```
### `supportMinimalRBACPrivileges`
Allows your end customers to enable minimal role-based access control (RBAC). When set to `true`, KOTS supports creating a namespace-scoped Role and RoleBinding instead of the default cluster-scoped ClusterRole and ClusterRoleBinding. By default, `supportMinimalRBACPrivileges` is false.
KOTS uses minimal RBAC only when you pass the `--use-minimal-rbac` flag with the `kots install` command.
For additional requirements and limitations related to using namespace-scoped RBAC, see [About Namespace-scoped RBAC](/vendor/packaging-rbac#min-rbac) in _Configuring KOTS RBAC_.
#### Limitations
* The `supportMinimalRBACPrivileges` property doesn't support Go templating.
* Supported for KOTS existing cluster installations only. Embedded Cluster doesn't support the `supportMinimalRBACPrivileges` property.
#### Example
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: your-application
spec:
supportMinimalRBACPrivileges: true
```
### `ports`
Extra ports, in addition to the `8800` Admin Console port, that are port-forwarded when running the `kubectl kots admin-console` command. With ports specified, KOTS can establish port forwarding to simplify connections to the deployed application. When the application starts and the service is ready, the KOTS CLI prints the URL to access the port-forwarded service. For more information, see [Port Forwarding Services with KOTS](/vendor/admin-console-port-forward).
#### About port forwarding in VM-based installations
For installations on VMs or bare metal servers with Embedded Cluster v2 or kURL, KOTS does not automatically create port forwards. This is because KOTS cannot verify that the ports are secure and authenticated. Instead, Embedded Cluster v2 or kURL creates a NodePort service. This makes the Admin Console accessible on a port on the node (port `8800` for kURL or port `30000` for Embedded Cluster v2).
You can expose additional ports on the node for Embedded Cluster v2 or kURL installations by creating NodePort services. For more information, see [Exposing Services Using NodePorts](/vendor/kurl-nodeport-services).
#### Properties
| Property | Description |
| --- | --- |
| `ports.serviceName` | The name of the service that receives the traffic. |
| `ports.servicePort` | The `containerPort` of the Pod where the service is running. Ensure that you use the `containerPort` and not the `servicePort`. The `containerPort` and `servicePort` are often the same port, though it is possible that they are different. |
| `ports.localPort` | The port to map on the local workstation. |
| `ports.applicationUrl` | Optional. When set to the same URL as the one in the `descriptor.links.url` field of the Kubernetes SIG Application custom resource, KOTS adds a link on the Admin Console dashboard where users can access the given service. This process automatically links to the hostname in the browser where users access the Admin Console and appends the specified `localPort`. If not set, KOTS links the URL defined in the `descriptor.links.url` field of the Kubernetes SIG Application on the Admin Console dashboard. |
#### Limitations
* `ports` supports Go templates in the `ports.serviceName` and `ports.applicationUrl` fields only.
Using Go templates in the `ports.localPort` or `ports.servicePort` fields results in an installation error similar to the following: `json: cannot unmarshal string into Go struct field ApplicationPort.spec.ports.servicePort of type int`.
* Supported only for Embedded Cluster v2, KOTS existing cluster, and kURL installations. Embedded Cluster v3 doesn't support the `ports` property or port-forwarding services with KOTS.
#### Example
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: your-application
spec:
ports:
- serviceName: web
servicePort: 9000
localPort: 9000
applicationUrl: "http://web"
```
### `statusInformers`
Resources to watch and report application status back to the user. When you include `statusInformers`, the dashboard can indicate when the application deployment is complete and the application is ready for use.
`statusInformers` use the format `[namespace/]type/name`, where namespace is optional.
For more information about including `statusInformers`, see [Enable and understand application status](/vendor/insights-app-status).
:::note
For Embedded Cluster v3 installations, you can define custom status informers using the Replicated SDK instead of listing them in the Application custom resource `statusInformers` field. For more information, see [Enable application status insights](/vendor/insights-app-status#enable-application-status-insights).
:::
#### Examples
##### Plain text
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: your-application
spec:
statusInformers:
- deployment/my-web-svc
- deployment/my-worker
```
##### Go templating
The following example shows excluding a specific status informer based on a user-supplied value from the Admin Console Configuration screen:
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: your-application
spec:
statusInformers:
- deployment/my-web-svc
- '{{repl if ConfigOptionEquals "option" "value"}}deployment/my-worker{{repl else}}{{repl end}}'
```
### `graphs`
For installations with KOTS in existing cluster, `graphs` defines custom graphs to include on the Admin Console dashboard. For more information about how to create custom graphs, see [Adding Custom Graphs](/vendor/admin-console-prometheus-monitoring).
The `graphs` key has the following fields:
* `graphs.title`: The graph title.
* `graphs.query`: The Prometheus query.
* `graphs.legend`: The legend to use for the query line. You can use Prometheus templating in the `legend` fields with each element returned from the Prometheus query. The template escape sequence is `{{}}`. Use `{{ value }}`. For more information, see [Template Reference](https://prometheus.io/docs/prometheus/latest/configuration/template_reference/) in the Prometheus documentation.
* `graphs.queries`: A list of queries containing a `query` and `legend`.
* `graphs.yAxisFormat`: The format of the Y axis labels with support for all Grafana units. For more information, see [Visualizations](https://grafana.com/docs/features/panels/graph/#left-y-right-y) in the Grafana documentation.
* `graphs.yAxisTemplate`: Y axis labels template.
#### Limitation
Embedded Cluster doesn't support the `graphs` property.
#### Example
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: your-application
spec:
graphs:
- title: User Signups
query: 'sum(user_signup_events_total)'
```
### `proxyRegistryDomain` (Deprecated)
:::important
`proxyRegistryDomain` is deprecated. For information about how to use a custom domain for the Replicated proxy registry, see [Use Custom Domains](/vendor/custom-domains-using).
:::
The custom domain used for proxy.replicated.com. For more information, see [Using Custom Domains](/vendor/custom-domains-using).
#### Limitation
The `proxyRegistryDomain` property doesn't support Go templating.
#### Example
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: your-application
spec:
proxyRegistryDomain: "proxy.yourcompany.com"
```
### `replicatedRegistryDomain` (Deprecated)
:::important
`replicatedRegistryDomain` is deprecated. For information about how to use a custom domain for the Replicated registry, see [Use Custom Domains](/vendor/custom-domains-using).
:::
The custom domain used for registry.replicated.com. For more information, see [Using Custom Domains](/vendor/custom-domains-using).
#### Limitation
The `replicatedRegistryDomain` property doesn't support Go templating.
#### Example
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: your-application
spec:
replicatedRegistryDomain: "registry.yourcompany.com"
```
### `targetKotsVersion`
For KOTS existing cluster installations, `targetKotsVersion` specifies the version of KOTS to use. For more information, see [Setting Minimum and Target Versions for KOTS](/vendor/packaging-kots-versions).
#### Limitations
* The `targetKotsVersion` property doesn't support Go templating.
* Supported for KOTS existing cluster installations only. Embedded Cluster doesn't support the `targetKotsVersion` property. To avoid installation failures, do not use `targetKotsVersion` in releases that support installation with Embedded Cluster. For more information, see [Setting Minimum and Target Versions for KOTS](/vendor/packaging-kots-versions).
#### Example
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: your-application
spec:
targetKotsVersion: "1.130.2"
```
### `minKotsVersion`
For KOTS existing cluster installations, `minKotsVersion` sets the minimum KOTS version required to deploy the given release. KOTS blocks an installation or update if the deployed KOTS version is earlier than the `minKotsVersion`. For more information, see [Setting Minimum and Target Versions for KOTS](/vendor/packaging-kots-versions).
#### Limitations
* The `minKotsVersion` property doesn't support Go templating.
* Supported for KOTS existing cluster installations only. Embedded Cluster doesn't support the `minKotsVersion` property. To avoid installation failures, do not use `minKotsVersion` in releases that support installation with Embedded Cluster. For more information, see [Setting Minimum and Target Versions for KOTS](/vendor/packaging-kots-versions).
#### Example
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: your-application
spec:
minKotsVersion: "1.124.5"
```
---
# Velero Backup resource for snapshots
This topic provides information about the supported fields in the Velero Backup resource for the Replicated KOTS snapshots feature.
:::note
Replicated KOTS is available only for existing customers. For supporting installations into customer managed clusters, we recommend Helm. For more information, see [About Helm Installations with Replicated](/vendor/helm-install-overview).
KOTS is a Generally Available (GA) product for existing customers. For more information about the Replicated product lifecycle phases, see [Support Lifecycle Policy](/vendor/policies-support-lifecycle).
:::
## Overview
The Velero Backup custom resource enables the KOTS snapshots backup and restore feature. The backend of this feature uses the Velero open source project to back up Kubernetes manifests and persistent volumes.
## Example
The following shows an example of the Velero Backup resource:
```yaml
apiVersion: velero.io/v1
kind: Backup
metadata:
name: backup
annotations:
# `pvc-volume` will be the only volume included in the backup
backup.velero.io/backup-volumes: pvc-volume
spec:
includedNamespaces:
- '*'
excludedNamespaces:
- some-namespace
orderedResources:
pods: mysql/mysql-cluster-replica-0,mysql/mysql-cluster-replica-1
persistentvolumes: pvc-12345,pvc-67890
ttl: 720h
hooks:
resources:
-
name: my-hook
includedNamespaces:
- '*'
excludedNamespaces:
- some-namespace
includedResources:
- pods
excludedResources: []
labelSelector:
matchLabels:
app: velero
component: server
pre:
-
exec:
container: my-container
command:
- /bin/uname
- -a
onError: Fail
timeout: 10s
post: []
```
## Supported fields for full backups with snapshots {#fields}
For partial backups with the snapshots feature, you can use all of the fields that Velero supports. See [Backups](https://velero.io/docs/v1.10/api-types/backup/) in the Velero documentation.
However, not all fields are supported for full backups. The table below lists the fields that are supported for full backups with snapshots:
| Field Name | Description |
|---|---|
includedNamespaces |
(Optional) Specifies an array of namespaces to include in the backup. If unspecified, all namespaces are included. |
excludedNamespaces |
(Optional) Specifies an array of namespaces to exclude from the backup. |
orderedResources |
(Optional) Specifies the order of the resources to collect during the backup process. This is a map that uses a key as the plural resource. Each resource name has the format NAMESPACE/OBJECTNAME. The object names are a comma delimited list. For cluster resources, use OBJECTNAME only. |
ttl |
Specifies the amount of time before this backup is eligible for garbage collection. Default:720h (equivalent to 30 days). This value is configurable only by the customer. |
hooks |
(Optional) Specifies the actions to perform at different times during a backup. The only supported hook is executing a command in a container in a pod (uses the pod exec API). Supports pre and post hooks. |
hooks.resources |
(Optional) Specifies an array of hooks that are applied to specific resources. |
hooks.resources.name |
Specifies the name of the hook. This value displays in the backup log. |
hooks.resources.includedNamespaces |
(Optional) Specifies an array of namespaces that this hook applies to. If unspecified, the hook is applied to all namespaces. |
hooks.resources.excludedNamespaces |
(Optional) Specifies an array of namespaces to which this hook does not apply. |
hooks.resources.includedResources |
Specifies an array of pod resources to which this hook applies. |
hooks.resources.excludedResources |
(Optional) Specifies an array of resources to which this hook does not apply. |
hooks.resources.labelSelector |
(Optional) Specifies that this hook only applies to objects that match this label selector. |
hooks.resources.pre |
Specifies an array of exec hooks to run before executing custom actions. |
hooks.resources.post |
Specifies an array of exec hooks to run after executing custom actions. Supports the same arrays and fields as pre hooks. |
hooks.resources.[post/pre].exec |
Specifies the type of the hook. exec is the only supported type. |
hooks.resources.[post/pre].exec.container |
(Optional) Specifies the name of the container where the specified command will be executed. If unspecified, the first container in the pod is used. |
hooks.resources.[post/pre].exec.command |
Specifies the command to execute. The format is an array. |
hooks.resources.[post/pre].exec.onError |
(Optional) Specifies how to handle an error that might occur when executing the command. Valid values: Fail and Continue Default: Fail |
hooks.resources.[post/pre].exec.timeout |
(Optional) Specifies how many seconds to wait for the command to finish executing before the action times out. Default: 30s |
[View a larger version of this image](/images/config-screen-bool.png)
### `dropdown`
> Introduced in KOTS v1.114.0
The `dropdown` item type includes one or more nested items that display in a dropdown on the config screen. Dropdowns are especially useful for displaying long lists of options. You can also use the [`radio`](#radio) item type to display radio buttons for items with shorter lists of options.
To set a default value for `dropdown` items, set the `default` field to the name of the target nested item.
```yaml
spec:
groups:
- name: example_settings
title: My Example Config
items:
- name: version
title: Version
default: version_latest
type: dropdown
items:
- name: version_latest
title: latest
- name: version_123
title: 1.2.3
- name: version_124
title: 1.2.4
- name: version_125
title: 1.2.5
```
[View a larger version of this image](/images/config-screen-dropdown.png)
[View a larger version of this image](/images/config-screen-dropdown-open.png)
### `file`
A `file` is a special type of form field that renders an [``](https://www.w3schools.com/tags/tag_input.asp) HTML element.
The form field captures only the file contents, not the filename.
See the [`ConfigOptionData`](template-functions-config-context#configoptiondata) template function for examples on how to use the file contents in your application.
```yaml
- name: certs
title: TLS Configuration
items:
- name: tls_private_key_file
title: Private Key
type: file
- name: tls_certificate_file
title: Certificate
type: file
```
[View a larger version of this image](/images/config-screen-file.png)
### `heading`
The `heading` type allows you to display a group heading as a sub-element within a group.
This is useful when you would like to use a config group to group items together, but still separate the items visually.
```yaml
- name: ldap_settings
title: LDAP Server Settings
items:
...
- name: ldap_schema
type: heading
title: LDAP schema
...
```
[View a larger versio of this image](/images/config-screen-heading.png)
### `label`
The `label` type allows you to display an input label.
```yaml
- name: email
title: Email
items:
- name: email-address
title: Email Address
type: text
- name: description
type: label
title: "Note: The system will send you an email every hour."
```
[View a larger version of this image](/images/config-screen-label.png)
### `password`
The `password` type is a text field that hides the character input.
```yaml
- name: password_text
title: Password Text
type: password
value: '{{repl RandomString 10}}'
```
[View a larger version of this image](/images/config-screen-password.png)
### `radio`
> Introduced in KOTS v1.114.0
The `radio` item type includes one or more nested items that display as radio buttons on the config screen. Radio buttons are especially useful for displaying short lists of options. You can also use the [`dropdown`](#dropdown) item type for items with longer lists of options.
To set a default value for `radio` items, set the `default` field to the name of the target nested item.
```yaml
spec:
groups:
- name: example_settings
title: My Example Config
items:
- name: authentication_type
title: Authentication Type
default: authentication_type_anonymous
type: radio
items:
- name: authentication_type_anonymous
title: Anonymous
- name: authentication_type_password
title: Password
```
### `select_one` (Deprecated)
:::important
The `select_one` item type is deprecated. Use [`radio`](#radio) instead.
:::
`select_one` items must contain nested items. The nested items display as radio buttons on the config screen.
Use the `name` field of a `select_one` item with Replicated template functions in the Config context (such as ConfigOption or ConfigOptionEquals) to return the user-selected option.
For example, if the user selects the **Password** option for the `select_one` item in the following example, then the template function `'{{repl ConfigOption "authentication_type"}}'` returns `authentication_type_password`. For more information about working with template functions in the Config context, see [Config Context](/reference/template-functions-config-context).
```yaml
spec:
groups:
- name: example_settings
title: My Example Config
description: Configuration to serve as an example for creating your own.
items:
- name: authentication_type
title: Authentication Type
default: authentication_type_anonymous
type: select_one
items:
- name: authentication_type_anonymous
title: Anonymous
- name: authentication_type_password
title: Password
```
### `text`
A `text` input field allows users to enter a string value.
Optionally, all additional properties are available for this input type.
```yaml
- name: example_text_input
title: Example Text Input
type: text
```
:::important
Do not store secrets or passwords in `text` items because they are not encrypted or masked and can be accessed. Instead, use [`password`](#password) items.
:::
### `textarea`
A `textarea` items creates a multi-line text input for when users have to enter a sizeable amount of text.
```yaml
- name: custom_key
title: Set your secret key for your app
description: Paste in your Custom Key
items:
- name: key
title: Key
type: textarea
- name: hostname
title: Hostname
type: text
```
## Item properties
Items have a `name`, `title`, `type`, and other optional properties.
### `affix`
Affix items `left` or `right` to display them on the same line on the config screen.
Specify the `affix` field to all of the items in a particular group to preserve the line spacing and prevent the appearance of crowded text.
#### Example
```yaml
groups:
- name: example_settings
title: My Example Config
description: Configuration to serve as an example for creating your own.
items:
- name: username
title: Username
type: text
required: true
affix: left
- name: password
title: Password
type: password
required: true
affix: right
```
### `default`
Defines the default value for the config item. If the user does not provide a value for the item, the `default` value takes effect.
If the `default` value is not associated with a `password` type config item, then it appears as placeholder text on the config screen.
The installer reevaluates Go template functions in the `default` property each time the user changes their configuration settings.
#### Example
```yaml
- name: custom_key
title: Set your secret key for your app
description: Paste in your Custom Key
items:
- name: key
title: Key
type: text
value: ""
default: change me
```
[View a larger version of this image](/images/config-default.png)
### `help_text`
Displays a helpful message under the `title` for the config item on the config screen.
The property supports markdown syntax. For more information, see [Basic writing and formatting syntax](https://guides.github.com/features/mastering-markdown/) in the GitHub Docs.
#### Example
```yaml
- name: http_settings
title: HTTP Settings
items:
- name: http_enabled
title: HTTP Enabled
help_text: Check to enable the HTTP listener
type: bool
```
[View a larger version of this image](/images/config-help-text.png)
### `hidden`
Hidden items are not visible on the config screen.
When you assign a template function that generates a value to a `value` property, you can use the `readonly` and `hidden` properties to define whether or not the generated value is ephemeral or persistent between changes to the configuration settings for the application. For more information, see [RandomString](template-functions-static-context#randomstring) in _Static Context_.
#### Limitation
The `hidden` property doesn't support Go templating.
#### Example
```yaml
- name: secret_key
title: Secret Key
type: password
hidden: true
value: "{{repl RandomString 40}}"
```
### `name` (Required)
A unique identifier for the config item. Item names must be unique both within the group and across all groups. The item `name` is not displayed on the config screen.
Use the item `name` with Replicated template functions in the Config context (such as ConfigOption or ConfigOptionEquals) to return the value of the item. For more information, see [Config Context](/reference/template-functions-config-context).
#### Example
```yaml
- name: http_settings
title: HTTP Settings
items:
- name: http_enabled
title: HTTP Enabled
type: bool
```
### `readonly`
Readonly items display on the config screen and users cannot edit their value.
When you assign a template function that generates a value to a `value` property, you can use the `readonly` and `hidden` properties to define whether or not the generated value is ephemeral or persistent between changes to the configuration settings for the application. For more information, see [RandomString](template-functions-static-context#randomstring) in _Static Context_.
#### Limitation
The `readonly` property doesn't support Go templating.
#### Example
```yaml
- name: key
title: Key
type: text
value: ""
default: change me
- name: unique_key
title: Unique Key
type: text
value: "{{repl RandomString 20}}"
readonly: true
```
[View a larger version of this image](/images/config-readonly.png)
### `recommended`
Displays a Recommended tag for the config item on the config screen.
#### Limitations
* The `recommended` property doesn't support Go templating.
* Embedded Cluster v3 doesn't support the `recommended` property
#### Example
```yaml
- name: recommended_field
title: My recommended field
type: bool
default: "0"
recommended: true
```
[View a larger version of this image](/images/config-recommended-item.png)
### `required`
Displays a Required tag for the config item on the config screen. A required item prevents the application from starting until it has a value.
#### Limitation
The `required` property doesn't support Go templating.
#### Example
```yaml
- name: custom_key
title: Set your secret key for your app
description: Paste in your Custom Key
items:
- name: key
title: Key
type: text
value: ""
default: change me
required: true
```
[View a larger version of this image](/images/config-required-item.png)
### `title` (Required)
The title of the config item that displays on the config screen.
#### Example
```yaml
- name: http_settings
title: HTTP Settings
items:
- name: http_enabled
title: HTTP Enabled
help_text: Check to enable the HTTP listener
type: bool
```
[View a larger version of this image](/images/config-help-text.png)
### `type` (Required)
Each item has a `type` property that defines the type of user input accepted by the field.
The `type` property supports the following values:
[View a larger version of this image](/images/config-screen-bool.png)
### `value`
Defines the value of the config item. Data that you add to `value` appears as the HTML input value for the config item on the config screen.
If the config item is not readonly, then the data that you add to `value` is overwritten by any user input for the item. If the item is readonly, then the data that you add to `value` cannot be overwritten.
When you assign a template function that generates a value to a `value` property, you can use the `readonly` and `hidden` properties to define whether or not the generated value is ephemeral or persistent between changes to the configuration settings for the application. For more information, see [RandomString](template-functions-static-context#randomstring) in _Static Context_.
#### Example
```yaml
- name: custom_key
title: Set your secret key for your app
description: Paste in your Custom Key
items:
- name: key
title: Key
type: text
value: "{{repl RandomString 20}}"
```
[View a larger version of this image](/images/config-value-randomstring.png)
### `when` {#when-item}
The `when` property denotes items that display on the config screen only when a condition evaluates to true. When the condition evaluates to false, the item does not display.
This lets you conditionally show or hide fields so your end customers only see the options that are relevant to them.
You can use Go template functions to create conditional statements. Replicated provides a set of Go template functions that you can use to evaluate conditions like the user's environment, their license entitlements, and their previous configuration choices. For more information, see [About Replicated Template Functions](/reference/template-functions-about).
:::note
`when` is a property of both groups and items. See [Group Properties > `when`](/reference/custom-resource-config#when) above.
:::
#### Requirements
* The `when` property accepts the following types of values:
* Booleans
* Strings that match "true", "True", "false", or "False"
* For the `when` property to evaluate to true, the values compared in the conditional statement must match exactly without quotes
- Do not apply `when` to items nested under a `radio`, `dropdown`, or `select_one` item. To conditionally show or hide `radio`, `dropdown`, or `select_one` items, apply the `when` property to the item itself.
#### Example
Display the `database_host` and `database_password` items only when the user selects `external` for the `db_type` item:
```yaml
- name: database_settings_group
title: Database Settings
items:
- name: db_type
title: Database Type
type: radio
default: external
items:
- name: external
title: External
- name: embedded
title: Embedded DB
- name: database_host
title: Database Hostname
type: text
when: repl{{ (ConfigOptionEquals "db_type" "external")}}
- name: database_password
title: Database Password
type: password
when: repl{{ (ConfigOptionEquals "db_type" "external")}}
```
[View a larger version of this image](/images/config-when-enabled.png)
[View a larger version of this image](/images/config-when-disabled.png)
### `validation`
Use the `validation` property to validate an item's value and specify custom validation rules that determine whether the value is valid.
You can use regex to validate whether an item's value matches the provided regular expression `pattern`. The regex pattern should be of the [RE2 regular expression](https://github.com/google/re2/wiki/Syntax) type and can validate the `text`, `textarea`, `password`, and `file` field types.
Based on specified validation rules, the item is validated and a validation message is returned if the validation rule is not satisfied. A default message is returned if there is an empty validation message.
The validation rules are as follows:
- An item is validated only when its value is not empty.
- Items of types `text`, `textarea`, `password`, and `file` are validated, but `repeatable` items are not validated.
- If an item is marked as `hidden` or if its `when` condition is set to `false`, the item is not validated.
- If a group `when` condition is set to `false`, the items in the group are not validated.
#### Limitation
The `validation` property doesn't support Go templating.
#### Example
Validates and returns if `password` value is not matching the regex.
The `jwt_token` file content is only validated if the file is uploaded since it is optional.
```
- name: smtp-settings
title: SMTP Settings
- name: smtp_password
title: SMTP Password
type: password
required: true
validation:
regex:
pattern: ^(?:[\w@#$%^&+=!*()_\-{}[\]:;"'<>,.?\/|]){8,16}$
message: The password must be between 8 and 16 characters long and can contain a combination of uppercase letters, lowercase letters, digits, and special characters.
- name: jwt_token
title: JWT token
type: file
validation:
regex:
pattern: ^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$
message: Upload a file with valid JWT token.
```
[View a larger version of this image](/images/regex_password_validation_error.png)
[View a larger version of this image](/images/regex_file_validation_error.png)
## Repeatable Items
A repeatable config item copies a YAML array entry or YAML document for as many values as are provided. Any number of values can be added to a repeatable item to generate additional copies.
To make an item repeatable, set `repeatable` to true:
```yaml
- name: ports_group
items:
- name: serviceport
title: Service Port
type: text
repeatable: true
```
Repeatable items do not use the `default` or `value` fields, but instead a `valuesByGroup` field.
`valuesByGroup` must have an entry for the parent Config Group name, with all of the default `key:value` pairs nested in the group. The repeatable item requires at least one default entry:
```yaml
valuesByGroup:
ports_group:
port-default-1: "80"
```
### Limitations
* Repeatable items work only for text, textarea, and file types.
* Repeatable item names must only consist of lower case alphanumeric characters.
* Repeatable items are only supported for Kubernetes manifests, not Helm charts.
### Template targets
Repeatable items require that you provide at least one `template`. The `template` defines a YAML target in the manifest to duplicate for each repeatable item.
Required fields for a template target are `apiVersion`, `kind`, and `name`.
`namespace` is an optional template target field to match a YAML document's `metadata.namespace` property when the same filename appears in multiple namespaces.
The installer duplicates the entire YAML node at the target, including nested fields.
The `yamlPath` field of the `template` must denote index position for arrays using square brackets. For example, `spec.ports[0]` selects the first port entry for duplication. The installer appends all duplicate YAML to the final array in the `yamlPath`.
`yamlPath` must end with an array.
**Example:**
```yaml
templates:
- apiVersion: v1
kind: Service
name: my-service
namespace: my-app
yamlPath: 'spec.ports[0]'
```
If the `yamlPath` field is not present, the installer replaces the entire YAML document matching the `template` with a copy for each repeatable item entry. The `metadata.name` field of the new document reflects the repeatable item `key`.
### Templating
Use the delimiters `repl[[ .itemName ]]` or `[[repl .itemName ]]` for repeat items. Place these delimiters anywhere inside the `yamlPath` target node:
```yaml
- port: repl{{ ConfigOption "[[repl .serviceport ]]" | ParseInt }}
name: '[[repl .serviceport ]]'
```
This repeatable templating is not compatible with sprig templating functions. Use it to insert repeatable `keys` into the manifest. You can nest repeatable templating inside Replicated config templating.
### Ordering
The installer processes repeatable templates before config template rendering.
The installer processes repeatable items in order of the template targets in the Config Spec file. Effectively, this ordering is from the top of the Config Spec, by Config Group, by Config Item, and then by template target.
```yaml
- name: ports_group
items:
- name: serviceport
title: Service Port
type: text
repeatable: true
templates:
- apiVersion: v1 #processed first
kind: Service
name: my-service
namespace: my-app
yamlPath: 'spec.ports[0]'
- apiVersion: v1 #processed second
kind: Service
name: my-service
namespace: my-app
{other item properties ...}
- name: other_ports
title: Other Service Port
type: text
repeatable: true
templates:
- apiVersion: v1 #processed third
kind: Service
name: my-other-service
namespace: my-app
{other item properties ...}
- name: deployments
items:
- name: deployment-name
title: Deployment Names
type: text
repeatable: true
templates:
- apiVersion: apps/v1 #processed fourth
kind: Deployment
name: my-deployment
namespace: my-app
{other item properties ...}
```
### Repeatable examples
In these examples, the release includes the default service port "80". When you add port 443 as an additional port on the config screen, The installer stores it in the ConfigValues file.
#### Repeatable item example for a yamlPath
**Config custom resource manifest file:**
```yaml
- name: ports_group
items:
- name: serviceport
title: Service Port
type: text
repeatable: true
templates:
- apiVersion: v1
kind: Service
name: my-service
namespace: my-app
yamlPath: spec.ports[0]
valuesByGroup:
ports_group:
port-default-1: "80"
```
**Config values:**
```yaml
apiVersion: kots.io/v1beta1
kind: ConfigValues
metadata:
name: example_app
spec:
values:
port-default-1:
repeatableItem: serviceport
value: "80"
serviceport-8jdn2bgd:
repeatableItem: serviceport
value: "443"
```
**Template manifest:**
```yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: my-app
spec:
type: NodePort
ports:
- port: repl{{ ConfigOption "[[repl .serviceport ]]" | ParseInt }}
name: '[[repl .serviceport ]]'
selector:
app: repeat_example
component: my-deployment
```
**After repeatable config processing:**
**Note**: This phase is internal to configuration rendering for KOTS. This example is only provided to further explain the templating process.*
```yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: my-app
spec:
type: NodePort
ports:
- port: repl{{ ConfigOption "port-default-1" | ParseInt }}
name: 'port-default-1'
- port: repl{{ ConfigOption "serviceport-8jdn2bgd" | ParseInt }}
name: 'serviceport-8jdn2bgd'
selector:
app: repeat_example
component: my-deployment
```
**Resulting manifest:**
```yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: my-app
spec:
type: NodePort
ports:
- port: 80
name: port-default-1
- port: 443
name: serviceport-8jdn2bgd
selector:
app: repeat_example
component: my-deployment
```
#### Repeatable Item Example for an Entire Document
**Config spec:**
```yaml
- name: ports_group
items:
- name: serviceport
title: Service Port
type: text
repeatable: true
templates:
- apiVersion: v1
kind: Service
name: my-service
namespace: my-app
valuesByGroup:
ports_group:
port-default-1: "80"
```
**Config values:**
```yaml
apiVersion: kots.io/v1beta1
kind: ConfigValues
metadata:
name: example_app
spec:
values:
port-default-1:
repeatableItem: serviceport
value: "80"
serviceport-8jdn2bgd:
repeatableItem: serviceport
value: "443"
```
**Template manifest:**
```yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: my-app
spec:
type: NodePort
ports:
- port: repl{{ ConfigOption "[[repl .serviceport ]]" | ParseInt }}
selector:
app: repeat_example
component: repl[[ .serviceport ]]
```
**After repeatable config processing:**
**Note**: This phase is internal to configuration rendering for KOTS. This example is only provided to further explain the templating process.*
```yaml
apiVersion: v1
kind: Service
metadata:
name: port-default-1
namespace: my-app
spec:
type: NodePort
ports:
- port: repl{{ ConfigOption "port-default-1" | ParseInt }}
selector:
app: repeat_example
component: port-default-1
---
apiVersion: v1
kind: Service
metadata:
name: serviceport-8jdn2bgd
namespace: my-app
spec:
type: NodePort
ports:
- port: repl{{ ConfigOption "serviceport-8jdn2bgd" | ParseInt }}
selector:
app: repeat_example
component: serviceport-8jdn2bgd
```
**Resulting manifest:**
```yaml
apiVersion: v1
kind: Service
metadata:
name: port-default-1
namespace: my-app
spec:
type: NodePort
ports:
- port: 80
selector:
app: repeat_example
component: port-default-1
---
apiVersion: v1
kind: Service
metadata:
name: serviceport-8jdn2bgd
namespace: my-app
spec:
type: NodePort
ports:
- port: 443
selector:
app: repeat_example
component: serviceport-8jdn2bgd
```
---
# ConfigValues
This topic describes the Replicated ConfigValues resource. Use ConfigValues to set application configuration values during automated or headless installations from the command line.
## Overview
The ConfigValues resource lists the values and defaults for each application configuration item defined in the Replicated [Config](custom-resource-config) resource in the release.
In automated or headless installations, end users set configuration values from the command line rather than through the UI. They provide a ConfigValues resource with the install command.
The following image shows how application configuration items defined a Config resource map to a ConfigValues resource:

[View a larger version of this image](/images/configvalues-diagram.png)
As shown in the preceding image, the `values` key in the ConfigValues resource lists each item from the Config resource by its `name`. For each item, the ConfigValues resource lists the user-supplied value and the default defined in the Config resource (if applicable).
## Example
```yaml
apiVersion: kots.io/v1beta1
kind: ConfigValues
spec:
values:
config_item_name:
default: example_default_value
value: example_value
boolean_config_item_name:
value: "1"
password_config_item_name:
valuePlaintext: exampleplaintextpassword
select_one_config_item_name:
default: default_option_name
value: selected_option_name
```
## Requirements
* Linux operating system
* cgroups v2 (required for Kubernetes versions 1.35 and later)
* x86-64 architecture
* systemd
* At least 2GB of memory and 2 CPU cores
* The disk on the host must have a maximum P99 write latency of 10 ms. This supports etcd performance and stability. For more information about the disk write latency requirements for etcd, see [Disks](https://etcd.io/docs/latest/op-guide/hardware/#disks) in _Hardware recommendations_ and [What does the etcd warning “failed to send out heartbeat on time” mean?](https://etcd.io/docs/latest/faq/) in the etcd documentation.
* The user performing the installation must have root access to the machine, such as with `sudo`.
* The data directory used by Embedded Cluster must have 40Gi or more of total space and be less than 80% full. By default, the data directory is `/var/lib/APP_SLUG`, where `APP_SLUG` is the unique slug of the application. The directory can be changed by passing the `--data-dir` flag with the Embedded Cluster `install` command. For more information, see [install](/embedded-cluster/v3/embedded-cluster-install).
Note that in addition to the primary data directory, Embedded Cluster creates directories and files in the following locations:
- `/etc/cni`
- `/etc/k0s`
- `/opt/cni`
- `/opt/containerd`
- `/run/calico`
- `/run/containerd`
- `/run/k0s`
- `/sys/fs/cgroup/kubepods`
- `/sys/fs/cgroup/system.slice/containerd.service`
- `/sys/fs/cgroup/system.slice/k0scontroller.service`
- `/usr/libexec/k0s`
- `/var/lib/calico`
- `/var/lib/cni`
- `/var/lib/containers`
- `/var/lib/kubelet`
- `/var/log/calico`
- `/var/log/containers`
- `/var/log/APP_SLUG`, where `APP_SLUG` is the unique slug for the application
- `/var/log/pods`
- `/usr/local/bin/k0s`
* (Online installations only) Access to replicated.app and proxy.replicated.com or your custom domain for each
* Embedded Cluster is based on k0s, so all k0s system requirements and external runtime dependencies apply. See [System requirements](https://docs.k0sproject.io/stable/system-requirements/) and [External runtime dependencies](https://docs.k0sproject.io/stable/external-runtime-deps/) in the k0s documentation.
## Limitation
Replicated template functions are not supported in the ConfigValues resource. To use a template function for a config item's value, add it to the `default` or `value` property in the [Config](custom-resource-config) resource instead.
For more information about working with Replicated template functions, see [About Replicated Template Functions](/reference/template-functions-about).
## ConfigValues spec
### values.[item_name].default
The item's default value, as defined in the [Config](custom-resource-config) custom resource in the release.
#### Example
```yaml
apiVersion: kots.io/v1beta1
kind: ConfigValues
spec:
values:
certificate_source:
default: generate_internal
deploy_postgres:
default: "1"
value: "0"
service_type:
default: cluster_ip
value: node_port
node_port_port:
default: "443"
value: "3000"
```
### values.[item_name].value
The user-supplied value for the application configuration item.
#### Example
```yaml
apiVersion: kots.io/v1beta1
kind: ConfigValues
spec:
values:
slack_clientid:
value: T057KR02S
slackernews_domain:
value: hello.ingress.replicatedcluster.com
slackernews_admin_user_emails:
value: mandy@nitflex.com, jeff@nitflex.com, anil@nitflex.com
service_type:
value: node_port
node_port_port:
value: "443"
```
:::note
For KOTS or Embedded Cluster v2 installations, the `value` property in the auto-generated ConfigValues might also contain one of the following:
* A value rendered by a Replicated template function. For example, a [`hidden`](/reference/custom-resource-config#hidden) item defined in the Config resource could use the Replicated [RandomString](/reference/template-functions-static-context#randomstring) template function to set the value with `value: repl{{ RandomString 40}}`. In this case, the template function generates the value for the item in the ConfigValues, not the user. For more information about using Replicated template functions, see [About Replicated Template Functions](/reference/template-functions-about).
* An encrypted empty string. For any `password` configuration items without a user-supplied value, the Admin Console sets the value to an empty string. In the ConfigValues generated for the installation, this empty string is automatically encrypted.
* An empty mapping (`{}`). For configuration items without a user-supplied `value` or a `default`, KOTS sets the value to `{}`.
:::
### values.[item_name].valuePlaintext {#valueplaintext}
A plain text value. For any configuration items of type [`password`](/reference/custom-resource-config#password), provide the password in plain text in the `valuePlaintext` property rather than in the `value` property.
During installation, the installer encrypts the values set in `valuePlaintext`. In the ConfigValues resource automatically generated as part of installation, the installer saves these encrypted values in `value` properties. The following image shows how the installer encrypts a `valuePlaintext` value and adds it to a `value` property during installation:

[View a larger version of this image](/images/configvalues-plaintext.png)
#### Example
```yaml
apiVersion: kots.io/v1beta1
kind: ConfigValues
spec:
values:
slack_bot_token:
valuePlaintext: examplebottoken
slack_clientsecret:
valuePlaintext: exampleclientsecret
slack_user_token:
valuePlaintext: exampleusertoken
```
## (KOTS and Embedded Cluster v2 Only) Download the ConfigValues for an installation {#download}
This section applies only to installations with KOTS in an existing cluster or with Embedded Cluster v2.
To get the ConfigValues file from an installed application instance:
1. Install the target release in a development environment. You can either install the release with Replicated Embedded Cluster or install in an existing cluster with KOTS. For more information, see [Online Installation with Embedded Cluster](/embedded-cluster/v3/installing-embedded) or [Online Installation in Existing Clusters](/enterprise/installing-existing-cluster).
1. Depending on the installer that you used, do one of the following to get the ConfigValues for the installed instance:
* **For Embedded Cluster installations**: In the Admin Console, go to the **View files** tab. In the filetree, go to **upstream > userdata** and open **config.yaml**, as shown in the image below:

[View a larger version of this image](/images/admin-console-view-files-configvalues.png)
* **For KOTS installations in an existing cluster**: Run the `kubectl kots get config` command to view the generated ConfigValues file:
```bash
kubectl kots get config --namespace APP_NAMESPACE --decrypt
```
Where:
* `APP_NAMESPACE` is the cluster namespace where KOTS is running.
* The `--decrypt` flag decrypts all configuration fields with `type: password`. In the downloaded ConfigValues file, the decrypted value is stored in a `valuePlaintext` field.
The output of the `kots get config` command shows the contents of the ConfigValues file. For more information about the `kots get config` command, including additional flags, see [kots get config](/reference/kots-cli-get-config).
---
# HelmChart v2
This topic describes the Replicated HelmChart v2 custom resource.
## Overview
Each Helm chart `.tgz` archive in a release requires a unique HelmChart custom resource. The HelmChart custom resource provides the Replicated installer with the instructions needed to process and deploy the given Helm chart.
The HelmChart custom resource also generates a list of required images for the chart, which is necessary for the following use cases:
* Air gap installations with the Helm CLI or with a Replicated installer
* Online installations with a Replicated installer where the user will push images to a local image registry
* Online or air gap installations that use the [Security Center (Alpha)](/vendor/security-center-about) to scan and report on Helm chart images
## Example
The following is an example manifest file for the HelmChart v2 custom resource:
```yaml
apiVersion: kots.io/v1beta2
kind: HelmChart
metadata:
name: samplechart
spec:
# chart identifies a matching chart from a .tgz
chart:
name: samplechart
chartVersion: 3.1.7
releaseName: samplechart-release-1
exclude: "repl{{ ConfigOptionEquals 'include_chart' 'include_chart_no'}}"
# weight determines the order that charts are applied, with lower weights first.
weight: 42
# helmUpgradeFlags specifies additional flags to pass to the `helm upgrade` command.
helmUpgradeFlags:
- --skip-crds
- --no-hooks
- --timeout
- 1200s
- --history-max=15
# values are used in the customer environment as a pre-render step
# these values are supplied to helm template
values:
postgresql:
enabled: repl{{ ConfigOptionEquals 'postgres_type' 'embedded_postgres'}}
optionalValues:
- when: "repl{{ ConfigOptionEquals 'postgres_type' 'external_postgres'}}"
recursiveMerge: false
values:
postgresql:
postgresqlDatabase: "repl{{ if ConfigOptionEquals 'postgres_type' 'external_postgres'}}repl{{ ConfigOption 'external_postgres_database'}}repl{{ end}}"
postgresqlUsername: "repl{{ if ConfigOptionEquals 'postgres_type' 'external_postgres'}}repl{{ ConfigOption 'external_postgres_username'}}repl{{ end}}"
postgresqlHost: "repl{{ if ConfigOptionEquals 'postgres_type' 'external_postgres'}}repl{{ ConfigOption 'external_postgres_host'}}repl{{ end}}"
postgresqlPassword: "repl{{ if ConfigOptionEquals 'postgres_type' 'external_postgres'}}repl{{ ConfigOption 'external_postgres_password'}}repl{{ end}}"
postgresqlPort: "repl{{ if ConfigOptionEquals 'postgres_type' 'external_postgres'}}repl{{ ConfigOption 'external_postgres_port'}}repl{{ end}}"
# namespace allows for a chart to be installed in an alternate namespace to
# the default
namespace: samplechart-namespace
# builder values render the chart with all images and manifests.
# builder is used to create `.airgap` packages and to support end users
# who use private registries
builder:
postgresql:
enabled: true
```
## Properties
### chart
The `chart` key allows for a mapping between the data in this definition and the chart archive itself.
You can create multiple HelmChart resources that all reference a single chart archive.
`chart` has the following properties:
| Property | Description |
| --- | --- |
| `chart.name` | The name of the chart. This value must exactly match the `name` field from a `Chart.yaml` in a `.tgz` chart archive that is also included in the release. If the names do not match, then the installation can error or fail. |
| `chart.chartVersion` | The version of the chart. This value must match the `version` field from a `Chart.yaml` in a `.tgz` chart archive that is also included in the release. |
#### Example
```yaml
apiVersion: kots.io/v1beta2
kind: HelmChart
metadata:
name: samplechart
spec:
chart:
name: samplechart
chartVersion: 3.1.7
```
### releaseName
Specifies the release name to use when installing this instance of the Helm chart.
Defaults to the chart name.
The release name must be unique across all charts deployed in the namespace.
To deploy multiple instances of the same Helm chart in a release,
add a separate HelmChart custom resource with a unique release name for each instance.
Must be a valid Helm release name that matches regex `^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$` and is no longer than 53 characters.
#### Example
```yaml
apiVersion: kots.io/v1beta2
kind: HelmChart
metadata:
name: samplechart
spec:
releaseName: samplechart-release-1
```
### weight
For installations with a Replicated installer,
`weight` specifies the installation order of the Helm charts in the release.
Charts are installed by weight in ascending order with lower weights first.
`weight` also determines the uninstall order,
where charts are uninstalled by weight in descending order with higher weights first.
For installations with the Helm CLI, the Replicated Enterprise Portal uses the `weight` property to order the list of charts in the installation and update instructions.
For more information, see [View Install and Update Instructions](/vendor/enterprise-portal-use#view-install-and-update-instructions) in _Access and Use the Enterprise Portal_.
**Supported values:** Positive or negative integers. **Default:** `0`
#### Example
```yaml
apiVersion: kots.io/v1beta2
kind: HelmChart
metadata:
name: samplechart
spec:
weight: 42
```
### helmUpgradeFlags
Specifies additional flags to pass to the `helm upgrade` command.
The Replicated installer runs `helm upgrade` for _all_ deployments, not just upgrades, by specifying the `--install` flag.
The Replicated installer passes these flags in addition to the flags it passes by default.
The values specified in this field take precedence if the installer already passes the same flag.
Template functions can parse the `helmUpgradeFlags` attribute.
For more information, see [About Replicated template functions](/reference/template-functions-about).
For non-boolean flags that require an additional argument, such as `--timeout 1200s`, you must use an equal sign (`=`) or specify the additional argument separately in the array.
:::note
KOTS passes `--wait` to Helm by default, which means Helm waits for all non-hook resources to reach a Ready state before running post-install or post-upgrade hooks. If a non-hook resource depends on a resource created by a hook (for example, a Deployment with an init container that waits for a database custom resource created by a post-install hook), this creates a circular deadlock. To avoid this, add `--wait=false` and `--wait-for-jobs=false` to `helmUpgradeFlags`. These flags are appended after the defaults and override them.
:::
#### Examples
```yaml
helmUpgradeFlags:
- --timeout
- 1200s
- --history-max=15
```
Disable the default `--wait` behavior to prevent deadlocks with post-install hooks:
```yaml
helmUpgradeFlags:
- --wait=false
- --wait-for-jobs=false
```
### exclude
When the installer processes your release, it excludes any Helm chart if the output of the `exclude` field is `true`.
Template functions can parse the `exclude` attribute.
See [About Replicated template functions](template-functions-about).
#### Example
```yaml
apiVersion: kots.io/v1beta2
kind: HelmChart
metadata:
name: samplechart
spec:
exclude: '{{repl ConfigOptionEquals "postgres_type" "external_postgres" }}'
```
### values
Use the `values` key to set or delete values in the corresponding Helm chart's `values.yaml` file.
Any values that you include in the `values` key must match values in the Helm chart `values.yaml`.
For example, `spec.values.images.pullSecret` in the HelmChart custom resource matches `images.pullSecret` in the Helm chart `values.yaml`.
During installation or upgrade with a Replicated installer, the installer merges `values` with the Helm chart `values.yaml` in the chart archive.
Only include values in the `values` key that you want to set or delete.
#### Examples
##### Set static values
```yaml
# Helm chart values.yaml
replicatedOnlyValue:
enabled: false
```
```yaml
# HelmChart custom resource
apiVersion: kots.io/v1beta2
kind: HelmChart
spec:
values:
replicatedOnlyValue:
enabled: true
```
##### Set values with Replicated Config template functions
Using Replicated template functions in the [Config](/reference/template-functions-config-context) context allows you to set Helm values based on user-supplied values from the Admin Console configuration page.
The following Helm chart `values.yaml` file contains `postgresql.enabled`, which is set to `false`:
```yaml
# Helm chart values.yaml
postgresql:
enabled: false
```
The following HelmChart custom resource contains a mapping to `postgresql.enabled` in its `values` key:
```yaml
# HelmChart custom resource
apiVersion: kots.io/v1beta2
kind: HelmChart
metadata:
name: samplechart
spec:
values:
postgresql:
enabled: repl{{ ConfigOptionEquals `postgres_type` `embedded_postgres`}}
```
The `values.postgresql.enabled` field in the HelmChart custom resource above uses the Replicated [ConfigOptionEquals](/reference/template-functions-config-context#configoptionequals) template function to evaluate the user's selection for a `postgres_type` configuration option.
During installation or upgrade, the template function is rendered to true or false based on the user's selction. Then, the Replicated installer sets the matching `postgresql.enabled` value in the Helm chart `values.yaml` file accordingly.
##### Set values with Replicated License template functions
Using Replicated template functions in the [License](/reference/template-functions-license-context) context allows you to set Helm values based on the unique license file used for installation or upgrade.
For example, the following HelmChart custom resource uses the Replicated [LiencseFieldValue](/reference/template-functions-license-context#licensefieldvalue) template function to evaluate if the license has the boolean `newFeatureEntitlement` field set to `true`:
```yaml
# HelmChart custom resource
apiVersion: kots.io/v1beta2
kind: HelmChart
metadata:
name: samplechart
spec:
values:
newFeature:
enabled: repl{{ LicenseFieldValue "newFeatureEntitlement" }}
```
During installation or upgrade, the LicenseFieldValue template function is rendered based on the user's license. Then, the Replicated installer sets the matching `newFeature.enabled` value in the Helm chart `values.yaml` file accordingly.
##### Delete a default value key
A common use case for deleting default value keys is when you include a community Helm chart as a dependency. Because you cannot control how the community chart is built and structured, you might want to change some of the default behavior. For more information about using a `null` value to delete a key, see [Deleting a Default Key](https://helm.sh/docs/chart_template_guide/values_files/#deleting-a-default-key) in the Helm documentation.
```yaml
# HelmChart custom resource
apiVersion: kots.io/v1beta2
kind: HelmChart
spec:
values:
exampleKey: "null"
```
### optionalValues
Use the `optionalValues` key to set values in the Helm chart `values.yaml` file when a conditional statement evaluates to true.
For example, a customer including an optional application component might need Helm chart values related to that component.
`optionalValues` includes the following properties:
| Property | Description |
| --- | --- |
| `optionalValues.when` | Defines a conditional statement that must evaluate to true for the Helm chart to apply the values in `optionalValues.values`. The Replicated installer defers evaluation of the conditional in `optionalValues.when` until render time in the customer environment. |
| `optionalValues.recursiveMerge` | The `optionalValues.recursiveMerge` boolean defines how the Replicated installer merges `values` and `optionalValues`. When `optionalValues.recursiveMerge` is false, the top level keys in `optionalValues` override the top level keys in `values`. When `optionalValues.recursiveMerge` is true, the installer includes all keys from `values` and `optionalValues`. In the case of a conflict where there is a matching key in `optionalValues` and `values`, the Replicated installer uses the value of the key from `optionalValues`. By default, `optionalValues.recursiveMerge` is false. For an example, see [Recursive merge](#recursive-merge) on this page.|
| `optionalValues.values` | Array of key value pairs to set in the Helm chart when the specified condition is true. Supports static values and Replicated template functions. |
#### Examples
##### Set optional values with Replicated template functions
```yaml
# Replicated HelmChart custom resource
apiVersion: kots.io/v1beta2
kind: HelmChart
metadata:
name: outline
spec:
chart:
name: outline
chartVersion: 0.7.3
releaseName: outline
namespace: outline
spec:
optionalValues:
- when: "repl{{ ConfigOptionEquals 'postgres_type' 'external_postgres' }}"
recursiveMerge: true
values:
externalPostgresql:
host: "repl{{ ConfigOption 'external_postgres_host' }}"
port: "repl{{ ConfigOption 'external_postgres_port' }}"
database: "repl{{ ConfigOption 'external_postgres_database' }}"
username: "repl{{ ConfigOption 'external_postgres_username' }}"
password: "repl{{ ConfigOption 'external_postgres_password' }}"
- when: "repl{{ ConfigOptionEquals 'redis_type' 'external_redis' }}"
recursiveMerge: true
values:
externalRedis:
host: "repl{{ ConfigOption 'external_redis_host' }}"
port: "repl{{ ConfigOption 'external_redis_port' }}"
password: "repl{{ ConfigOption 'external_redis_password' }}"
```
##### Recursive merge
The following HelmChart custom resource has both `values` and `optionalValues`:
```yaml
# HelmChart custom resource
apiVersion: kots.io/v1beta2
kind: HelmChart
spec:
values:
favorite:
drink:
hot: tea
cold: soda
dessert: ice cream
day: saturday
optionalValues:
- when: '{{repl ConfigOptionEquals "example_config_option" "1" }}'
recursiveMerge: false
values:
example_config_option:
enabled: true
favorite:
drink:
cold: lemonade
```
The associated Helm chart `values.yaml` file defines these key value pairs:
```yaml
# Helm chart values.yaml
favorite:
drink:
hot: coffee
cold: soda
dessert: pie
```
The associated Helm chart has the following `templates/configmap.yaml` file:
```yaml
# templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
data:
favorite_day: {{ .Values.favorite.day }}
favorite_dessert: {{ .Values.favorite.dessert }}
favorite_drink_cold: {{ .Values.favorite.drink.cold }}
favorite_drink_hot: {{ .Values.favorite.drink.hot }}
```
When `recursiveMerge` is `false`, the ConfigMap for the deployed application includes the following key value pairs:
```yaml
# templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
data:
favorite_day: null
favorite_dessert: pie
favorite_drink_cold: lemonade
favorite_drink_hot: coffee
```
When `recursiveMerge` is `true`, the ConfigMap for the deployed application includes the following key value pairs:
```yaml
# templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
data:
favorite_day: saturday
favorite_dessert: ice cream
favorite_drink_cold: lemonade
favorite_drink_hot: tea
```
### namespace
The `namespace` key specifies an alternative namespace to install the Helm chart.
By default, for Embedded Cluster v2 and KOTS existing cluster installations,
KOTS installs the chart in the same namespace as the Admin Console.
For Embedded Cluster v3 installations, Embedded Cluster installs the chart in a namespace named `| Level | Description |
|---|---|
| error | The rule is enabled and shows as an error. |
| warn | The rule is enabled and shows as a warning. |
| info | The rule is enabled and shows an informational message. |
| off | The rule is disabled. |
| Field Name | Description |
|---|---|
collectorName |
(Optional) A collector can specify the collectorName field. In some collectors, this field controls the path where result files are stored in the support bundle. |
exclude |
(Optional) (KOTS Only) Based on the runtime available configuration, a conditional can be specified in the exclude field. This is useful for deployment techniques that allow templating for Replicated KOTS and the optional KOTS Helm component. When this value is true, the collector is not included. |
| Field Name | Description |
|---|---|
collectorName |
(Optional) An analyzer can specify the collectorName field. |
exclude |
(Optional) (KOTS Only) A condition based on the runtime available configuration can be specified in the exclude field. This is useful for deployment techniques that allow templating for KOTS and the optional KOTS Helm component. When this value is true, the analyzer is not included. |
strict |
(Optional) (KOTS Only) An analyzer can be set to strict: true so that fail outcomes for that analyzer prevent the release from being deployed by KOTS until the vendor-specified requirements are met. When exclude: true is also specified, exclude overrides strict and the analyzer is not executed. |
| Field Name | Description |
|---|---|
file |
(Optional) Specifies a single file for redaction. |
files |
(Optional) Specifies multiple files for redaction. |
/my/test/glob/* matches /my/test/glob/file, but does not match /my/test/glob/subdir/file.
### removals
The `removals` object is required and defines the redactions that occur. This object supports the following fields. At least one of these fields must be specified:
| Field Name | Description |
|---|---|
regex |
(Optional) Allows a regular expression to be applied for removal and redaction on lines that immediately follow a line that matches a filter. The selector field is used to identify lines, and the redactor field specifies a regular expression that runs on the line after any line identified by selector. If selector is empty, the redactor runs on every line. Using a selector is useful for removing values from pretty-printed JSON, where the value to be redacted is pretty-printed on the line beneath another value.Matches to the regex are removed or redacted, depending on the construction of the regex. Any portion of a match not contained within a capturing group is removed entirely. The contents of capturing groups tagged mask are masked with ***HIDDEN***. Capturing groups tagged drop are dropped. |
values |
(Optional) Specifies values to replace with the string ***HIDDEN***. |
yamlPath |
(Optional) Specifies a .-delimited path to the items to be redacted from a YAML document. If an item in the path is the literal string *, the redactor is applied to all options at that level.Files that fail to parse as YAML or do not contain any matches are not modified. Files that do contain matches are re-rendered, which removes comments and custom formatting. Multi-document YAML is not fully supported. Only the first document is checked for matches, and if a match is found, later documents are discarded entirely. |
| Flag | Type | Description |
--rootdir |
string | Root directory where the YAML will be written (default `${HOME}` or `%USERPROFILE%`) |
--namespace |
string | Target namespace for the Admin Console |
--shared-password |
string | Shared password to use when deploying the Admin Console |
--http-proxy |
string | Sets HTTP_PROXY environment variable in all KOTS Admin Console components |
--http-proxy |
string | Sets HTTP_PROXY environment variable in all KOTS Admin Console |
--kotsadm-namespace |
string | Set to override the registry namespace of KOTS Admin Console images. Used for air gap installations. For more information, see [Air Gap Installation in Existing Clusters with KOTS](/enterprise/installing-existing-cluster-airgapped). Note: Replicated recommends that you use |
--kotsadm-registry |
string | Set to override the registry hostname and namespace of KOTS Admin Console images. Used for air gap installations. For more information, see [Air Gap Installation in Existing Clusters with KOTS](/enterprise/installing-existing-cluster-airgapped). |
--no-proxy |
string | Sets NO_PROXY environment variable in all KOTS Admin Console components |
--private-ca-configmap |
string | Name of a ConfigMap containing private CAs to add to the kotsadm deployment |
--registry-password |
string | Password to use to authenticate with the application registry. Used for air gap installations. |
--registry-username |
string | Username to use to authenticate with the application registry. Used for air gap installations. |
--with-minio |
bool | Set to true to include a local minio instance to be used for storage (default true) |
--minimal-rbac |
bool | Set to true to include a local minio instance to be used for storage (default true) |
--additional-namespaces |
string | Comma delimited list to specify additional namespace(s) managed by KOTS outside where it is to be deployed. Ignored without with --minimal-rbac=true |
--storage-class |
string | Sets the storage class to use for the KOTS Admin Console components. Default: unset, which means the default storage class will be used |
| Flag | Type | Description |
|---|---|---|
--ensure-rbac |
bool | When false, KOTS does not attempt to create the RBAC resources necessary to manage applications. Default: true. If a role specification is needed, use the generate-manifests command. |
-h, --help |
Help for the command. | |
--kotsadm-namespace |
string | Set to override the registry namespace of KOTS Admin Console images. Used for air gap installations. For more information, see [Air Gap Installation in Existing Clusters with KOTS](/enterprise/installing-existing-cluster-airgapped). Note: Replicated recommends that you use |
--kotsadm-registry |
string | Set to override the registry hostname and namespace of KOTS Admin Console images. Used for air gap installations. For more information, see [Air Gap Installation in Existing Clusters with KOTS](/enterprise/installing-existing-cluster-airgapped). |
--registry-password |
string | Password to use to authenticate with the application registry. Used for air gap installations. |
--registry-username |
string | Username to use to authenticate with the application registry. Used for air gap installations. |
--skip-rbac-check |
bool | When true, KOTS does not validate RBAC permissions. Default: false |
--strict-security-context |
bool |
Set to By default, KOTS Pods and containers are not deployed with a specific security context. When
The following shows the Default: |
--wait-duration |
string | Timeout out to be used while waiting for individual components to be ready. Must be in Go duration format. Example: 10s, 2m |
--with-minio |
bool | When true, KOTS deploys a local MinIO instance for storage and attempts to change any MinIO-based snapshots (hostpath and NFS) to the local-volume-provider plugin. See local-volume-provider in GitHub. Default: true |
| Flag | Type | Description |
--additional-annotations |
bool | Additional annotations to add to kotsadm pods. |
--additional-labels |
bool | Additional labels to add to kotsadm pods. |
--airgap |
bool | Set to true to run install in air gapped mode. Setting --airgap-bundle implies --airgap=true. Default: false. For more information, see Air Gap Installation in Existing Clusters with KOTS. |
--airgap-bundle |
string | Path to the application air gap bundle where application metadata will be loaded from. Setting --airgap-bundle implies --airgap=true. For more information, see Air Gap Installation in Existing Clusters with KOTS. |
--app-version-label |
string | The application version label to install. If not specified, the latest version is installed. |
--config-values |
string | Path to a manifest file containing configuration values. This manifest must be apiVersion: kots.io/v1beta1 and kind: ConfigValues. For more information, see Install with the KOTS CLI. |
--copy-proxy-env |
bool | Copy proxy environment variables from current environment into all Admin Console components. Default: false |
--disable-image-push |
bool | Set to true to disable images from being pushed to private registry. Default: false |
--ensure-rbac |
bool | When false, KOTS does not attempt to create the RBAC resources necessary to manage applications. Default: true. If a role specification is needed, use the [generate-manifests](kots-cli-admin-console-generate-manifests) command. |
-h, --help |
Help for the command. | |
--http-proxy |
string | Sets HTTP_PROXY environment variable in all Admin Console components. |
--https-proxy |
string | Sets HTTPS_PROXY environment variable in all Admin Console components. |
--kotsadm-namespace |
string | Set to override the registry namespace of KOTS Admin Console images. Used for air gap installations. For more information, see [Air Gap Installation in Existing Clusters with KOTS](/enterprise/installing-existing-cluster-airgapped). Note: Replicated recommends that you use |
--kotsadm-registry |
string | Set to override the registry hostname and namespace of KOTS Admin Console images. Used for air gap installations. For more information, see [Air Gap Installation in Existing Clusters with KOTS](/enterprise/installing-existing-cluster-airgapped). |
--license-file |
string | Path to a license file. |
--local-path |
string | Specify a local-path to test the behavior of rendering a Replicated application locally. Only supported on Replicated application types. |
--name |
string | Name of the application to use in the Admin Console. |
--no-port-forward |
bool | Set to true to disable automatic port forward. Default: false |
--no-proxy |
string | Sets NO_PROXY environment variable in all Admin Console components. |
--port |
string | Override the local port to access the Admin Console. Default: 8800 |
--private-ca-configmap |
string | Name of a ConfigMap containing private CAs to add to the kotsadm deployment. |
--preflights-wait-duration |
string | Timeout to be used while waiting for preflights to complete. Must be in [Go duration](https://pkg.go.dev/time#ParseDuration) format. For example, 10s, 2m. Default: 15m |
--registry-password |
string | Password to use to authenticate with the application registry. Used for air gap installations. |
--registry-username |
string | Username to use to authenticate with the application registry. Used for air gap installations. |
--repo |
string | Repo URI to use when installing a Helm chart. |
--shared-password |
string | Shared password to use when deploying the Admin Console. |
--skip-compatibility-check |
bool | Set to true to skip compatibility checks between the current KOTS version and the application. Default: false |
--skip-preflights |
bool | Set to true to skip preflight checks. Default: false. If any strict preflight checks are configured, the --skip-preflights flag is not honored because strict preflight checks must run and contain no failures before the application is deployed. For more information, see [Define Preflight Checks](/vendor/preflight-defining). |
--skip-rbac-check |
bool | Set to true to bypass RBAC check. Default: false |
--skip-registry-check |
bool | Set to true to skip the connectivity test and validation of the provided registry information. Default: false |
--strict-security-context |
bool |
Set to By default, KOTS Pods and containers are not deployed with a specific security context. When
The following shows the Default: |
--use-minimal-rbac |
bool | When set to true, KOTS RBAC permissions are limited to the namespace where it is installed. To use --use-minimal-rbac, the application must support namespace-scoped installations and the user must have the minimum RBAC permissions required by KOTS in the target namespace. For a complete list of requirements, see [Namespace-scoped RBAC Requirements](/enterprise/installing-general-requirements#namespace-scoped) in _Installation Requirements_. Default: false |
--wait-duration |
string | Timeout to be used while waiting for individual components to be ready. Must be in [Go duration](https://pkg.go.dev/time#ParseDuration) format. For example, 10s, 2m. Default: 2m |
--with-minio |
bool | When set to true, KOTS deploys a local MinIO instance for storage and uses MinIO for host path and NFS snapshot storage. Default: true |
--storage-class |
string | Sets the storage class to use for the KOTS Admin Console components. Default: unset, which means the default storage class will be used |
| Flag | Type | Description |
|---|---|---|
--force |
bool |
Removes the reference even if the application has already been deployed. |
--undeploy |
bool |
Un-deploys the application by deleting all its resources from the cluster. When Note: The following describes how
|
-n |
string |
The namespace where the target application is deployed. Use |
| Flag | Type | Description |
-h, --help |
Help for the command. | |
| `-n, --namespace` | string | The namespace of the Admin Console (required) |
| `--hostpath` | string | A local host path on the node |
--kotsadm-namespace |
string | Set to override the registry namespace of KOTS Admin Console images. Used for air gap installations. For more information, see [Air Gap Installation in Existing Clusters with KOTS](/enterprise/installing-existing-cluster-airgapped). Note: Replicated recommends that you use |
--kotsadm-registry |
string | Set to override the registry hostname and namespace of KOTS Admin Console images. Used for air gap installations. For more information, see [Air Gap Installation in Existing Clusters with KOTS](/enterprise/installing-existing-cluster-airgapped). |
--registry-password |
string | Password to use to authenticate with the application registry. Used for air gap installations. |
--registry-username |
string | Username to use to authenticate with the application registry. Used for air gap installations. |
| `--force-reset` | bool | Bypass the reset prompt and force resetting the nfs path. (default `false`) |
| `--output` | string | Output format. Supported values: `json` |
| Flag | Type | Description |
-h, --help |
Help for the command. | |
| `-n, --namespace` | string | The namespace of the Admin Console (required) |
| `--nfs-server` | string | The hostname or IP address of the NFS server (required) |
| `--nfs-path` | string | The path that is exported by the NFS server (required) |
--kotsadm-namespace |
string | Set to override the registry namespace of KOTS Admin Console images. Used for air gap installations. For more information, see [Air Gap Installation in Existing Clusters with KOTS](/enterprise/installing-existing-cluster-airgapped). Note: Replicated recommends that you use |
--kotsadm-registry |
string | Set to override the registry hostname and namespace of KOTS Admin Console images. Used for air gap installations. For more information, see [Air Gap Installation in Existing Clusters with KOTS](/enterprise/installing-existing-cluster-airgapped). |
--registry-password |
string | Password to use to authenticate with the application registry. Used for air gap installations. |
--registry-username |
string | Username to use to authenticate with the application registry. Used for air gap installations. |
| `--force-reset` | bool | Bypass the reset prompt and force resetting the nfs path. (default `false`) |
| `--output` | string | Output format. Supported values: `json` |
| Flag | Type | Description |
-h, --help |
Help for the command. | |
| `-n, --namespace` | string | The namespace of the Admin Console (required) |
| `--access-key-id` | string | The AWS access key ID to use for accessing the bucket (required) |
| `--bucket` | string | Name of the object storage bucket where backups should be stored (required) |
| `--endpoint` | string | The S3 endpoint (for example, http://some-other-s3-endpoint) (required) |
| `--path` | string | Path to a subdirectory in the object store bucket |
| `--region` | string | The region where the bucket exists (required) |
| `--secret-access-key` | string | The AWS secret access key to use for accessing the bucket (required) |
| `--cacert` | string | File containing a certificate bundle to use when verifying TLS connections to the object store |
| `--skip-validation` | bool | Skip the validation of the S3 bucket (default `false`) |
--kotsadm-namespace |
string | Set to override the registry namespace of KOTS Admin Console images. Used for air gap installations. For more information, see [Air Gap Installation in Existing Clusters with KOTS](/enterprise/installing-existing-cluster-airgapped). Note: Replicated recommends that you use |
--kotsadm-registry |
string | Set to override the registry hostname and namespace of KOTS Admin Console images. Used for air gap installations. For more information, see [Air Gap Installation in Existing Clusters with KOTS](/enterprise/installing-existing-cluster-airgapped). |
--registry-password |
string | Password to use to authenticate with the application registry. Used for air gap installations. |
--registry-username |
string | Username to use to authenticate with the application registry. Used for air gap installations. |
| Description | Notifies if any manifest file has allowPrivilegeEscalation set to true. |
|---|---|
| Level | Info |
| Applies To | All files |
| Example | Example of matching YAML for this rule: |
| Description | Requires an application icon. |
|---|---|
| Level | Warn |
| Applies To |
Files with kind: Application and apiVersion: kots.io/v1beta1.
|
| Example | Example of correct YAML for this rule: |
| Description |
Requires an Application custom resource manifest file. Accepted value for |
|---|---|
| Level | Warn |
| Example | Example of matching YAML for this rule: |
| Description |
Requires statusInformers.
|
|---|---|
| Level | Warn |
| Applies To |
Files with kind: Application and apiVersion: kots.io/v1beta1.
|
| Example | Example of correct YAML for this rule: |
| Description |
Enforces valid types for Config items. For more information, see Items in Config. |
|---|---|
| Level | Error |
| Applies To | All files |
| Example |
| Description | Enforces that all ConfigOption items do not reference themselves. |
|---|---|
| Level | Error |
| Applies To |
Files with kind: Config and apiVersion: kots.io/v1beta1.
|
| Example | |
| Description |
Requires all ConfigOption items to be defined in the Config custom resource manifest file.
|
|---|---|
| Level | Warn |
| Applies To | All files |
| Description | Enforces that sub-templated ConfigOption items must be repeatable. |
|---|---|
| Level | Error |
| Applies To | All files |
| Description |
Requires ConfigOption items with any of the following names to have
|
|---|---|
| Level | Warn |
| Applies To | All files |
| Example | Example of correct YAML for this rule: |
| Description |
Enforces valid For more information, see when in Config. |
|---|---|
| Level | Error |
| Applies To | Files with kind: Config and apiVersion: kots.io/v1beta1. |
| Description |
Enforces valid RE2 regular expressions pattern when regex validation is present. For more information, see Validation in Config. |
|---|---|
| Level | Error |
| Applies To | Files with kind: Config and apiVersion: kots.io/v1beta1. |
| Example |
| Description |
Enforces valid item type when regex validation is present. Item type should be For more information, see Validation in Config. |
|---|---|
| Level | Error |
| Applies To | Files with kind: Config and apiVersion: kots.io/v1beta1. |
| Example |
| Description |
Requires a Config custom resource manifest file. Accepted value for Accepted value for |
|---|---|
| Level | Warn |
| Example | Example of matching YAML for this rule: |
| Description | Notifies if any manifest file has a container image tag appended with
:latest. |
|---|---|
| Level | Info |
| Applies To | All files |
| Example | Example of matching YAML for this rule: |
| Description | Disallows any manifest file having a container image tag that includes LocalImageName. |
|---|---|
| Level | Error |
| Applies To | All files |
| Example | Example of matching YAML for this rule: |
| Description | Notifies if a spec.container has no resources.limits field. |
|---|---|
| Level | Info |
| Applies To | All files |
| Example | Example of matching YAML for this rule: |
| Description | Notifies if a spec.container has no resources.requests field. |
|---|---|
| Level | Info |
| Applies To | All files |
| Example | Example of matching YAML for this rule: |
| Description | Notifies if a manifest file has no resources field. |
|---|---|
| Level | Info |
| Applies To | All files |
| Example | Example of matching YAML for this rule: |
| Description |
Disallows using the deprecated kURL installer
|
|---|---|
| Level | Warn |
| Applies To |
Files with kind: Installer and apiVersion: kurl.sh/v1beta1.
|
| Example |
| Description |
Enforces unique |
|---|---|
| Level | Error |
| Applies To |
Files with kind: HelmChart and apiVersion: kots.io/v1beta1.
|
| Description |
Disallows duplicate Replicated custom resources.
A release can only include one of each This rule disallows inclusion of more than one file with:
|
|---|---|
| Level | Error |
| Applies To | All files |
| Description |
Notifies if any manifest file has a Replicated strongly recommends not specifying a namespace to allow for flexibility when deploying into end user environments. For more information, see Managing Application Namespaces. |
|---|---|
| Level | Info |
| Applies To | All files |
| Example | Example of matching YAML for this rule: |
| Description | Requires that a |
|---|---|
| Level | Error |
| Applies To |
Releases with a HelmChart custom resource manifest file containing kind: HelmChart and apiVersion: kots.io/v1beta1.
|
| Description | Enforces that a HelmChart custom resource manifest file with |
|---|---|
| Level | Error |
| Applies To |
Releases with a *.tar.gz archive file present.
|
| Description |
Runs Each top-level violation is reported as a separate finding so that individual schema errors are easier to read and address. For more information about |
|---|---|
| Level | Error |
| Applies To |
Helm v3 and later chart archives (*.tar.gz) that have a matching HelmChart custom resource. HelmChart custom resources with helmVersion: v2 are skipped.
|
| Description |
Enforces valid
|
|---|---|
| Level | Warn |
| Applies To |
Files with kind: HelmChart and apiVersion: kots.io/v1beta1.
|
| Example | Example of correct YAML for this rule: |
| Description |
Enforces valid Replicated kURL add-on versions. kURL add-ons included in the kURL installer must pin specific versions rather than |
|---|---|
| Level | Error |
| Applies To |
Files with
|
| Example |
| Description |
Requires Accepts a |
|---|---|
| Level | Error |
| Applies To |
Files with kind: Application and apiVersion: kots.io/v1beta1.
|
| Example | Example of correct YAML for this rule: |
| Description | Enforces valid YAML after rendering the manifests using the Config spec. |
|---|---|
| Level | Error |
| Applies To | YAML files |
| Example |
| Description |
Requires Accepts a |
|---|---|
| Level | Error |
| Applies To |
Files with kind: Application and apiVersion: kots.io/v1beta1
|
| Example | Example of correct YAML for this rule: |
| Description | Requires that the value of a property matches that property's expected type. |
|---|---|
| Level | Error |
| Applies To | All files |
| Example |
| Description | Enforces valid YAML. |
|---|---|
| Level | Error |
| Applies To | YAML files |
| Example |
| Description | Notifies if any manifest file may contain secrets. |
|---|---|
| Level | Info |
| Applies To | All files |
| Example | Example of matching YAML for this rule: |
| Description | Requires the apiVersion: field in all files. |
|---|---|
| Level | Error |
| Applies To | All files |
| Example | Example of correct YAML for this rule: |
| Description | Requires the kind: field in all files. |
|---|---|
| Level | Error |
| Applies To | All files |
| Example | Example of correct YAML for this rule: |
| Description |
Requires that each The linter cannot evaluate If you configure status informers for Helm-managed resources, you can ignore |
|---|---|
| Level | Warning |
| Applies To |
Compares |
| Description |
Requires a Preflight custom resource manifest file with:
and one of the following:
|
|---|---|
| Level | Warn |
| Example | Example of matching YAML for this rule: |
| Description | Notifies if any manifest file has privileged set to true. |
|---|---|
| Level | Info |
| Applies To | All files |
| Example | Example of matching YAML for this rule: |
| Description |
Enforces ConfigOption For more information, see Repeatable Item Template Targets in Config. |
|---|---|
| Level | Error |
| Applies To | All files |
| Example | Example of correct YAML for this rule: |
| Description |
Disallows repeating Config item with undefined For more information, see Repeatable Item Template Targets in Config. |
|---|---|
| Level | Error |
| Applies To | All files |
| Example | Example of correct YAML for this rule: |
| Description |
Disallows repeating Config item with undefined For more information, see Repeatable Items in Config. |
|---|---|
| Level | Error |
| Applies To | All files |
| Example | Example of correct YAML for this rule: |
| Description | Notifies if any manifest file has replicas set to 1. |
|---|---|
| Level | Info |
| Applies To | All files |
| Example | Example of matching YAML for this rule: |
| Description | Notifies if a spec.container has no resources.limits.cpu field. |
|---|---|
| Level | Info |
| Applies To | All files |
| Example | Example of matching YAML for this rule: |
| Description | Notifies if a spec.container has no resources.limits.memory field. |
|---|---|
| Level | Info |
| Applies To | All files |
| Example | Example of matching YAML for this rule: |
| Description | Notifies if a spec.container has no resources.requests.cpu field. |
|---|---|
| Level | Info |
| Applies To | All files |
| Example | Example of matching YAML for this rule: |
| Description | Notifies if a spec.container has no resources.requests.memory field. |
|---|---|
| Level | Info |
| Applies To | All files |
| Example | Example of matching YAML for this rule: |
| Description |
Requires a Troubleshoot manifest file. Accepted values for
Accepted values for
|
|---|---|
| Level | Warn |
| Example | Example of matching YAML for this rule: |
| Description |
Notifies if a Helm chart contains a top-level Preflight and SupportBundle custom resources cannot be applied directly from a Helm chart — they require cluster-side CRDs that are not available in most shared clusters and that need cluster-admin permissions to install. Embed the spec in a Kubernetes Secret with the |
|---|---|
| Level | Warn |
| Applies To | Helm chart archives in the release |
| Description | Notifies if a spec.volumes has hostPath
set to /var/run/docker.sock. |
|---|---|
| Level | Info |
| Applies To | All files |
| Example | Example of matching YAML for this rule: |
| Description | Notifies if a spec.volumes has defined a hostPath. |
|---|---|
| Level | Info |
| Applies To | All files |
| Example | Example of matching YAML for this rule: |
| Filter | JSON key | Required | Options |
|---|---|---|---|
| Application | appId |
No | Any application in your account |
| Customer | customerId |
No | Any customer for the selected application |
| Access Method | accessMethod |
No | invite, self_signup, saml_jit |
| License Type | licenseType |
No | paid, trial, community, dev |
| Access Type | accessType |
No |
First Access for Selected License Type only tracks Enterprise Portal access events that occur after March 27, 2026. |
| Filter | JSON key | Required | Options |
|---|---|---|---|
| Application | appId |
No | Any application in your account |
| Channel | channelId |
No | Any channel for the selected application |
| Customer | customerId |
No | Any customer for the selected application |
| License Type | licenseType |
No | paid, trial, community, dev |
| Asset Type | assetType |
No | helm_chart, embedded_cluster_bundle, proxy_image |
| Pull Type | pullType |
No |
For customers who pulled software before March 18, 2026, the Vendor Portal applies |
[View a larger version of this image](/images/customer-expiration-policy.png)
1. Install the Replicated SDK as a standalone component in your cluster. This is called _integration mode_. Installing in integration mode allows you to develop locally against the SDK API without needing to create releases for your application in the vendor portal. See [Develop Against the SDK API](/vendor/replicated-sdk-development).
1. In your application, use the `/api/v1/license/fields/expires_at` endpoint to get the `expires_at` field that you defined in the previous step.
**Example:**
```bash
curl replicated:3000/api/v1/license/fields/expires_at
```
```json
{
"name": "expires_at",
"title": "Expiration",
"description": "License Expiration",
"value": "2023-05-30T00:00:00Z",
"valueType": "String",
"signature": {
"v1": "c6rsImpilJhW0eK+Kk37jeRQvBpvWgJeXK2M..."
}
}
```
1. Add logic to your application to revoke access if the current date and time is more recent than the expiration date of the license.
1. (Recommended) Use signature verification in your application to ensure the integrity of the license field. See [Verify License Field Signatures with the Replicated SDK API](/vendor/licenses-verify-fields-sdk-api).
---
# replicated
Manage your Commercial Software Distribution Lifecycle using Replicated
### Synopsis
The 'replicated' CLI allows Replicated customers (vendors) to manage their Commercial Software Distribution Lifecycle (CSDL) using the Replicated API.
### Options
```
--app string The app slug or app id to use in all calls
--debug Enable debug output
-h, --help help for replicated
-o, --output string The output format to use. Supported formats vary by command (json, table, wide). (default 'table', override with REPLICATED_OUTPUT env var) (default "table")
--profile string The authentication profile to use for this command
--token string The API token to use to access your app in the Vendor API
```
### SEE ALSO
* [replicated api](replicated-cli-api) - Make ad-hoc API calls to the Replicated API
* [replicated app](replicated-cli-app) - Manage applications
* [replicated channel](replicated-cli-channel) - Manage channels
* [replicated cluster](replicated-cli-cluster) - Manage test Kubernetes clusters.
* [replicated completion](replicated-cli-completion) - Generate completion script
* [replicated config](replicated-cli-config) - Manage .replicated configuration
* [replicated customer](replicated-cli-customer) - Manage customers
* [replicated default](replicated-cli-default) - Manage default values used by other commands
* [replicated installer](replicated-cli-installer) - Manage Kubernetes installers
* [replicated instance](replicated-cli-instance) - Manage instances
* [replicated login](replicated-cli-login) - Log in to Replicated
* [replicated logout](replicated-cli-logout) - Logout from Replicated
* [replicated network](replicated-cli-network) - Manage test networks for VMs and Clusters
* [replicated notification](replicated-cli-notification) - Manage event notifications
* [replicated policy](replicated-cli-policy) - Manage RBAC policies
* [replicated profile](replicated-cli-profile) - Manage authentication profiles
* [replicated registry](replicated-cli-registry) - Manage registries
* [replicated release](replicated-cli-release) - Manage app releases
* [replicated version](replicated-cli-version) - Print the current version and exit
* [replicated vm](replicated-cli-vm) - Manage test virtual machines.
---
# About Replicated template functions
This topic describes Replicated template functions, including information about use cases, template function contexts, syntax.
## Overview
Replicated provides a set of custom template functions based on the Go text/template library.
Common use cases for Replicated template functions include rendering values during installation or upgrade, such as:
* Customer-specific license field values
* User-provided configuration values
* Information about the customer environment, such the number of nodes or the Kubernetes version in the cluster where the application is installed
* Random strings
Replicated template functions can also be used to work with integer, boolean, float, and string values, such as doing mathematical operations, trimming leading and trailing spaces, or converting string values to integers or booleans.
Replicated template functions support all functionality of the Go templating language, including if statements, loops, and variables.
For more information about the Go library, see [text/template](https://golang.org/pkg/text/template/) in the Go documentation.
## Supported file types
You can use Replicated template functions in Kubernetes manifest files, such as:
* Custom resources in the `kots.io` API group like Application, Config, or HelmChart
* Custom resources in other API groups like Preflight or SupportBundle
* Kubernetes objects like Deployments, Services, Secrets, or ConfigMaps
* Kubernetes Operators
Replicated template functions are _not_ directly supported in Helm charts.
However, the HelmChart custom resource provides a way to map values rendered by Replicated template functions to Helm chart values.
This allows you to use Replicated template functions with Helm charts without making changes to those Helm charts.
For information about how to map values from the HelmChart custom resource to Helm chart `values.yaml` files, see [values](/reference/custom-resource-helmchart-v2#values) in _HelmChart v2_.
## Template function rendering
During application installation and upgrade, Replicated templates all Kubernetes manifest files in a release at the same time during a single process.
The Config custom resource is an exception.
For the [Config](/reference/custom-resource-config) custom resource,
Replicated templates each item separately.
This allows you to use template functions in fields in the Config custom resource that render user-supplied values from other fields.
For examples of this, see [Template function examples](/reference/template-functions-examples).
## Limitations
* Not all fields in the Config and Application custom resources support templating. For more information, see [Application](/reference/custom-resource-application) and [Config](/reference/custom-resource-config).
* The [Embedded Cluster Config](/embedded-cluster/v3/embedded-config) resource doesn't support Go templating in any fields.
* Replicated template functions are not directly supported in Helm charts. For more information, see [Supported file types](#supported-file-types) on this page.
* For installations with Embedded Cluster v3, the following template functions aren't supported:
* HasLocalRegistry
* LocalRegistryAddress
* LocalRegistryHost
* LocalRegistryNamespace
* LocalImageName
These template functions are typically used to conditionally rewrite image references in air gap installations to reference the local image registry.
For Embedded Cluster v3 installations, use the ReplicatedImageName and ReplicatedImageRegistry template functions instead. For more information, see [Template Functions for Embedded Cluster](/embedded-cluster/v3/template-functions).
## Syntax {#syntax}
The Replicated template function syntax supports the following functionally equivalent delimiters:
* [`repl{{ ... }}`](#syntax-integer)
* [`{{repl ... }}`](#syntax-string)
### Syntax requirements
Replicated template function syntax has the following requirements:
* For both syntax options, `repl{{ ... }}` and `{{repl ... }}`, there must be no whitespace between `repl` and the `{{` delimiter.
* The manifests where you use Replicated template functions must be valid YAML, because Replicated lints the YAML manifests before rendering the template functions.
### `repl{{ ... }}` {#syntax-integer}
Replicated recommends this syntax for most use cases.
Replicated strips any quotation marks wrapped around this syntax during rendering. If you need the rendered value in quotes, pipe into quote (`| quote`) or use the [`{{repl ... }}`](#syntax-string) syntax instead.
#### Integer example
```yaml
http:
port: repl{{ ConfigOption "load_balancer_port" }}
```
```yaml
http:
port: 8888
```
#### Example with `| quote`
```yaml
customTag: repl{{ ConfigOption "tag" | quote }}
```
```yaml
customTag: 'key: value'
```
#### If-else example
```yaml
http:
port: repl{{ if ConfigOptionEquals "ingress_type" "load_balancer" }}repl{{ ConfigOption "load_balancer_port" }}repl{{ else }}8081repl{{ end }}
```
```yaml
http:
port: 8081
```
For more examples, see [Template function examples](/reference/template-functions-examples).
### `{{repl ... }}` {#syntax-string}
Use this syntax when placing delimiters outside the template function improves YAML readability, such as in multi-line or if-else statements.
To use this syntax at the beginning of a YAML value, you must wrap it in quotes. YAML values cannot start with `{`, and KOTS requires valid YAML manifests.
When you wrap this syntax in quotes, the rendered value is also wrapped in quotes.
#### Example with quotes
The following example includes quotes because it appears at the beginning of a YAML value:
```yaml
customTag: '{{repl ConfigOption "tag" }}'
```
```yaml
customTag: 'key: value'
```
#### If-else example
```yaml
my-service:
type: '{{repl if ConfigOptionEquals "ingress_type" "load_balancer" }}LoadBalancer{{repl else }}ClusterIP{{repl end }}'
```
```yaml
my-service:
type: 'LoadBalancer'
```
For more examples, see [Template Function Examples](/reference/template-functions-examples).
## Contexts {#contexts}
Replicated groups template functions into different contexts based on the lifecycle phase when the function is available and the data provided.
### Static context
The context necessary to render the static template functions is always available.
The static context also includes the Masterminds Sprig function library. For more information, see [Sprig Function Documentation](http://masterminds.github.io/sprig/) on the sprig website.
For a list of all Replicated template functions available in the static context, see [Static Context](template-functions-static-context).
### Config context
Template functions in the config context are available when rendering an application that includes the Replicated [Config](/reference/custom-resource-config) custom resource. This custom resource defines the app configuration screen in the Replicated installer UI. At execution time, template functions in the config context also can use the static context functions. For more information about configuring the config screen, see [About the Configuration Screen](/vendor/config-screen-about).
For a list of all Replicated template functions available in the config context, see [Config Context](template-functions-config-context).
### License context
Template functions in the license context have access to customer license and version data. For more information about managing customer licenses, see [About Customers and Licensing](/vendor/licenses-about).
For a list of all Replicated template functions available in the license context, see [License Context](template-functions-license-context).
### kURL context
:::note
Replicated kURL is available only for existing customers. If you are not an existing kURL user, use Replicated Embedded Cluster instead. For more information, see [Use Embedded Cluster](/embedded-cluster/v3/embedded-overview).
kURL is a Generally Available (GA) product for existing customers. For more information about the Replicated product lifecycle phases, see [Support Lifecycle Policy](/vendor/policies-support-lifecycle).
:::
Template functions in the kURL context have access to information about applications installed with Replicated kURL. For more information about kURL, see [Introduction to kURL](/vendor/kurl-about).
For a list of all Replicated template functions available in the kURL context, see [kURL Context](template-functions-kurl-context).
---
# Config Context
This topic provides a list of the Replicated template functions in the Config context.
Template functions in the config context are available when rendering an application that includes the Replicated [Config](/reference/custom-resource-config) custom resource. This custom resource defines the app configuration screen in the Replicated installer UI. At execution time, template functions in the config context also can use the static context functions. For more information about configuring the config screen, see [About the Configuration Screen](/vendor/config-screen-about).
## ConfigOption
```go
func ConfigOption(optionName string) string
```
Returns the value of the specified option from the Replicated Config custom resource as a string.
For the `file` config option type, `ConfigOption` returns the base64 encoded file. To return the decoded contents of a file, use [ConfigOptionData](#configoptiondata) instead.
```yaml
'{{repl ConfigOption "hostname" }}'
```
#### Example
The following [HelmChart](/reference/custom-resource-helmchart-v2) custom resource uses the ConfigOption template function to set the port, node port, and annotations for a LoadBalancer service using the values supplied by the user on the config screen. These values are then mapped to the `values.yaml` file for the associated Helm chart during deployment.
```yaml
# HelmChart custom resource
apiVersion: kots.io/v1beta2
kind: HelmChart
metadata:
name: samplechart
spec:
chart:
name: samplechart
chartVersion: 3.1.7
values:
myapp:
service:
type: LoadBalancer
port: repl{{ ConfigOption "myapp_load_balancer_port"}}
nodePort: repl{{ ConfigOption "myapp_load_balancer_node_port"}}
annotations: repl{{ ConfigOption `myapp_load_balancer_annotations` | nindent 14 }}
```
For more information, see [values](/reference/custom-resource-helmchart-v2#values) in _HelmChart v2_.
## ConfigOptionData
```go
func ConfigOptionData(optionName string) string
```
For the `file` config option type, `ConfigOptionData` returns the base64 decoded contents of the file. To return the base64 encoded file, use [ConfigOption](#configoption) instead.
```yaml
'{{repl ConfigOptionData "ssl_key"}}'
```
#### Example
The following [HelmChart](/reference/custom-resource-helmchart-v2) custom resource uses the ConfigOptionData template function to set the TLS cert and key using the files supplied by the user on the config screen. These values are then mapped to the `values.yaml` file for the associated Helm chart during deployment.
```yaml
# HelmChart custom resource
apiVersion: kots.io/v1beta2
kind: HelmChart
metadata:
name: samplechart
spec:
chart:
name: samplechart
chartVersion: 3.1.7
values:
myapp:
tls:
enabled: true
genSelfSignedCert: repl{{ ConfigOptionEquals "myapp_ingress_tls_type" "self_signed" }}
cert: repl{{ print `|`}}repl{{ ConfigOptionData `tls_certificate_file` | nindent 12 }}
key: repl{{ print `|`}}repl{{ ConfigOptionData `tls_private_key_file` | nindent 12 }}
```
For more information, see [values](/reference/custom-resource-helmchart-v2#values) in _HelmChart v2_.
## ConfigOptionFilename
```go
func ConfigOptionFilename(optionName string) string
```
`ConfigOptionFilename` returns the filename associated with a `file` config option.
It will return an empty string if used erroneously with other types.
```yaml
'{{repl ConfigOptionFilename "pom_file"}}'
```
#### Example
For example, if you have the following Config defined:
```yaml
apiVersion: kots.io/v1beta1
kind: Config
metadata:
name: my-application
spec:
groups:
- name: java_settings
title: Java Settings
description: Configures the Java Server build parameters
items:
- name: pom_file
type: file
required: true
```
The following example shows how to use `ConfigOptionFilename` in a Pod Spec to mount a file:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: configmap-demo-pod
spec:
containers:
- name: some-java-app
image: busybox
command: ["bash"]
args:
- "-C"
- "cat /config/{{repl ConfigOptionFilename pom_file}}"
volumeMounts:
- name: config
mountPath: "/config"
readOnly: true
volumes:
- name: config
configMap:
name: demo-configmap
items:
- key: data_key_one
path: repl{{ ConfigOptionFilename pom_file }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: demo-configmap
data:
data_key_one: repl{{ ConfigOptionData pom_file }}
```
## ConfigOptionEquals
```go
func ConfigOptionEquals(optionName string, expectedValue string) bool
```
Returns true if the configuration option value is equal to the supplied value.
```yaml
'{{repl ConfigOptionEquals "http_enabled" "1" }}'
```
#### Example
The following [HelmChart](/reference/custom-resource-helmchart-v2) custom resource uses the ConfigOptionEquals template function to set the `postgres.enabled` value depending on if the user selected the `embedded_postgres` option on the config screen. This value is then mapped to the `values.yaml` file for the associated Helm chart during deployment.
```yaml
# HelmChart custom resource
apiVersion: kots.io/v1beta2
kind: HelmChart
metadata:
name: samplechart
spec:
chart:
name: samplechart
chartVersion: 3.1.7
values:
postgresql:
enabled: repl{{ ConfigOptionEquals `postgres_type` `embedded_postgres`}}
```
For more information, see [values](/reference/custom-resource-helmchart-v2#values) in _HelmChart v2_.
## ConfigOptionNotEquals
```go
func ConfigOptionNotEquals(optionName string, expectedValue string) bool
```
Returns true if the configuration option value is not equal to the supplied value.
```yaml
'{{repl ConfigOptionNotEquals "http_enabled" "1" }}'
```
## LocalRegistryAddress
:::note
The LocalRegistryAddress template function is not supported for installations with Embedded Cluster v3. See [Template Functions for Embedded Cluster (Beta)](/embedded-cluster/v3/template-functions).
:::
```go
func LocalRegistryAddress() string
```
Returns the local registry host or host/namespace that's configured.
This will always return everything before the image name and tag.
## LocalRegistryHost
:::note
The LocalRegistryHost template function is not supported for installations with Embedded Cluster v3. See [Template Functions for Embedded Cluster (Beta)](/embedded-cluster/v3/template-functions).
:::
```go
func LocalRegistryHost() string
```
Returns the host of the local registry that the user configured. Alternatively, for air gap installations with Replicated Embedded Cluster or Replicated kURL, LocalRegistryHost returns the host of the built-in registry.
Includes the port if one is specified.
#### Example
The following [HelmChart](/reference/custom-resource-helmchart-v2) custom resource uses the HasLocalRegistry, LocalRegistryHost, and LocalRegistryNamespace template functions to conditionally rewrite an image registry and repository depending on if a local registry is used. These values are then mapped to the `values.yaml` file for the associated Helm chart during deployment.
```yaml
# HelmChart custom resource
apiVersion: kots.io/v1beta2
kind: HelmChart
metadata:
name: samplechart
spec:
chart:
name: samplechart
chartVersion: 3.1.7
values:
myapp:
image:
registry: '{{repl HasLocalRegistry | ternary LocalRegistryHost "images.mycompany.com" }}'
repository: '{{repl HasLocalRegistry | ternary LocalRegistryNamespace "proxy/myapp/quay.io/my-org" }}/nginx'
tag: v1.0.1
```
For more information, see [values](/reference/custom-resource-helmchart-v2#values) in _HelmChart v2_.
## LocalRegistryNamespace
:::note
The LocalRegistryNamespace template function is not supported for installations with Embedded Cluster v3. See [Template Functions for Embedded Cluster (Beta)](/embedded-cluster/v3/template-functions).
:::
```go
func LocalRegistryNamespace() string
```
Returns the namespace of the local registry that the user configured. Alternatively, for air gap installations with Embedded Cluster or kURL, LocalRegistryNamespace returns the namespace of the built-in registry.
#### Example
The following [HelmChart](/reference/custom-resource-helmchart-v2) custom resource uses the HasLocalRegistry, LocalRegistryHost, and LocalRegistryNamespace template functions to conditionally rewrite an image registry and repository depending on if a local registry is used. These values are then mapped to the `values.yaml` file for the associated Helm chart during deployment.
```yaml
# HelmChart custom resource
apiVersion: kots.io/v1beta2
kind: HelmChart
metadata:
name: samplechart
spec:
chart:
name: samplechart
chartVersion: 3.1.7
values:
myapp:
image:
registry: '{{repl HasLocalRegistry | ternary LocalRegistryHost "images.mycompany.com" }}'
repository: '{{repl HasLocalRegistry | ternary LocalRegistryNamespace "proxy/myapp/quay.io/my-org" }}/nginx'
tag: v1.0.1
```
For more information, see [values](/reference/custom-resource-helmchart-v2#values) in _HelmChart v2_.
## LocalImageName
:::note
The LocalImageName template function is not supported for installations with Embedded Cluster v3. See [Template Functions for Embedded Cluster (Beta)](/embedded-cluster/v3/template-functions).
:::
```go
func LocalImageName(remoteImageName string) string
```
Given a `remoteImageName`, rewrite the `remoteImageName` so that it can be pulled to local hosts.
A common use case for the `LocalImageName` function is to ensure that a Kubernetes Operator can determine the names of container images on Pods created at runtime. For more information, see [Reference Images](/vendor/operator-referencing-images) in the _Packaging a Kubernetes Operator Application_ section.
`LocalImageName` rewrites the `remoteImageName` in one of the following ways, depending on if a private registry is configured and if the image must be proxied:
* If there is a private registry configured in the customer's environment, such as in air gapped environments, rewrite `remoteImageName` to reference the private registry locally. For example, rewrite `elasticsearch:7.6.0` as `registry.somebigbank.com/my-app/elasticsearch:7.6.0`.
* If there is no private registry configured in the customer's environment, but the image must be proxied, rewrite `remoteImageName` so that the image can be pulled through the proxy registry. For example, rewrite `"quay.io/orgname/private-image:v1.2.3"` as `proxy.replicated.com/proxy/app-name/quay.io/orgname/private-image:v1.2.3`.
* If there is no private registry configured in the customer's environment and the image does not need to be proxied, return `remoteImageName` without changes.
For more information about the Replicated proxy registry, see [About the Proxy Registry](/vendor/private-images-about).
## LocalRegistryImagePullSecret
```go
func LocalRegistryImagePullSecret() string
```
Returns the base64 encoded local registry image pull secret value.
This is often needed when an operator is deploying images to a namespace that is not managed by the Replicated installer.
Image pull secrets must be present in the namespace of the pod.
#### Example
```yaml
apiVersion: v1
kind: Secret
metadata:
name: my-image-pull-secret
namespace: my-namespace
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: '{{repl LocalRegistryImagePullSecret }}'
---
apiVersion: v1
kind: Pod
metadata:
name: dynamic-pod
namespace: my-namespace
spec:
containers:
- image: '{{repl LocalImageName "registry.replicated.com/my-app/my-image:abcdef" }}'
name: my-container
imagePullSecrets:
- name: my-image-pull-secret
```
## ImagePullSecretName
```go
func ImagePullSecretName() string
```
Returns the name of the image pull secret that can be added to pod specs that use private images.
The secret will be automatically created in all application namespaces.
It will contain authentication information for any private registry used with the application.
#### Example
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
template:
spec:
imagePullSecrets:
- name: repl{{ ImagePullSecretName }}
```
## HasLocalRegistry
:::note
The HasLocalRegistry template function is not supported for installations with Embedded Cluster v3. See [Template Functions for Embedded Cluster (Beta)](/embedded-cluster/v3/template-functions).
:::
```go
func HasLocalRegistry() bool
```
Returns true if the environment is configured to rewrite images to a local registry.
HasLocalRegistry is always true for air gap installations. HasLocalRegistry is true in online installations if the user pushed images to a local registry.
#### Example
The following [HelmChart](/reference/custom-resource-helmchart-v2) custom resource uses the HasLocalRegistry, LocalRegistryHost, and LocalRegistryNamespace template functions to conditionally rewrite an image registry and repository depending on if a local registry is used. These values are then mapped to the `values.yaml` file for the associated Helm chart during deployment.
```yaml
# HelmChart custom resource
apiVersion: kots.io/v1beta2
kind: HelmChart
metadata:
name: samplechart
spec:
chart:
name: samplechart
chartVersion: 3.1.7
values:
myapp:
image:
registry: '{{repl HasLocalRegistry | ternary LocalRegistryHost "images.mycompany.com" }}'
repository: '{{repl HasLocalRegistry | ternary LocalRegistryNamespace "proxy/myapp/quay.io/my-org" }}/nginx'
tag: v1.0.1
```
For more information, see [values](/reference/custom-resource-helmchart-v2#values) in _HelmChart v2_.
---
# Template function examples
This topic provides examples of how to use Replicated template functions in various common use cases.
For more information about working with Replicated template functions,
including the supported syntax and the types of files that support Replicated template functions,
see [About Replicated Template Functions](template-functions-about).
## Overview
Replicated template functions are based on the Go text/template library. All functionality of the Go templating language, including if statements, loops, and variables, is supported with Replicated template functions. For more information, see [text/template](https://golang.org/pkg/text/template/) in the Go documentation.
Additionally, Replicated template functions can be used with all functions in the Sprig library. Sprig provides several template functions for the Go templating language, such as type conversion, string, and integer math functions. For more information, see [Sprig Function Documentation](https://masterminds.github.io/sprig/).
Common use cases for Replicated template functions include rendering values during installation or upgrade, such as:
* Customer-specific license field values
* User-provided configuration values
* Information about the customer environment, such the number of nodes or the Kubernetes version in the cluster where the application is installed
* Random strings
Replicated template functions can also be used to work with integer, boolean, float, and string values, such as doing mathematical operations, trimming leading and trailing spaces, or converting string values to integers or booleans.
For examples demonstrating these use cases and more, see the following sections.
## Comparison examples
This section includes examples of how to use Replicated template functions to compare different types of data.
### Boolean comparison
Use boolean values in comparisons to evaluate if a given statement is true or false.
Because many Replicated template functions return string values,
comparing boolean values often requires using the Replicated
[ParseBool](/reference/template-functions-static-context#parsebool) template function
to return the boolean represented by the string.
One common use case for working with boolean values is to check that a given field is present in the customer's license.
For example,
you might need to show a configuration option only when the customer's license includes a certain entitlement.
The following example creates a conditional statement in the Replicated Config custom resource.
The statement evaluates to true when a specified license field is present in the customer's license _and_
the customer enables a specified configuration option.
```yaml
# Replicated Config custom resource
apiVersion: kots.io/v1beta1
kind: Config
metadata:
name: config-sample
spec:
groups:
- name: example_group
title: Example Config
items:
- name: radio_example
title: Select One
type: radio
items:
- name: option_one
title: Option One
- name: option_two
title: Option Two
- name: conditional_item
title: Conditional Item
type: text
# Display this item only when the customer enables the option_one config field *and*
# has the feature-1 entitlement in their license
when: repl{{ and (LicenseFieldValue "feature-1" | ParseBool) (ConfigOptionEquals "radio_example" "option_one")}}
```
This example uses the following Replicated template functions:
* [LicenseFieldValue](/reference/template-functions-license-context#licensefieldvalue)
to return the string value of a boolean type license field named `feature-1`
:::note
The LicenseFieldValue template function always returns a string, regardless of the license field type.
:::
* [ParseBool](/reference/template-functions-static-context#parsebool)
to convert the string returned by the LicenseFieldValue template function to a boolean
* [ConfigOptionEquals](/reference/template-functions-config-context#configoptionequals)
to return a boolean that evaluates to true if the configuration option value is equal to the supplied value
### Integer comparison
You can compare integer values using operators such as greater than, less than, equal to, and so on.
Because many Replicated template functions return string values,
you might need another function to return the integer represented by the string, such as:
* Replicated [ParseInt](/reference/template-functions-static-context#parseint),
which returns the integer value represented by the string with the option to provide a `base` other than 10
* Sprig [atoi](https://masterminds.github.io/sprig/conversion.html),
which is equivalent to ParseInt(s, 10, 0), converted to type integer
A common use case for comparing integer values is to display different configuration options
depending on values from the customer's license.
For example, licenses might include an entitlement that defines the number of seats available to the customer.
In this case,
you can conditionally display or hide certain fields on the configuration screen depending on the customer's team size.
The following example uses:
* Replicated [LicenseFieldValue](/reference/template-functions-license-context#licensefieldvalue) template function to evaluate the number of seats permitted by the license
* Sprig [atoi](https://masterminds.github.io/sprig/conversion.html) function to convert the string values returned by LicenseFieldValue to integers
* [Go binary comparison operators](https://pkg.go.dev/text/template#hdr-Functions) `gt`, `lt`, `ge`, and `le` to compare the integers
```yaml
# Replicated Config custom resource
apiVersion: kots.io/v1beta1
kind: Config
metadata:
name: config-sample
spec:
groups:
- name: example_group
title: Example Config
items:
- name: small
title: Small (100 or Fewer Seats)
type: text
default: Default for small teams
# Use le and atoi functions to display this config item
# only when the value of the numSeats entitlement is
# less than or equal to 100
when: repl{{ le (atoi (LicenseFieldValue "numSeats")) 100 }}
- name: medium
title: Medium (101-1000 Seats)
type: text
default: Default for medium teams
# Use ge, le, and atoi functions to display this config item
# only when the value of the numSeats entitlement is
# greater than or equal to 101 and less than or equal to 1000
when: repl{{ (and (ge (atoi (LicenseFieldValue "numSeats")) 101) (le (atoi (LicenseFieldValue "numSeats")) 1000)) }}
- name: large
title: Large (More Than 1000 Seats)
type: text
default: Default for large teams
# Use gt and atoi functions to display this config item
# only when the value of the numSeats entitlement is
# greater than 1000
when: repl{{ gt (atoi (LicenseFieldValue "numSeats")) 1000 }}
```
As shown in the image below, if the user's license contains `numSeats: 150`, then the `medium` item is displayed on the **Config** page and the `small` and `large` items are not displayed:
[View a larger version of this image](/images/config-example-numseats.png)
### String comparison
A common use case for string comparison is to compare the rendered value of a Replicated template function
against a string.
You can use this to conditionally show or hide fields based on details about the customer's environment.
For example, use a string comparison to check the Kubernetes distribution of the cluster where the application runs.
The following example uses:
* Replicated [Distribution](/reference/template-functions-static-context#distribution) template function to return the Kubernetes distribution of the cluster
* [eq](https://pkg.go.dev/text/template#hdr-Functions) (_equal_) Go binary operator to compare the rendered value of the Distribution template function to a string, then return the boolean truth of the comparison
```yaml
# Replicated Config custom resource
apiVersion: kots.io/v1beta1
kind: Config
metadata:
name: config-sample
spec:
groups:
- name: example_settings
title: My Example Config
description: Example fields for using Distribution template function
items:
- name: gke_distribution
type: label
title: "You are deploying to GKE"
# Use the eq binary operator to check if the rendered value
# of the Distribution template function is equal to gke
when: repl{{ eq Distribution "gke" }}
- name: openshift_distribution
type: label
title: "You are deploying to OpenShift"
when: repl{{ eq Distribution "openShift" }}
- name: eks_distribution
type: label
title: "You are deploying to EKS"
when: repl{{ eq Distribution "eks" }}
...
```
The following image shows how only the `gke_distribution` item appears on the app configuration screen:
### Not equal to comparison
It can be useful to compare the rendered value of a Replicated template function against another value
to check if the two values are different.
For example,
you can conditionally show certain fields only when the Kubernetes distribution of the cluster
where the application runs is _not_
[Replicated Embedded Cluster](/embedded-cluster/v3/embedded-overview).
In the following example, the `ingress_type` field appears on the configuration page only when the distribution of the cluster is _not_ [Replicated Embedded Cluster](/embedded-cluster/v3/embedded-overview). This ensures that only users deploying to their own existing cluster are able to select the method for ingress.
The following example uses:
* Replicated [Distribution](/reference/template-functions-static-context#distribution) template function to return the Kubernetes distribution of the cluster
* [ne](https://pkg.go.dev/text/template#hdr-Functions) (_not equal_) Go binary operator to compare the rendered value of the Distribution template function to a string, then return `true` if the values are not equal to one another
```yaml
apiVersion: kots.io/v1beta1
kind: Config
metadata:
name: config
spec:
groups:
# Ingress settings
- name: ingress_settings
title: Ingress Settings
description: Configure Ingress
items:
- name: ingress_type
title: Ingress Type
help_text: |
Select how traffic will ingress to the appliction.
type: radio
items:
- name: ingress_controller
title: Ingress Controller
- name: load_balancer
title: Load Balancer
default: "ingress_controller"
required: true
when: 'repl{{ ne Distribution "embedded-cluster" }}'
# Database settings
- name: database_settings
title: Database
items:
- name: postgres_type
help_text: Would you like to use an embedded postgres instance, or connect to an external instance that you manage?
type: radio
title: Postgres
default: embedded_postgres
items:
- name: embedded_postgres
title: Embedded Postgres
- name: external_postgres
title: External Postgres
```
The following image shows how the `ingress_type` field does not appear when the distribution of the cluster is `embedded-cluster`. Only the `postgres_type` item appears:
[View a larger version of this image](/images/config-example-distribution-not-ec.png)
Conversely, when the distribution of the cluster is not `embedded-cluster`, both fields appear:
[View a larger version of this image](/images/config-example-distribution-not-ec-2.png)
### Logical AND comparison
Logical comparisons such as AND, OR, and NOT work with Replicated template functions.
A common use case for logical AND comparisons is to construct more complex conditional statements
where two different conditions must both be true.
The following example shows how to use an `and` operator that evaluates to true
when two different configuration options are both enabled.
This example uses the Replicated
[ConfigOptionEquals](/reference/template-functions-config-context#configoptionequals) template function
to return a boolean that evaluates to true if the configuration option value is equal to the supplied value.
```yaml
# Replicated Config custom resource
apiVersion: kots.io/v1beta1
kind: Config
metadata:
name: config-sample
spec:
groups:
- name: example_group
title: Example Config
items:
- name: radio_example
title: Select One Example
type: radio
items:
- name: option_one
title: Option One
- name: option_two
title: Option Two
- name: boolean_example
title: Boolean Example
type: bool
default: "0"
- name: conditional_item
title: Conditional Item
type: text
# Display this item only when *both* specified config options are enabled
when: repl{{ and (ConfigOptionEquals "radio_example" "option_one") (ConfigOptionEquals "boolean_example" "1")}}
```
As shown in the following image,
when the user selects both `Option One` and `Boolean Example`,
the conditional statement evaluates to true and the `Conditional Item` field appears:
[View a larger version of this image](/images/conditional-item-true.png)
Alternatively,
if either `Option One` or `Boolean Example` is not selected,
then the conditional statement evaluates to false and the `Conditional Item` field is not displayed:
[View a larger version of this image](/images/conditional-item-false-option-two.png)
[View a larger version of this image](/images/conditional-item-false-boolean.png)
## Conditional statement examples
This section includes examples of using Replicated template functions to construct conditional statements.
Use conditional statements with Replicated template functions to render different values depending on a given condition.
### If-else statements
A common use case for if-else statements is to conditionally set values for application resources or objects,
such as custom annotations or service types.
:::note
For more complex or nested if-else statements,
use templating in your Helm chart `templates` instead of in the Replicated HelmChart custom resource.
For more information, see [If/Else](https://helm.sh/docs/chart_template_guide/control_structures/#ifelse)
in the Helm documentation.
:::
For most use cases, use single-line formatting for if-else statements.
Multi-line formatting can be useful to improve the readability of YAML files
for longer or more complex if-else statements.
You can construct multi-line if-else statements using YAML block scalars and block chomping characters
to ensure the rendered result is valid YAML:
* Use the greater than (`>`) character for a _folded_ block scalar style.
With the folded style, Go treats single line breaks in the string as a space.
* Use the block chomping minus (`-`) character to remove all the line breaks at the end of a string.
For more information about working with these characters,
see [Block Style Productions](https://yaml.org/spec/1.2.2/#chapter-8-block-style-productions) in the YAML documentation.
The following example shows if-else statements in the Replicated HelmChart custom resource `values` field.
The statements render different values depending on whether the user selects a load balancer or an ingress controller
as the ingress type.
This example uses the Replicated
[ConfigOptionEquals](/reference/template-functions-config-context#configoptionequals) template function
to return a boolean that evaluates to true if the configuration option value is equal to the supplied value.
```yaml
# Replicated HelmChart custom resource
apiVersion: kots.io/v1beta2
kind: HelmChart
metadata:
name: my-app
spec:
chart:
name: my-app
chartVersion: 0.23.0
values:
services:
my-service:
enabled: true
appName: ["my-app"]
# Render the service type based on the user's selection
# '{{repl ...}}' syntax is used for `type` to improve readability of the if-else statement and render a string
type: '{{repl if ConfigOptionEquals "ingress_type" "load_balancer" }}LoadBalancer{{repl else }}ClusterIP{{repl end }}'
ports:
http:
enabled: true
# Render the HTTP port for the service depending on the user's selection
# repl{{ ... }} syntax is used for `port` to render an integer value
port: repl{{ if ConfigOptionEquals "ingress_type" "load_balancer" }}repl{{ ConfigOption "load_balancer_port" }}repl{{ else }}8081repl{{ end }}
protocol: HTTP
targetPort: 8081
```
### Ternary operators
Ternary operators are useful for templating strings where certain values must render differently based on a condition.
They work best when you need to render a small portion of a string conditionally,
rather than choosing between entirely different values.
For example, you could use ternary operators to template the path to an image repository based on user-supplied values.
The following example uses ternary operators to render the registry and repository for a private nginx image.
The rendered value depends on whether the customer uses a local image registry.
This example uses the following Replicated template functions:
* [HasLocalRegistry](/reference/template-functions-config-context#haslocalregistry)
to return true if the environment rewrites images to a local registry
* [LocalRegistryHost](/reference/template-functions-config-context#localregistryhost)
to return the local registry host configured by the user
* [LocalRegistryNamespace](/reference/template-functions-config-context#localregistrynamespace)
to return the local registry namespace configured by the user
```yaml
# Replicated HelmChart custom resource
apiVersion: kots.io/v1beta2
kind: HelmChart
metadata:
name: samplechart
spec:
values:
image:
# If a local registry is configured, use the local registry host.
# Otherwise, use proxy.replicated.com
registry: repl{{ HasLocalRegistry | ternary LocalRegistryHost "proxy.replicated.com" }}
# If a local registry is configured, use the local registry's namespace.
# Otherwise, use proxy/my-app/quay.io/my-org
repository: repl{{ HasLocalRegistry | ternary LocalRegistryNamespace "proxy/my-app/quay.io/my-org" }}/nginx
tag: v1.0.1
```
## Formatting examples
This section includes examples of how to format the rendered output of Replicated template functions.
In addition to the examples in this section,
Replicated template functions in the Static context include several formatting options.
These include converting strings to upper or lower case and trimming leading and trailing space characters.
For more information, see [Static Context](/reference/template-functions-static-context).
### Indentation
When using template functions within nested YAML,
indent the rendered template functions correctly so that the YAML renders.
A common use case for indentation is templating annotations in resource or object metadata
based on user-supplied values.
The [nindent](https://masterminds.github.io/sprig/strings.html) function adds a new line to the beginning of the string
and indents the string by a specified number of spaces.
The following example shows templating a Helm chart value that sets annotations for an Ingress object.
This example uses the Replicated
[ConfigOption](/reference/template-functions-config-context#configoption) template function
to return user-supplied annotations from the configuration screen in the Replicated installer UI.
It also uses [nindent](https://masterminds.github.io/sprig/strings.html) to indent the rendered value ten spaces.
```yaml
# Replicated HelmChart custom resource
apiVersion: kots.io/v1beta2
kind: HelmChart
metadata:
name: myapp
spec:
values:
services:
myservice:
annotations: repl{{ ConfigOption "additional_annotations" | nindent 10 }}
```
### Render quoted values
To wrap a rendered value in quotes,
you can pipe the result from Replicated template functions with the `repl{{ ... }}` syntax into quotes using `| quote`.
Or, you can use the `'{{repl ... }}'` syntax instead.
One use case for quoted values in YAML is when values include indicator characters.
In YAML, indicator characters (`-`, `?`, `:`) have special semantics and require escaping when used in values.
For more information, see [Indicator Charactors](https://yaml.org/spec/1.2.2/#53-indicator-characters)
in the YAML documentation.
#### Example with `'{{repl ... }}'` syntax
```yaml
customTag: '{{repl ConfigOption "tag" }}'
```
#### Example with `| quote`
```yaml
customTag: repl{{ ConfigOption "tag" | quote }}
```
The result for both examples is:
```yaml
customTag: 'key: value'
```
## Variables example
This section includes an example of using variables with Replicated template functions.
For more information, see [Variables](https://pkg.go.dev/text/template#hdr-Variables) in the Go documentation.
### Using variables to generate TLS certificates in JSON
You can use the Sprig [genCA](https://masterminds.github.io/sprig/crypto.html) and
[genSignedCert](https://masterminds.github.io/sprig/crypto.html) functions
with Replicated template functions to generate certificate authorities (CAs) and signed certificates in JSON.
One use case for this is to generate default CAs, certificates, and keys that users can override with their own values.
The Sprig [genCA](https://masterminds.github.io/sprig/crypto.html) and
[genSignedCert](https://masterminds.github.io/sprig/crypto.html) functions
require the subject's common name and the certificate's validity duration in days.
The `genSignedCert` function also requires the CA that will sign the certificate.
You can use variables and Replicated template functions
to provide the necessary parameters when calling these functions.
The following example shows how to use variables and Replicated template functions
in the `default` property of a [`hidden`](/reference/custom-resource-config#hidden) item.
The example passes parameters to the `genCA` and `genSignedCert` functions to generate a CA, certificate, and key.
It uses a `hidden` item (not displayed on the configuration screen) to generate the certificate chain.
In the Replicated Config custom resource,
you can only access variables from the same item where you declared them.
For this reason, `hidden` items are useful for evaluating complex templates.
This example uses the following:
* Replicated [ConfigOption](/reference/template-functions-config-context#configoption) template function
to render the user-supplied value for the ingress hostname.
Pass this as a parameter to the [genCA](https://masterminds.github.io/sprig/crypto.html) and
[genSignedCert](https://masterminds.github.io/sprig/crypto.html) functions
* Sprig [genCA](https://masterminds.github.io/sprig/crypto.html) and
[genSignedCert](https://masterminds.github.io/sprig/crypto.html) functions
to generate a CA and a certificate signed by the CA
* Sprig [dict](https://masterminds.github.io/sprig/dicts.html),
[set](https://masterminds.github.io/sprig/dicts.html),
and [dig](https://masterminds.github.io/sprig/dicts.html) dictionary functions
to create a dictionary with entries for both the CA and the certificate,
then traverse the dictionary to return the values of the CA, certificate, and key.
* [toJson](https://masterminds.github.io/sprig/defaults.html) and
[fromJson](https://masterminds.github.io/sprig/defaults.html) Sprig functions
to encode the CA and certificate into a JSON string,
then decode the JSON for the purpose of displaying the values on the configuration screen as defaults
:::important
Replicated treats default values as ephemeral.
Replicated recalculates the following certificate chain each time you modify the application configuration.
Before using this example with your application,
be sure that your application can handle updating these parameters dynamically.
:::
```yaml
apiVersion: kots.io/v1beta1
kind: Config
metadata:
name: config-sample
spec:
groups:
- name: example_settings
title: My Example Config
items:
- name: ingress_hostname
title: Ingress Hostname
help_text: Enter a DNS hostname to use as the cert's CN.
type: text
- name: tls_json
title: TLS JSON
type: textarea
hidden: true
default: |-
repl{{ $ca := genCA (ConfigOption "ingress_hostname") 365 }}
repl{{ $tls := dict "ca" $ca }}
repl{{ $cert := genSignedCert (ConfigOption "ingress_hostname") (list ) (list (ConfigOption "ingress_hostname")) 365 $ca }}
repl{{ $_ := set $tls "cert" $cert }}
repl{{ toJson $tls }}
- name: tls_ca
title: Signing Authority
type: textarea
default: repl{{ fromJson (ConfigOption "tls_json") | dig "ca" "Cert" "" }}
- name: tls_cert
title: TLS Cert
type: textarea
default: repl{{ fromJson (ConfigOption "tls_json") | dig "cert" "Cert" "" }}
- name: tls_key
title: TLS Key
type: textarea
default: repl{{ fromJson (ConfigOption "tls_json") | dig "cert" "Key" "" }}
```
The following image shows how the default values for the CA, certificate, and key appear on the configuration screen:
[View a larger version of this image](/images/certificate-chain-default-values.png)
---
# kURL Context
This topic provides a list of the Replicated template functions in the kURL context.
:::note
Replicated kURL is available only for existing customers. If you are not an existing kURL user, use Replicated Embedded Cluster instead. For more information, see [Use Embedded Cluster](/embedded-cluster/v3/embedded-overview).
kURL is a Generally Available (GA) product for existing customers. For more information about the Replicated product lifecycle phases, see [Support Lifecycle Policy](/vendor/policies-support-lifecycle).
:::
## Overview
Template functions in the kURL context have access to information about applications installed with Replicated kURL. For more information about kURL, see [Introduction to kURL](/vendor/kurl-about).
The creation of the kURL Installer custom resource will reflect both install script changes made by posting YAML to the kURL API and changes made with -s flags at runtime. These functions are not available on the KOTS Admin Console config page.
KurlBool, KurlInt, KurlString, and KurlOption all take a string yamlPath as a param.
This is the path from the manifest file, and is delineated between add-on and subfield by a period ’.’.
For example, the kURL Kubernetes version can be accessed as `{{repl KurlString "Kubernetes.Version" }}`.
KurlBool, KurlInt, KurlString respectively return a bool, integer, and string value.
If used on a valid field but with the wrong type these will return the falsy value for their type, false, 0, and “string respectively.
The `KurlOption` function will convert all bool, int, and string fields to string.
All functions will return falsy values if there is nothing at the yamlPath specified, or if these functions are run in a cluster with no installer custom resource (as in, not a cluster created by kURL).
## KurlBool
```go
func KurlBool(yamlPath string) bool
```
Returns the value at the yamlPath if there is a valid boolean there, or false if there is not.
```yaml
'{{repl KurlBool "Docker.NoCEonEE" }}'
```
## KurlInt
```go
func KurlInt(yamlPath string) int
```
Returns the value at the yamlPath if there is a valid integer there, or 0 if there is not.
```yaml
'{{repl KurlInt "Rook.CephReplicaCount" }}'
```
## KurlString
```go
func KurlString(yamlPath string) string
```
Returns the value at the yamlPath if there is a valid string there, or "" if there is not.
```yaml
'{{repl KurlString "Kubernetes.Version" }}'
```
## KurlOption
```go
func KurlOption(yamlPath string) string
```
Returns the value at the yamlPath if there is a valid string, int, or bool value there, or "" if there is not.
Int and Bool values will be converted to string values.
```yaml
'{{repl KurlOption "Rook.CephReplicaCount" }}'
```
## KurlAll
```go
func KurlAll() string
```
Returns all values in the Installer custom resource as key:value pairs, sorted by key.
```yaml
'{{repl KurlAll }}'
```
---
# License Context
This topic provides a list of the Replicated template functions in the License context.
Template functions in the license context have access to customer license and version data. For more information about managing customer licenses, see [About Customers and Licensing](/vendor/licenses-about).
## LicenseFieldValue
```go
func LicenseFieldValue(name string) string
```
LicenseFieldValue returns the value of the specified license field. LicenseFieldValue accepts custom license fields and all built-in license fields. For a list of all built-in fields, see [Built-In License Fields](/vendor/licenses-using-builtin-fields).
LicenseFieldValue always returns a string, regardless of the license field type. To return integer or boolean values, you need to use the [ParseInt](/reference/template-functions-static-context#parseint) or [ParseBool](/reference/template-functions-static-context#parsebool) template function to convert the string value.
#### String License Field
The following example returns the value of the built-in `customerName` license field:
```yaml
customerName: '{{repl LicenseFieldValue "customerName" }}'
```
#### Integer License Field
The following example returns the value of a custom integer license field named `numSeats`:
```yaml
numSeats: repl{{ LicenseFieldValue "numSeats" | ParseInt }}
```
This example uses [ParseInt](/reference/template-functions-static-context#parseint) to convert the returned value to an integer.
#### Boolean License Field
The following example returns the value of a custom boolean license field named `feature-1`:
```yaml
feature-1: repl{{ LicenseFieldValue "feature-1" | ParseBool }}
```
This example uses [ParseBool](/reference/template-functions-static-context#parsebool) to convert the returned value to a boolean.
## LicenseDockerCfg
```go
func LicenseDockerCfg() string
```
LicenseDockerCfg returns a value that can be written to a secret if needed to deploy manually.
Replicated KOTS creates and injects this secret automatically in normal conditions, but some deployments (with static, additional namespaces) may need to include this.
```yaml
apiVersion: v1
kind: Secret
type: kubernetes.io/dockerconfigjson
metadata:
name: myapp-registry
namespace: my-other-namespace
data:
.dockerconfigjson: repl{{ LicenseDockerCfg }}
```
## Sequence
```go
func Sequence() int64
```
Sequence is the sequence of the application deployed.
This will start at 0 for each installation, and increase with every app update, config change, license update and registry setting change.
```yaml
'{{repl Sequence }}'
```
## Cursor
```go
func Cursor() string
```
Cursor is the channel sequence of the app.
For instance, if 5 releases have been promoted to the channel that the app is running, then this would return the string `5`.
```yaml
'{{repl Cursor }}'
```
## ChannelName
```go
func ChannelName() string
```
ChannelName is the name of the deployed channel of the app.
```yaml
'{{repl ChannelName }}'
```
## VersionLabel
```go
func VersionLabel() string
```
VersionLabel is the semantic version of the app, as specified when promoting a release to a channel.
```yaml
'{{repl VersionLabel }}'
```
## ReleaseNotes
```go
func ReleaseNotes() string
```
ReleaseNotes is the release notes of the current version of the app.
```yaml
'{{repl ReleaseNotes }}'
```
## IsAirgap
```go
func IsAirgap() bool
```
IsAirgap is `true` when the app is installed via uploading an airgap package, false otherwise.
```yaml
'{{repl IsAirgap }}'
```
---
# Static Context
This topic provides a list of the Replicated template functions in the Static context.
The context necessary to render the static template functions is always available.
The static context also includes the Masterminds Sprig function library. For more information, see [Sprig Function Documentation](http://masterminds.github.io/sprig/) on the sprig website.
## Certificate Functions
### PrivateCACert
>Introduced in KOTS v1.117.0
```go
func PrivateCACert() string
```
PrivateCACert returns the name of a ConfigMap containing one or more private CA certificates.
PrivateCACert returns the name of the ConfigMap even if the ConfigMap has no entries. If no ConfigMap exists, PrivateCACert returns the empty string.
The Replicated installer (Embedded Cluster or KOTS) mounts the ConfigMap returned by the PrivateCACert template function as a volume.
It then uses the private CA from the host when making outbound network requests.
For KOTS installations in existing clusters, the end user can also optionally create and pass the ConfigMap to the `install` command using the `--private-ca-configmap` flag. For more information, see [install](/reference/kots-cli-install).
You can use the PrivateCACert template function to ensure the Replicated installer trusts private CA certificates from TLS man-in-the-middle proxies in the end user's environment. You can use also the PrivateCACert template function to mount the ConfigMap in your own application container.
## Cluster Information Functions
### Distribution
```go
func Distribution() string
```
Distribution returns the Kubernetes distribution detected. The possible return values are:
* aks
* digitalOcean
* dockerDesktop
* eks
* embedded-cluster
* gke
* ibm
* k0s
* k3s
* kind
* kurl
* microk8s
* minikube
* oke
* openShift
* rke2
:::note
[IsKurl](#iskurl) can also be used to detect kURL instances.
:::
#### Detect the Distribution
```yaml
repl{{ Distribution }}
```
#### Equal To Comparison
```yaml
repl{{ eq Distribution "gke" }}
```
#### Not Equal To Comparison
```yaml
repl{{ ne Distribution "embedded-cluster" }}
```
See [Functions](https://pkg.go.dev/text/template#hdr-Functions) in the Go documentation.
### IsKurl
```go
func IsKurl() bool
```
IsKurl returns true if running within a kurl-based installation.
#### Detect kURL Installations
```yaml
repl{{ IsKurl }}
```
#### Detect Non-kURL Installations
```yaml
repl{{ not IsKurl }}
```
See [Functions](https://pkg.go.dev/text/template#hdr-Functions) in the Go documentation.
### KotsVersion
```go
func KotsVersion() string
```
KotsVersion returns the current version of KOTS.
```yaml
repl{{ KotsVersion }}
```
You can compare the KOTS version as follows:
```yaml
repl{{KotsVersion | semverCompare ">= 1.19"}}
```
This returns `true` if the KOTS version is greater than or equal to `1.19`.
For more complex comparisons, see [Semantic Version Functions](https://masterminds.github.io/sprig/semver.html) in the sprig documentation.
### KubernetesMajorVersion
> Introduced in KOTS v1.92.0
```go
func KubernetesMajorVersion() string
```
KubernetesMajorVersion returns the Kubernetes server *major* version.
```yaml
repl{{ KubernetesMajorVersion }}
```
You can compare the Kubernetes major version as follows:
```yaml
repl{{lt (KubernetesMajorVersion | ParseInt) 2 }}
```
This returns `true` if the Kubernetes major version is less than `2`.
### KubernetesMinorVersion
> Introduced in KOTS v1.92.0
```go
func KubernetesMinorVersion() string
```
KubernetesMinorVersion returns the Kubernetes server *minor* version.
```yaml
repl{{ KubernetesMinorVersion }}
```
You can compare the Kubernetes minor version as follows:
```yaml
repl{{gt (KubernetesMinorVersion | ParseInt) 19 }}
```
This returns `true` if the Kubernetes minor version is greater than `19`.
### KubernetesVersion
> Introduced in KOTS v1.92.0
```go
func KubernetesVersion() string
```
KubernetesVersion returns the Kubernetes server version.
```yaml
repl{{ KubernetesVersion }}
```
You can compare the Kubernetes version as follows:
```yaml
repl{{KubernetesVersion | semverCompare ">= 1.19"}}
```
This returns `true` if the Kubernetes version is greater than or equal to `1.19`.
For more complex comparisons, see [Semantic Version Functions](https://masterminds.github.io/sprig/semver.html) in the sprig documentation.
### Namespace
```go
func Namespace() string
```
Namespace returns the Kubernetes namespace that the application belongs to.
```yaml
'{{repl Namespace}}'
```
### NodeCount
```go
func NodeCount() int
```
NodeCount returns the number of nodes detected within the Kubernetes cluster.
```yaml
repl{{ NodeCount }}
```
### Lookup
> Introduced in KOTS v1.103.0
```go
func Lookup(apiversion string, resource string, namespace string, name string) map[string]interface{}
```
Lookup is also supported for installations with Embedded Cluster v3. For more information, see [Lookup](/embedded-cluster/v3/template-functions#lookup) in _Template Functions for Embedded Cluster (Beta)_.
Lookup searches resources in a running cluster and returns a resource or resource list.
Lookup uses the Helm lookup function to search resources and has the same functionality as the Helm lookup function. For more information, see [lookup](https://helm.sh/docs/chart_template_guide/functions_and_pipelines/#using-the-lookup-function) in the Helm documentation.
```yaml
repl{{ Lookup "API_VERSION" "KIND" "NAMESPACE" "NAME" }}
```
Both `NAME` and `NAMESPACE` are optional and can be passed as an empty string ("").
The following combination of parameters are possible:
| Behavior | Lookup function |
|---|---|
kubectl get pod mypod -n mynamespace |
repl{{ Lookup "v1" "Pod" "mynamespace" "mypod" }} |
kubectl get pods -n mynamespace |
repl{{ Lookup "v1" "Pod" "mynamespace" "" }} |
kubectl get pods --all-namespaces |
repl{{ Lookup "v1" "Pod" "" "" }} |
kubectl get namespace mynamespace |
repl{{ Lookup "v1" "Namespace" "" "mynamespace" }} |
kubectl get namespaces |
repl{{ Lookup "v1" "Namespace" "" "" }} |
| readonly | hidden | Outcome | Use Case |
|---|---|---|---|
| false | true | Persistent |
Set
|
| true | false | Ephemeral |
Set
|
| true | true | Ephemeral |
Set
|
| false | false | Persistent |
Set
For example, set both |
[View a larger version of this image](/images/gitea-open-app.png)
:::note
KOTS uses the Kubernetes SIG Application custom resource as metadata and does not require or use an in-cluster controller to handle this custom resource. An application that follows best practices does not require cluster admin privileges or any cluster-wide components to be installed.
:::
## Add a link
To add a link to the Admin Console dashboard, include a [Kubernetes SIG Application](https://github.com/kubernetes-sigs/application#kubernetes-applications) custom resource in the release with a `spec.descriptor.links` field. The `spec.descriptor.links` field is an array of links that are displayed on the Admin Console dashboard after the application is deployed.
Each link in the `spec.descriptor.links` array contains two fields:
* `description`: The link text that will appear on the Admin Console dashboard.
* `url`: The target URL.
For example:
```yaml
# App.k8s.io/v1beta1 application custom resource
apiVersion: app.k8s.io/v1beta1
kind: Application
metadata:
name: "gitea"
spec:
descriptor:
links:
- description: About Wordpress
url: "https://wordpress.org/"
```
When the application is deployed, the "About Wordpress" link is displayed on the Admin Console dashboard as shown below:
[View a larger version of this image](/images/dashboard-link-about-wordpress.png)
For an additional example of a Kubernetes SIG Application custom resource, see [application.yaml](https://github.com/kubernetes-sigs/application/blob/master/docs/examples/wordpress/application.yaml) in the kubernetes-sigs GitHub repository.
### Create URLs with user-supplied values using Replicated template functions {#url-template}
You can use Replicated template functions to template URLs in the Kubernetes SIG Application custom resource. This can be useful when all or some of the URL is a user-supplied value. For example, an application might allow users to provide their own ingress controller or load balancer. In this case, the URL can be templated to render the hostname that the user provides on the Admin Console Config screen.
The following examples show how to use the KOTS [ConfigOption](/reference/template-functions-config-context#configoption) template function in the Kubernetes SIG Application custom resource `spec.descriptor.links.url` field to render one or more user-supplied values:
* In the example below, the URL hostname is a user-supplied value for an ingress controller that the user configures during installation.
```yaml
apiVersion: app.k8s.io/v1beta1
kind: Application
metadata:
name: "my-app"
spec:
descriptor:
links:
- description: Open App
url: 'http://{{repl ConfigOption "ingress_host" }}'
```
* In the example below, both the URL hostname and a node port are user-supplied values. It might be necessary to include a user-provided node port if you are exposing NodePort services for installations on VMs or bare metal servers with [Replicated Embedded Cluster](/embedded-cluster/v3/embedded-overview) or [Replicated kURL](/vendor/kurl-about).
```yaml
apiVersion: app.k8s.io/v1beta1
kind: Application
metadata:
name: "my-app"
spec:
descriptor:
links:
- description: Open App
url: 'http://{{repl ConfigOption "hostname" }}:{{repl ConfigOption "node_port"}}'
```
For more information about working with Replicated template functions, see [About Replicated Template Functions](/reference/template-functions-about).
---
# Customize the application icon
You can add a custom application icon that displays in the Replicated Admin Console and the download portal. Adding a custom icon helps ensure that your brand is reflected for your customers.
:::note
You can also use a custom domain for the download portal. For more information, see [About Custom Domains](custom-domains).
:::
:::note
Replicated KOTS is available only for existing customers. For supporting installations into customer managed clusters, we recommend Helm. For more information, see [About Helm Installations with Replicated](/vendor/helm-install-overview).
KOTS is a Generally Available (GA) product for existing customers. For more information about the Replicated product lifecycle phases, see [Support Lifecycle Policy](/vendor/policies-support-lifecycle).
:::
## Add a custom icon
For information about how to choose an image file for your custom application icon that displays well in the Admin Console, see [Icon Image File Recommendations](#icon-image-file-recommendations) below.
To add a custom application icon:
1. In the [Vendor Portal](https://vendor.replicated.com/apps), click **Releases**. Click **Create release** to create a new release, or click **Edit YAML** to edit an existing release.
1. Create or open the Application custom resource manifest file. An Application custom resource manifest file has `apiVersion: kots.io/v1beta1` and `kind: Application`.
1. In the preview section of the Help pane:
1. If your Application manifest file is already populated with an `icon` key, the icon displays in the preview. Click **Preview a different icon** to access the preview options.
1. Drag and drop an icon image file to the drop zone. Alternatively, paste a link or Base64 encoded data URL in the text box. Click **Preview**.

1. (Air gap only) If you paste a link to the image in the text box, click **Preview** and **Base64 encode icon** to convert the image to a Base64 encoded data URL. An encoded URL displays that you can copy and paste into the Application manifest. Base64 encoding is required for images used with air gap installations.
:::note
If you pasted a Base64 encoded data URL into the text box, the **Base64 encode icon** button does not display because the image is already encoded. If you drag and drop an icon, the icon is automatically encoded for you.
:::

1. Click **Preview a different icon** to preview a different icon if needed.
1. In the Application manifest, under `spec`, add an `icon` key that includes a link or the Base64 encoded data URL to the desired image.
**Example**:
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: my-application
spec:
title: My Application
icon: https://kots.io/images/kotsadm-logo-large@2x.png
```
1. Click **Save Release**.
## Icon image file recommendations
For your custom application icon to look best in the Admin Console, consider the following recommendations:
* Use a PNG or JPG file.
* Use an image that is at least 250 by 250 pixels.
* Export the image file at 2x.
---
# Create and edit configuration fields
This topic describes how to use the Replicated Config custom resource manifest file to add and edit fields in the KOTS Admin Console configuration screen.
:::note
Replicated KOTS is available only for existing customers. For supporting installations into customer managed clusters, we recommend Helm. For more information, see [About Helm Installations with Replicated](/vendor/helm-install-overview).
KOTS is a Generally Available (GA) product for existing customers. For more information about the Replicated product lifecycle phases, see [Support Lifecycle Policy](/vendor/policies-support-lifecycle).
:::
## About the Config custom resource
Applications distributed with Replicated KOTS can include a configuration screen in the Admin Console to collect required or optional values from your users that are used to run your application. For more information about the configuration screen, see [About the Configuration Screen](config-screen-about).
To include a configuration screen in the Admin Console for your application, you add a Config custom resource manifest file to a release for the application.
You define the fields that appear on the configuration screen as an array of `groups` and `items` in the Config custom resource:
* `groups`: A set of `items`. Each group must have a `name`, `title`, `description`, and `items`. For example, you can create a group of several user input fields that are all related to configuring an SMTP mail server.
* `items`: An array of user input fields. Each array under `items` must have a `name`, `title`, and `type`. You can also include several optional properties. For example, in a group for configuring a SMTP mail server, you can have user input fields under `items` for the SMTP hostname, port, username, and password.
There are several types of `items` supported in the Config manifest that allow you to collect different types of user inputs. For example, you can use the `password` input type to create a text field on the configuration screen that hides user input.
For more information about the syntax of the Config custom resource manifest, see [Config](/reference/custom-resource-config).
## About regular expression validation
You can use [RE2 regular expressions](https://github.com/google/re2/wiki/Syntax) (regex) to validate user input for config items, ensuring conformity to certain standards, such as valid email addresses, password complexity rules, IP addresses, and URLs. This prevents users from deploying an application with a verifiably invalid configuration.
You add the `validation`, `regex`, `pattern` and `message` fields to items in the Config custom resource. Validation is supported for `text`, `textarea`, `password` and `file` config item types. For more information about regex validation fields, see [Item Validation](/reference/custom-resource-config#item-validation) in _Config_.
The following example shows a common password complexity rule:
```
- name: smtp-settings
title: SMTP Settings
items:
- name: smtp_password
title: SMTP Password
type: password
help_text: Set SMTP password
validation:
regex:
pattern: ^(?:[\w@#$%^&+=!*()_\-{}[\]:;"'<>,.?\/|]){8,16}$
message: The password must be between 8 and 16 characters long and can contain a combination of uppercase letter, lowercase letters, digits, and special characters.
```
## Add fields to the configuration screen
To add fields to the Admin Console configuration screen:
1. In the [Vendor Portal](https://vendor.replicated.com/apps), click **Releases**. Then, either click **Create release** to create a new release, or click **Edit YAML** to edit an existing release.
1. Create or open the Config custom resource manifest file in the desired release. A Config custom resource manifest file has `kind: Config`.
1. In the Config custom resource manifest file, define custom user-input fields in an array of `groups` and `items`.
**Example**:
```yaml
apiVersion: kots.io/v1beta1
kind: Config
metadata:
name: my-application
spec:
groups:
- name: smtp_settings
title: SMTP Settings
description: Configure SMTP Settings
items:
- name: enable_smtp
title: Enable SMTP
help_text: Enable SMTP
type: bool
default: "0"
- name: smtp_host
title: SMTP Hostname
help_text: Set SMTP Hostname
type: text
- name: smtp_port
title: SMTP Port
help_text: Set SMTP Port
type: text
- name: smtp_user
title: SMTP User
help_text: Set SMTP User
type: text
- name: smtp_password
title: SMTP Password
type: password
default: 'password'
```
The example above includes a single group with the name `smtp_settings`.
The `items` array for the `smtp_settings` group includes the following user-input fields: `enable_smtp`, `smtp_host`, `smtp_port`, `smtp_user`, and `smtp_password`. Additional item properties are available, such as `affix` to make items appear horizontally on the same line. For more information about item properties, see [Item Properties](/reference/custom-resource-config#item-properties) in Config.
The following screenshot shows how the SMTP Settings group from the example YAML above displays in the Admin Console configuration screen during application installation:

1. (Optional) Add default values for the fields. You can add default values using one of the following properties:
* **With the `default` property**: When you include the `default` key, KOTS uses this value when rendering the manifest files for your application. The value then displays as a placeholder on the configuration screen in the Admin Console for your users. KOTS only uses the default value if the user does not provide a different value.
:::note
If you change the `default` value in a later release of your application, installed instances of your application receive the updated value only if your users did not change the default from what it was when they initially installed the application.
If a user did change a field from its default, the Admin Console does not overwrite the value they provided.
:::
* **With the `value` property**: When you include the `value` key, KOTS does not overwrite this value during an application update. The value that you provide for the `value` key is visually indistinguishable from other values that your user provides on the Admin Console configuration screen. KOTS treats user-supplied values and the value that you provide for the `value` key as the same.
2. (Optional) Add regular expressions to validate user input for `text`, `textarea`, `password` and `file` config item types. For more information, see [About Regular Expression Validation](#about-regular-expression-validation).
**Example**:
```yaml
- name: smtp_host
title: SMTP Hostname
help_text: Set SMTP Hostname
type: text
validation:
regex:
pattern: ^[a-zA-Z]([a-zA-Z0-9\-]+[\.]?)*[a-zA-Z0-9]$
message: Valid hostname starts with a letter (uppercase/lowercase), followed by zero or more groups of letters (uppercase/lowercase), digits, or hyphens, optionally followed by a period. Ends with a letter or digit.
```
3. (Optional) Mark fields as required by including `required: true`. When there are required fields, the user is prevented from proceeding with the installation until they provide a valid value for required fields.
**Example**:
```yaml
- name: smtp_password
title: SMTP Password
type: password
required: true
```
4. Save and promote the release to a development environment to test your changes.
## Next steps
After you add user input fields to the configuration screen, you use template functions to map the user-supplied values to manifest files in your release. If you use a Helm chart for your application, you map the values to the Helm chart `values.yaml` file using the HelmChart custom resource.
For more information, see [Map User-Supplied Values](config-screen-map-inputs).
---
# Add resource status informers
This topic describes how to add status informers for your application. Status informers apply only to applications installed with Replicated KOTS. For information about how to collect application status data for applications installed with Helm, see [Enabling and Understanding Application Status](insights-app-status).
:::note
Replicated KOTS is available only for existing customers. For supporting installations into customer managed clusters, we recommend Helm. For more information, see [About Helm Installations with Replicated](/vendor/helm-install-overview).
KOTS is a Generally Available (GA) product for existing customers. For more information about the Replicated product lifecycle phases, see [Support Lifecycle Policy](/vendor/policies-support-lifecycle).
:::
## About status informers
_Status informers_ are a feature of KOTS that report on the status of supported Kubernetes resources deployed as part of your application. You enable status informers by listing the target resources under the `statusInformers` property in the Replicated Application custom resource. KOTS watches all of the resources that you add to the `statusInformers` property for changes in state.
Possible resource statuses are Ready, Updating, Degraded, Unavailable, and Missing. For more information, see [Understanding Application Status](#understanding-application-status).
When you one or more status informers to your application, KOTS automatically does the following:
* Displays application status for your users on the dashboard of the Admin Console. This can help users diagnose and troubleshoot problems with their instance. The following shows an example of how an Unavailable status displays on the Admin Console dashboard:
* Sends application status data to the Vendor Portal. This is useful for viewing insights on instances of your application running in customer environments, such as the current status and the average uptime. For more information, see [Instance Details](instance-insights-details).
The following shows an example of the Vendor Portal **Instance details** page with data about the status of an instance over time:
[View a larger version of this image](/images/instance-details.png)
## Add status informers
To create status informers for your application, add one or more supported resource types to the `statusInformers` property in the Application custom resource. See [`statusInformers`](/reference/custom-resource-application#statusinformers) in _Application_.
The following resource types are supported:
* Deployment
* StatefulSet
* Service
* Ingress
* PersistentVolumeClaims (PVC)
* DaemonSet
You can target resources of the supported types that are deployed in any of the following ways:
* Deployed by KOTS.
* Deployed by a Kubernetes Operator that is deployed by KOTS. For more information, see [About Packaging a Kubernetes Operator Application](operator-packaging-about).
* Deployed by Helm. For more information, see [About Distributing Helm Charts with KOTS](/vendor/helm-native-about).
### Examples
Status informers are in the format `[namespace/]type/name`, where namespace is optional and defaults to the current namespace.
**Example**:
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: my-application
spec:
statusInformers:
- deployment/my-web-svc
- deployment/my-worker
```
The `statusInformers` property also supports template functions. Using template functions allows you to include or exclude a status informer based on a customer-provided configuration value:
**Example**:
```yaml
statusInformers:
- deployment/my-web-svc
- '{{repl if ConfigOptionEquals "option" "value"}}deployment/my-worker{{repl else}}{{repl end}}'
```
In the example above, the `deployment/my-worker` status informer is excluded unless the statement in the `ConfigOptionEquals` template function evaluates to true.
For more information about using template functions in application manifest files, see [About Replicated Template Functions](/reference/template-functions-about).
## Understanding application status
This section provides information about how Replicated interprets and aggregates the status of Kubernetes resources for your application to report an application status.
### Resource statuses
Possible resource statuses are Ready, Updating, Degraded, Unavailable, and Missing.
The following table lists the supported Kubernetes resources and the conditions that contribute to each status:
| Deployment | StatefulSet | Service | Ingress | PVC | DaemonSet | |
|---|---|---|---|---|---|---|
| Ready | Ready replicas equals desired replicas | Ready replicas equals desired replicas | All desired endpoints are ready, any load balancers have been assigned | All desired backend service endpoints are ready, any load balancers have been assigned | Claim is bound | Ready daemon pods equals desired scheduled daemon pods |
| Updating | The deployed replicas are from a different revision | The deployed replicas are from a different revision | N/A | N/A | N/A | The deployed daemon pods are from a different revision |
| Degraded | At least 1 replica is ready, but more are desired | At least 1 replica is ready, but more are desired | At least one endpoint is ready, but more are desired | At least one backend service endpoint is ready, but more are desired | N/A | At least one daemon pod is ready, but more are desired |
| Unavailable | No replicas are ready | No replicas are ready | No endpoints are ready, no load balancer has been assigned | No backend service endpoints are ready, no load balancer has been assigned | Claim is pending or lost | No daemon pods are ready |
| Missing | Missing is an initial deployment status indicating that informers have not reported their status because the application has just been deployed and the underlying resource has not been created yet. After the resource is created, the status changes. However, if a resource changes from another status to Missing, then the resource was either deleted or the informers failed to report a status. | |||||
| Resource Statuses | Aggregate Application Status |
|---|---|
| No status available for any resource | Missing |
| One or more resources Unavailable | Unavailable |
| One or more resources Degraded | Degraded |
| One or more resources Updating | Updating |
| All resources Ready | Ready |
| Field | Instructions |
| `ports.serviceName` | Add the name of the service. KOTS can create a port forward to ClusterIP, NodePort, or LoadBalancer services. For more information about Kubernetes service types, see [Service](https://kubernetes.io/docs/concepts/services-networking/service/) in the Kubernetes documentation. |
| `ports.servicePort` | Add the `containerPort` of the Pod where the service is running. This is the port where KOTS forwards traffic. Go templates are not supported in the `localPort` or `servicePort` field. For more information, see [`ports`](/reference/custom-resource-application#ports) in _Application_. |
| `ports.localPort` | Add the port to map on the local workstation. Go templates are not supported in the `localPort` or `servicePort` field. For more information, see [`ports`](/reference/custom-resource-application#ports) in _Application_.. |
[View a larger version of this image](/images/gitea-open-app.png)
## Access port-forwarded services
This section describes how to access port-forwarded services.
### Command line
Run [`kubectl kots admin-console`](/reference/kots-cli-admin-console-index) to open the KOTS port forward tunnel.
The `kots admin-console` command runs the equivalent of `kubectl port-forward svc/myapplication-service
[View a larger version of this image](/images/gitea-open-app.png)
## Example: Nginx application with clusterip and nodeport services
The following example demonstrates how to link to a port-forwarded ClusterIP service for existing cluster KOTS installations. It also shows how to use the `ports` key to add a link to a NodePort service for Embedded Cluster or kURL installations. Although the primary purpose of the `ports` key is to port forward services for existing cluster KOTS installations, it is also possible to use the `ports` key so that links to NodePort services for Embedded Cluster or kURL installations use the hostname in the browser. For information about exposing NodePort services for Embedded Cluster or kURL installations, see [Exposing Services Using NodePorts](kurl-nodeport-services).
To test this example:
1. Add the `example-service.yaml`, `example-deployment.yaml`, `kots-app.yaml`, `k8s-app.yaml`, and `embedded-cluster.yaml` files provided below to a new, empty release in the Vendor Portal. Promote to the channel that you use for internal testing. For more information, see [Manage Releases with the Vendor Portal](releases-creating-releases).
The YAML below contains ClusterIP and NodePort specifications for a service named nginx. Each specification uses the kots.io/when annotation with the Replicated Distribution template function to conditionally include the service based on the installation type (existing cluster or Embedded Cluster/kURL cluster). For more information, see Conditionally Including or Excluding Resources.
As shown below, both the ClusterIP and NodePort nginx services are exposed on port 80.
A basic Deployment specification for the NGINX application.
The Replicated Application custom resource below adds port 80 to the KOTS port forward tunnel and maps port 8888 on the local machine. The specification also includes applicationUrl: "http://nginx" so that a link to the service can be added to the Admin Console dashboard.
The Kubernetes Application custom resource lists the same URL as the `ports.applicationUrl` field in the Replicated Application custom resource (`"http://nginx"`). This adds a link to the port-forwarded service on the Admin Console dashboard that uses the hostname in the browser and appends the specified `localPort`. The label to be used for the link in the Admin Console is "Open App".
To install your application with Embedded Cluster, an Embedded Cluster Config must be present in the release. At minimum, the Embedded Cluster Config sets the version of Embedded Cluster that will be installed. You can also define several characteristics about the cluster.
[View a larger version of this image](/images/kotsadm-dashboard-graph.png)
## About customizing graphs
If your application exposes Prometheus metrics, you can add custom graphs to the Admin Console dashboard to expose these metrics to your users. You can also modify or remove the default graphs.
To customize the graphs that are displayed on the Admin Console, edit the [`graphs`](/reference/custom-resource-application#graphs) property in the Replicated Application custom resource manifest file. At a minimum, each graph in the `graphs` property must include the following fields:
* `title`: Defines the graph title that is displayed on the Admin Console.
* `query`: A valid PromQL Prometheus query. You can also include a list of multiple queries by using the `queries` property. For more information about querying Prometheus with PromQL, see [Querying Prometheus](https://prometheus.io/docs/prometheus/latest/querying/basics/) in the Prometheus documentation.
:::note
By default, a kURL cluster exposes the Prometheus expression browser at NodePort 30900. For more information, see [Expression Browser](https://prometheus.io/docs/visualization/browser/) in the Prometheus documentation.
:::
## Limitation
Monitoring applications with Prometheus is not supported for installations with [Replicated Embedded Cluster](/embedded-cluster/v3/embedded-overview).
## Add and modify graphs
To customize graphs on the Admin Console dashboard:
1. In the [Vendor Portal](https://vendor.replicated.com/), click **Releases**. Then, either click **Create release** to create a new release, or click **Edit YAML** to edit an existing release.
1. Create or open the [Replicated Application](/reference/custom-resource-application) custom resource manifest file.
1. In the Application manifest file, under `spec`, add a `graphs` property. Edit the `graphs` property to modify or remove existing graphs or add a new custom graph. For more information, see [graphs](/reference/custom-resource-application#graphs) in _Application_.
**Example**:
The following example shows the YAML for adding a custom graph that displays the total number of user signups for an application.
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: my-application
spec:
graphs:
- title: User Signups
query: 'sum(user_signup_events_total)'
```
1. (Optional) Under `graphs`, copy and paste the specs for the default Disk Usage, CPU Usage, and Memory Usage Admin Console graphs provided in the YAML below.
Adding these default graphs to the Application custom resource manifest ensures that they are not overwritten when you add one or more custom graphs. When the default graphs are included in the Application custom resource, the Admin Console displays them in addition to any custom graphs.
Alternatively, you can exclude the YAML specs for the default graphs to remove them from the Admin Console dashboard.
```yaml
apiVersion: kots.io/v1beta1
kind: Application
metadata:
name: my-application
spec:
graphs:
- title: User Signups
query: 'sum(user_signup_events_total)'
# Disk Usage, CPU Usage, and Memory Usage below are the default graphs
- title: Disk Usage
queries:
- query: 'sum((node_filesystem_size_bytes{job="node-exporter",fstype!="",instance!=""} - node_filesystem_avail_bytes{job="node-exporter", fstype!=""})) by (instance)'
legend: 'Used: {{ instance }}'
- query: 'sum((node_filesystem_avail_bytes{job="node-exporter",fstype!="",instance!=""})) by (instance)'
legend: 'Available: {{ instance }}'
yAxisFormat: bytes
- title: CPU Usage
query: 'sum(rate(container_cpu_usage_seconds_total{namespace="{{repl Namespace}}",container!="POD",pod!=""}[5m])) by (pod)'
legend: '{{ pod }}'
- title: Memory Usage
query: 'sum(container_memory_usage_bytes{namespace="{{repl Namespace}}",container!="POD",pod!=""}) by (pod)'
legend: '{{ pod }}'
yAxisFormat: bytes
```
1. Save and promote the release to a development environment to test your changes.
---
# About integrating with CI/CD
This topic provides an introduction to integrating Replicated CLI commands in your continuous integration and continuous delivery (CI/CD) pipelines, including Replicated's best practices and recommendations.
## Overview
Using CI/CD workflows to automatically compile code and run tests improves the speed at which teams can test, iterate on, and deliver releases to customers. When you integrate Replicated CLI commands into your CI/CD workflows, you can automate the process of deploying your application to clusters for testing, rather than needing to manually create and then archive channels, customers, and environments for testing.
You can also include continuous delivery workflows to automatically promote a release to a shared channel in your Replicated team. This allows you to more easily share releases with team members for internal testing and iteration, and then to promote releases when they are ready to be shared with customers.
## Best practices and recommendations
The following are Replicated's best practices and recommendations for CI/CD:
* Include unique workflows for development and for releasing your application. This allows you to run tests on every commit, and then to promote releases to internal and customer-facing channels only when ready. For more information about the workflows that Replicated recommends, see [Recommended CI/CD Workflows](ci-workflows).
* Integrate Replicated Compatibility Matrix (CMX) into your CI/CD workflows to quickly create multiple different types of clusters where you can deploy and test your application. Supported distributions include OpenShift, GKE, EKS, and more. For more information, see [About CMX](testing-about).
* If you use the GitHub Actions CI/CD platform, integrate the custom GitHub actions that Replicated maintains to replace repetitive tasks related to distributing application with Replicated or using CMX. For more information, see [Use Replicated GitHub Actions in CI/CD](/vendor/ci-workflows-github-actions).
* To help show you are conforming to a secure supply chain, sign all commits and container images. Additionally, provide a verification mechanism for container images.
* Use custom RBAC policies to control the actions that can be performed in your CI/CD workflows. For example, you can create a policy that blocks the ability to promote releases to your production channel. For more information about creating custom RBAC policies in the Vendor Portal, see [Configure RBAC Policies](/vendor/team-management-rbac-configuring). For a full list of available RBAC resources, see [RBAC Resource Names](/vendor/team-management-rbac-resource-names).
* Incorporating code tests into your CI/CD workflows is important for ensuring that developers receive quick feedback and can make updates in small iterations. Replicated recommends that you create and run all of the following test types as part of your CI/CD workflows:
* **Application Testing:** Traditional application testing includes unit, integration, and end-to-end tests. These tests are critical for application reliability, and CMX is designed to to incorporate and use your application testing.
* **Performance Testing:** Performance testing is used to benchmark your application to ensure it can handle the expected load and scale gracefully. Test your application under a range of workloads and scenarios to identify any bottlenecks or performance issues. Make sure to optimize your application for different Kubernetes distributions and configurations by creating all of the environments you need to test in.
* **Smoke Testing:** Using a single, conformant Kubernetes distribution to test basic functionality of your application with default (or standard) configuration values is a quick way to get feedback if something is likely to be broken for all or most customers. Replicated also recommends that you include each Kubernetes version that you intend to support in your smoke tests.
* **Compatibility Testing:** Because applications run on various Kubernetes distributions and configurations, it is important to test compatibility across different environments. CMX provides this infrastructure.
* **Canary Testing:** Before releasing to all customers, consider deploying your application to a small subset of your customer base as a _canary_ release. This lets you monitor the application's performance and stability in real-world environments, while minimizing the impact of potential issues. CMX enables canary testing by simulating exact (or near) customer environments and configurations to test your application with.
---
# Use Replicated GitHub actions in CI/CD
This topic describes how to integrate Replicated's custom GitHub actions into continuous integration and continuous delivery (CI/CD) workflows that use the GitHub Actions platform.
## Overview
Replicated maintains a set of custom GitHub actions that are designed to replace repetitive tasks related to distributing your application with Replicated and related to using Replicated Compatibility Matrix (CMX), such as:
* Creating and removing customers, channels, and clusters
* Promoting releases
* Creating a matrix of clusters for testing based on the Kubernetes distributions and versions where your customers are running application instances
* Reporting the success or failure of tests
If you use GitHub Actions as your CI/CD platform, you can include these custom actions in your workflows rather than using Replicated CLI commands. Integrating the Replicated GitHub actions into your CI/CD pipeline helps you quickly build workflows with the required inputs and outputs, without needing to manually create the required CLI commands for each step.
To view all the available GitHub actions that Replicated maintains, see the [replicatedhq/replicated-actions](https://github.com/replicatedhq/replicated-actions/) repository in GitHub.
## GitHub actions workflow examples
The [replicatedhq/replicated-actions](https://github.com/replicatedhq/replicated-actions#examples) repository in GitHub contains example workflows that use the Replicated GitHub actions. You can use these workflows as a template for your own GitHub Actions CI/CD workflows:
* For a simplified development workflow, see [development-helm-prepare-cluster.yaml](https://github.com/replicatedhq/replicated-actions/blob/main/example-workflows/development-helm-prepare-cluster.yaml).
* For a customizable development workflow for applications installed with the Helm CLI, see [development-helm.yaml](https://github.com/replicatedhq/replicated-actions/blob/main/example-workflows/development-helm.yaml).
* For a customizable development workflow for applications installed with KOTS, see [development-kots.yaml](https://github.com/replicatedhq/replicated-actions/blob/main/example-workflows/development-kots.yaml).
* For a release workflow, see [release.yaml](https://github.com/replicatedhq/replicated-actions/blob/main/example-workflows/release.yaml).
## Integrate GitHub actions
The following table lists GitHub actions that are maintained by Replicated that you can integrate into your CI/CI workflows. The table also describes when to use the action in a workflow and indicates the related Replicated CLI command where applicable.
:::note
For an up-to-date list of the avilable custom GitHub actions, see the [replicatedhq/replicated-actions](https://github.com/replicatedhq/replicated-actions/) repository in GitHub.
:::
| GitHub Action | When to Use | Related Replicated CLI Commands |
|---|---|---|
| archive-channel |
In release workflows, a temporary channel is created to promote a release for testing. This action archives the temporary channel after tests complete. See Archive the temporary channel and customer in Recommended CI/CD Workflows. |
channel delete |
| archive-customer |
In release workflows, a temporary customer is created so that a release can be installed for testing. This action archives the temporary customer after tests complete. See Archive the temporary channel and customer in Recommended CI/CD Workflows. |
N/A |
| create-cluster |
In release workflows, use this action to create one or more clusters for testing. See Create cluster matrix, deploy, and test in Recommended CI/CD Workflows. |
cluster create |
| create-release |
In release workflows, use this action to create a release to be installed and tested, and optionally to be promoted to a shared channel after tests complete. See Create a release and promote to a temporary channel in Recommended CI/CD Workflows. |
release create |
| get-customer-instances |
In release workflows, use this action to create a matrix of clusters for running tests based on the Kubernetes distributions and versions of active instances of your application running in customer environments. See Create cluster matrix, deploy, and test in Recommended CI/CD Workflows. |
N/A |
| helm-install |
In development or release workflows, use this action to install a release using the Helm CLI in one or more clusters for testing. See Create cluster matrix, deploy, and test in Recommended CI/CD Workflows. |
N/A |
| kots-install |
In development or release workflows, use this action to install a release with Replicated KOTS in one or more clusters for testing. See Create cluster matrix, deploy, and test in Recommended CI/CD Workflows. |
N/A |
| prepare-cluster |
In development workflows, use this action to create a cluster, create a temporary customer of type See Prepare clusters, deploy, and test in Recommended CI/CD Workflows. |
cluster prepare |
| promote-release |
In release workflows, use this action to promote a release to an internal or customer-facing channel (such as Unstable, Beta, or Stable) after tests pass. See Promote to a shared channel in Recommended CI/CD Workflows. |
release promote |
| remove-cluster |
In development or release workflows, use this action to remove a cluster after running tests if no See Prepare clusters, deploy, and test and Create cluster matrix, deploy, and test in Recommended CI/CD Workflows. |
cluster rm |
| report-compatibility-result | In development or release workflows, use this action to report the success or failure of tests that ran in clusters provisioned by CMX. | release compatibility |
| upgrade-cluster | In release workflows, use this action to test your application's compatibility with Kubernetes API resource version migrations after upgrading. | cluster upgrade |
[View a larger version of this image](/images/helm-install-diagram.png)
As shown in the diagram, customers install your Helm chart by authenticating to the [Replicated proxy registry](/vendor/private-images-about) with their unique license ID. This ensures that every customer who installs your chart has a valid, unexpired license. After logging in, they run `helm install` to install the chart.
For Helm CLI installations, customers can optionally run preflight checks before installing to verify that their cluster meets your application's requirements. For more information, see [Define Preflight Checks](preflight-defining).
## Installations with Embedded Cluster on a VM
Replicated Embedded Cluster allows you to distribute a Kubernetes cluster and your application together as a single appliance. Enterprise users install, update, and manage the application and the cluster in tandem on a VM or bare metal server. Embedded Cluster uses the open source Kubernetes distribution [k0s](https://k0sproject.io/).
Embedded Cluster provides a built-in UI that guides users through installation and upgrades. This includes license validation, preflight checks, and application configuration. Cluster infrastructure updates alongside application updates, so users do not need to manage Kubernetes separately.
Vendors configure the [Embedded Cluster Config](/embedded-cluster/v3/embedded-config) to define the cluster and installation. This includes optional Helm extensions that deploy additional components before your application.
For more information, see [Embedded Cluster Overview](/embedded-cluster/v3/embedded-overview).
## Supporting both installation methods from the same release
With Replicated, you support both Helm CLI and Embedded Cluster installations from a single release. You package your application as Helm charts, and each release can include an Embedded Cluster Config for VM-based installations. You maintain one set of artifacts while giving customers the flexibility to choose the method that fits their environment.
For more information about creating releases, see [About releasing your application](concepts-release).
---
# About customer licensing
Licensing codifies the agreements in the software contract between the vendor and the enterprise customer. It makes those agreements available to the application through a license server at installation and runtime.
Licensing is a cross-functional concern:
* **Sales teams** need license entitlements integrated with CRM tools like Salesforce so that entitlements can be updated when contracts change.
* **Support teams** need the license as a unique customer identifier to get visibility into entitlements and product usage.
* **Engineering teams** need application logic that controls access to features based on entitlements, without requiring code changes each time a license agreement changes.
## About customer records
In the Replicated Vendor Portal, each licensed end customer has a customer record. The record includes the customer's license, which defines their entitlements, expiration date, release channel, and available installation methods. You can create and manage customer records in the Vendor Portal or with the Replicated CLI and Vendor API.
For more information, see [Create and Manage Customers](releases-creating-customer).
## About custom license entitlements
License agreements for enterprise software often include entitlements such as:
* **Expiration dates** for trial or Proof-of-Concept licenses
* **Feature-based entitlements** to control access to features available only under certain product plans
* **Usage-based entitlements** to limit the number of instances, users, or nodes permitted
* **Application-specific entitlements**, such as controlling which AI model images a customer can access
Define custom license fields in the Vendor Portal to represent these entitlements. The [Replicated SDK](/vendor/replicated-sdk-overview) provides an in-cluster API that your application queries at runtime to retrieve the customer's current entitlements.
For more information, see [About Customers and Licensing](licenses-about).
## Use license fields in custom metrics
In most cases, vendors rely on the license agreement to enforce entitlements, as enterprise customers avoid violating a software contract. Rather than blocking usage in code, most vendors track usage that exceeds the contract and reconcile at renewal. The exception is expiration dates, which you can enforce directly and extend as needed.
Measuring usage surfaces data to both the vendor and the customer. For vendors, it helps identify opportunities to expand the agreement. For customers, understanding their own usage helps them stay within contractual limits.
For more information about custom metrics, see [Configure Custom Metrics](custom-metrics).
## Use license fields in preflight checks
Reference license field values in preflight check specifications to validate that the customer's environment meets their license requirements. For example, write a preflight check that verifies the node count does not exceed the customer's licensed limit.
For more information, see [Define Preflight Checks](preflight-defining).
---
# About releasing your application
Releasing refers to the process of delivering software to licensed users, ensuring that new features, improvements, and bug fixes get into the hands of the right customers at the right frequency.
Key considerations for vendors when releasing modern enterprise software include:
* Making application images available for customers to access securely
* Packaging and publishing cryptographically signed release artifacts for different installation methods
* Demonstrating the integrity of each release with supply chain metadata like SBOMs and provenance attestations
* Managing release streams for different customers, including production (GA) and pre-release (alpha, beta) versions
* Versioning releases with a consistent pattern so that customers understand backward compatibility
## About creating your application releases
### Packaging with Helm
Replicated releases are built around Helm charts. You package your application as one or more Helm charts, which Replicated distributes through the proxy registry. Use standard Helm packaging practices and your existing CI/CD pipelines to build charts, then promote them as Replicated releases.
For more information, see [Manage Releases with the CLI](releases-creating-cli).
### Release files for installers
A release contains your application Helm charts and any additional manifests required for installation. For Embedded Cluster installations, releases also include an Embedded Cluster Config that defines the cluster, Helm extensions, and node roles. Replicated generates the appropriate installation assets for each method, including air gap bundles for disconnected environments.
### About iterating on releases with the Replicated platform
Replicated supports a rapid iteration workflow where you create and test releases frequently. Use the Replicated CLI to create releases from your local environment or automate release creation in CI/CD. Promote releases to development channels and install them in test environments provisioned with Compatibility Matrix for fast feedback before promoting to customer-facing channels.
## About managing releases with channels
Release management is important for ensuring that each release is made available to the right subset of users (including internal teams and customers).
With Replicated, each release is promoted to one or more _channels_.
Channels provide a way to progress releases through the software development lifecycle: from internal testing, to sharing with early-adopters, and finally to making the release generally available.
Channels also control which customers are able to install a release.
You assign each customer to a channel to define the releases that the customer can access.
For more information, see [About Channels and Releases](releases-about).
Channels create a logical separation between different types of releases. You can isolate releases intended for internal testing without manually granting or restricting access. Channels also provide flexibility in release frequency, letting you publish updates to internal channels more often while maintaining a different pace for GA releases.
For example, vendors might keep separate channels for internal-only, experimental, beta, and generally available (GA) releases.
Enterprise customers and internal users can then access the releases published to the channel where they are subscribed.
### Default unstable, beta, and stable channels
Replicated includes the following channels by default:
* **Unstable**: The Unstable channel is designed for internal testing and development. You can create and assign an internal test customer to the Unstable channel to install in a development environment. Replicated recommends that you do not license any of your external users against the Unstable channel.
* **Beta**: The Beta channel is designed for release candidates and early-adopting customers. Replicated recommends that you promote a release to the Beta channel after it has passed automated testing in the Unstable channel. You can also choose to license early-adopting customers against this channel.
* **Stable**: The Stable channel is designed for releases that are generally available. Replicated recommends that you assign most of your customers to the Stable channel. Customers licensed against the Stable channel only receive application updates when you promote a new release to the Stable channel.
## About testing your releases
Testing ensures that enterprise software can be reliably distributed to current and future customer environments. Catching issues before the application reaches customers improves the customer experience and manages costs. Discovering and fixing a bug after the fact is more expensive than investing in testing up front.
### Customer-representative environments with compatibility matrix
Testing self-hosted software presents a unique challenge: both the application and the customer’s environment can cause a failed deployment. The same application that installs successfully in one environment might fail in the next. Testing must go beyond unit and integration tests to verify functionality across different environments.
Test on a variety of distributions representative of your customer base. For example, you might test on vanilla Kubernetes, a cloud provider (like GKE or AKS), and a more complex distribution like OpenShift.
For more information, see [About Compatibility Matrix](testing-about).
## Provide secure access to images with the proxy registry
A single release for an application contains all the artifacts required to install and run the application, such as container images or executables.
When publishing a release for distribution to self-hosted environments, software vendors need to make images available to customers securely.
For online (internet-connected) environments, proxy servers grant pull-through access to images. A proxy acts as an intermediary between your private image registry and the customer, so users access images without exposing registry credentials. Customers authenticate with credentials you determine, such as their unique license ID.
For air gap environments, customers must have access to downloadable archives that contain the release images so they can push images to their own registry.
For more information, see [About the Replicated Proxy Registry](/vendor/private-images-about).
All image pull activity can be tracked for auditing and reporting. For more information, see [About Telemetry and Reporting](concepts-report).
## Release versioning
Assign and increment version numbers using a consistent pattern, such as Semantic Versioning (SemVer). SemVer communicates backward compatibility using the format `MAJOR.MINOR.PATCH`.
The versioning pattern should also dictate how you indicate pre-release versions. With SemVer, alpha or beta versions append a hyphen and label, such as `1.0.0-alpha` or `1.2.3-0.0.2`.
A consistent pattern like SemVer is important because vendors often support multiple versions concurrently. Enterprise customers can understand that a patch release is backward compatible with the corresponding minor version.
## Automate releases with CI/CD
Minimize manual intervention by automating release management and publishing in your CI/CD pipelines.
For example, vendors can create workflows that run tests, publish releases to the right channel, and notify customers subscribed to the channel that a new version is available.
For more information, see [About Integrating with CI/CD](ci-overview).
---
# About telemetry and reporting
With Replicated, you get out-of-the-box visibility into your application instances running in customer-controlled environments. For example:
* Metadata about the environment where the application is running, such as the Kubernetes distribution, version, or cloud provider
* Application uptime and service status
* Adoption data such as the current application version
Replicated also supports collecting custom metrics through the [Replicated SDK](/vendor/replicated-sdk-overview) for reporting on usage data such as daily or weekly active users.
Unlike traditional observability with its firehose of logs, Replicated reporting focuses on application usage and functionality at a customer level.
Access to reporting data empowers vendors to take more informed action:
* **Feature prioritization**: Low feature usage can indicate the need to invest in usability, discoverability, or documentation.
* **Security scoping**: Knowing which version each customer is running helps you scope and prioritize CVE disclosures and patches.
* **Churn and growth signals**: Decreased usage for a customer can indicate churn risk, while increased usage can indicate expansion opportunities.
* **Performance monitoring**: Uptime data helps troubleshoot issues and understand the resiliency of your software.
## Custom metrics with the SDK
In addition to built-in insights like uptime and time to install, you can configure custom metrics to measure application instances in customer environments. Collect custom metrics from instances in both online and air gap environments.
The following diagram demonstrates how a custom `activeUsers` metric is sent to the in-cluster API and displayed in the Vendor Portal:
[View a larger version of this image](/images/custom-metrics-flow.png)
For more information, see [Configure Custom Metrics](custom-metrics).
## Air gap telemetry
Air gap instances run in environments without outbound internet access, so they cannot send telemetry to the Vendor Portal directly. Instead, the Replicated SDK collects and stores instance telemetry, including custom metrics, in a Kubernetes Secret in the customer environment.
When a customer generates a support bundle, the stored telemetry is included automatically. When the bundle is uploaded to the Vendor Portal, the telemetry is associated with the correct customer and instance, and the Vendor Portal updates insights and event data accordingly.
Replicated recommends collecting support bundles from air gap customers regularly (monthly or quarterly) to maintain complete telemetry data. The Vendor Portal handles overlapping event archives idempotently.
For more information, see [Collect Telemetry for Air Gap Instances](telemetry-air-gap).
## Event notifications
Define and subscribe to notifications in the Vendor Portal to receive alerts when specific events occur. Built-in event types and filters let you target the events that matter most. For example:
* Customer Success Managers could get an email when a key customer uploads a support bundle
* Support Engineers could get a Slack notification when a customer instance has been unhealthy for an extended period
The following shows an example of the notifications **Overview** page:

[View a larger version of this image](/images/notifications-overview.png)
For more information, see [Configure Event Notifications](/vendor/event-notifications).
---
# About supporting your application
Support refers to the services, tools, and documentation offered by a software vendor that help customers troubleshoot and resolve issues with their deployed instances.
For enterprise software, a Service Level Agreement (SLA) typically defines support expectations: response times, standard support hours, and emergency support. Common expectations include 24/7 support hours and a response time under three hours for critical issues.
Support teams aim to reduce the mean time to resolution (MTTR) while meeting SLA commitments. To do this, they need:
* The training and expertise to address customer issues
* Access to diagnostic information from the customer environment, such as logs, the Kubernetes distribution and version, and usage data
## The challenge of on-prem support
Accessing diagnostic information is challenging for on-prem software because customer environments are often disconnected. Support engineers cannot SSH into machines or view observability data directly. Instead, vendors need tools that securely collect redacted information and run diagnostics.
Replicated provides two tools for this: **preflight checks** and **support bundles**.
## Preflight checks
Preflight checks run before or during installation to validate that the customer's environment meets application requirements. They catch issues like insufficient resources, missing dependencies, or incompatible Kubernetes versions before installation.
For more information, see [Define Preflight Checks](preflight-defining). For example specs, see [Example Preflight Specs](preflight-examples).
## Support bundles
Support bundles collect diagnostic information from a running instance: logs, cluster state, and application-specific data. Customers generate a bundle and upload it through the [Enterprise Portal](/vendor/enterprise-portal-v2-about) or share it with your support team. Uploaded bundles become available for analysis in the Vendor Portal.
Support bundles are valuable beyond just your own troubleshooting. When you open a support request with Replicated, including a support bundle dramatically improves resolution time. Based on historical data, Severity 1 issues with an attached support bundle have been resolved up to three times faster. The Vendor Portal can also pre-populate support request details from the bundle, reducing the back-and-forth needed to get to a resolution.
For more information, see [Add and Customize Support Bundles](support-bundle-customizing). For example specs, see [Example Support Bundle Specs](support-bundle-examples).
## Treating specs as living documents
Preflight and support bundle specs should not be static. As customers deploy across diverse environments, you learn which checks matter and what diagnostic information helps most during escalations.
Treat your specs as living documents that evolve over time:
* **After support escalations**, add collectors or analyzers that capture what would have helped resolve the issue faster. If a ticket required manual root cause analysis, codify that investigation as a new analyzer.
* **After installation failures**, add preflight checks that would have caught the issue. For example, if an install failed due to a missing storage class, add a check so the next customer gets a warning.
* **As your application evolves**, update specs for new components and dependencies. A feature that adds a database dependency should include a preflight check for connectivity and a collector for database logs.
The most effective vendors review specs regularly alongside support metrics, using ticket patterns to identify gaps in what they check and collect.
## Getting support from Replicated
Replicated provides support to help you troubleshoot issues with the Replicated Platform and your application deployments. You can submit support requests and attach support bundles directly from the Vendor Portal.
For more information, see [Submit a Support Request](support-submit-request).
## Documentation and self-service support
High-quality documentation and community help articles help customers self-resolve issues. Keep documentation up to date with troubleshooting information for common issues to reduce repeat tickets.
---
# About the configuration screen
This topic describes the configuration screen on the Config tab in the Replicated Admin Console.
:::note
Replicated KOTS is available only for existing customers. For supporting installations into customer managed clusters, we recommend Helm. For more information, see [About Helm Installations with Replicated](/vendor/helm-install-overview).
KOTS is a Generally Available (GA) product for existing customers. For more information about the Replicated product lifecycle phases, see [Support Lifecycle Policy](/vendor/policies-support-lifecycle).
:::
## About collecting configuration values
When you distribute your application with Replicated KOTS, you can include a configuration screen in the Admin Console. This configuration screen is used to collect required or optional values from your users that are used to run your application. You can use regular expressions to validate user input for some fields, such as passwords and email addresses. For more information about how to add custom fields to the configuration screen, see [Create and Edit Configuration Fields](admin-console-customize-config-screen).
If you use a Helm chart for your application, your users provide any values specific to their environment from the configuration screen, rather than in a Helm chart `values.yaml` file. This means that your users can provide configuration values through a user interface, rather than having to edit a YAML file or use `--set` CLI commands. The Admin Console configuration screen also allows you to control which options you expose to your users.
For example, you can use the configuration screen to provide database configuration options for your application. Your users could connect your application to an external database by providing required values in the configuration screen, such as the host, port, and a username and password for the database.
Or, you can also use the configuration screen to provide a database option that runs in the cluster as part of your application. For an example of this use case, see [Example: Adding Database Configuration Options](tutorial-adding-db-config).
## Viewing the configuration screen
If you include a configuration screen with your application, users of your application can access the configuration screen from the Admin Console:
* During application installation.
* At any time after application installation on the Admin Console Config tab.
### Application installation
The Admin Console displays the configuration screen when the user installs the application, after they upload their license file.
The following shows an example of how the configuration screen displays during installation:

[View a larger version of this image](/images/config-screen-sentry-enterprise-app-install.png)
### Admin Console Config tab
Users can access the configuration screen any time after they install the application by going to the Config tab in the Admin Console.
The following shows an example of how the configuration screen displays in the Admin Console Config tab:

[View a larger version of this image](/images/config-screen-sentry-enterprise.png)
---
# Use conditional statements in configuration fields
This topic describes how to use Replicated template functions in the Config custom resource to conditionally show or hide configuration fields for your application on the Replicated KOTS Admin Console **Config** page.
:::note
Replicated KOTS is available only for existing customers. For supporting installations into customer managed clusters, we recommend Helm. For more information, see [About Helm Installations with Replicated](/vendor/helm-install-overview).
KOTS is a Generally Available (GA) product for existing customers. For more information about the Replicated product lifecycle phases, see [Support Lifecycle Policy](/vendor/policies-support-lifecycle).
:::
## Overview
The `when` property in the Config custom resource denotes configuration groups or items that are displayed on the Admin Console **Config** page only when a condition evaluates to true. When the condition evaluates to false, the group or item is not displayed.
This lets you conditionally show or hide fields so your end customers only see the options that are relevant to them.
You can use Go template functions to create conditional statements. Replicated provides a set of Go template functions that you can use to evaluate conditions like the user's environment, their license entitlements, and their previous configuration choices. For more information, see [About Replicated Template Functions](/reference/template-functions-about).
For more information about the Config custom resource `when` property, see [when](/reference/custom-resource-config#when) in _Config_.
## Conditional statement examples
This section includes examples of common types of conditional statements used in the `when` property of the Config custom resource.
For additional examples of using conditional statements in the Config custom resource, see [Applications](https://github.com/replicatedhq/platform-examples/tree/main/applications) in the platform-examples repository in GitHub.
### Cluster distribution check
It can be useful to show or hide configuration fields depending on the distribution of the cluster because different distributions often have unique requirements.
In the following example, the `when` properties use the [Distribution](/reference/template-functions-static-context#distribution) template function to return the Kubernetes distribution of the cluster where Replicated KOTS is running. If the distribution of the cluster matches the specified distribution, then the `when` property evaluates to true.
The following example uses:
* Replicated [Distribution](/reference/template-functions-static-context#distribution) template function to return the Kubernetes distribution of the cluster
* [eq](https://pkg.go.dev/text/template#hdr-Functions) (_equal_) Go binary operator to compare the rendered value of the Distribution template function to a string, then return the boolean truth of the comparison
```yaml
# Replicated Config custom resource
apiVersion: kots.io/v1beta1
kind: Config
metadata:
name: config-sample
spec:
groups:
- name: example_settings
title: My Example Config
description: Example fields for using Distribution template function
items:
- name: gke_distribution
type: label
title: "You are deploying to GKE"
# Use the eq binary operator to check if the rendered value
# of the Distribution template function is equal to gke
when: repl{{ eq Distribution "gke" }}
- name: openshift_distribution
type: label
title: "You are deploying to OpenShift"
when: repl{{ eq Distribution "openShift" }}
- name: eks_distribution
type: label
title: "You are deploying to EKS"
when: repl{{ eq Distribution "eks" }}
...
```
The following image shows how only the `gke_distribution` item appears on the app configuration screen:
### Embedded Cluster distribution check
It can be useful to show or hide configuration fields if the distribution of the cluster is [Replicated Embedded Cluster](/embedded-cluster/v3/embedded-overview) because you can include extensions in embedded cluster distributions to manage functionality such as ingress and storage. This means that embedded clusters frequently have fewer configuration options for the user.
In the following example, the `ingress_type` field appears on the configuration page only when the distribution of the cluster is _not_ [Replicated Embedded Cluster](/embedded-cluster/v3/embedded-overview). This ensures that only users deploying to their own existing cluster are able to select the method for ingress.
The following example uses:
* Replicated [Distribution](/reference/template-functions-static-context#distribution) template function to return the Kubernetes distribution of the cluster
* [ne](https://pkg.go.dev/text/template#hdr-Functions) (_not equal_) Go binary operator to compare the rendered value of the Distribution template function to a string, then return `true` if the values are not equal to one another
```yaml
apiVersion: kots.io/v1beta1
kind: Config
metadata:
name: config
spec:
groups:
# Ingress settings
- name: ingress_settings
title: Ingress Settings
description: Configure Ingress
items:
- name: ingress_type
title: Ingress Type
help_text: |
Select how traffic will ingress to the appliction.
type: radio
items:
- name: ingress_controller
title: Ingress Controller
- name: load_balancer
title: Load Balancer
default: "ingress_controller"
required: true
when: 'repl{{ ne Distribution "embedded-cluster" }}'
# Database settings
- name: database_settings
title: Database
items:
- name: postgres_type
help_text: Would you like to use an embedded postgres instance, or connect to an external instance that you manage?
type: radio
title: Postgres
default: embedded_postgres
items:
- name: embedded_postgres
title: Embedded Postgres
- name: external_postgres
title: External Postgres
```
The following image shows how the `ingress_type` field does not appear when the distribution of the cluster is `embedded-cluster`. Only the `postgres_type` item appears:
[View a larger version of this image](/images/config-example-distribution-not-ec.png)
Conversely, when the distribution of the cluster is not `embedded-cluster`, both fields appear:
[View a larger version of this image](/images/config-example-distribution-not-ec-2.png)
### kURL distribution check
It can be useful to show or hide configuration fields if the cluster was provisioned by Replicated kURL because kURL distributions often include add-ons to manage functionality such as ingress and storage. This means that kURL clusters frequently have fewer configuration options for the user.
In the following example, the `when` property of the `not_kurl` group uses the IsKurl template function to evaluate if the cluster was provisioned by kURL. For more information about the IsKurl template function, see [IsKurl](/reference/template-functions-static-context#iskurl) in _Static Context_.
```yaml
# Config custom resource
apiVersion: kots.io/v1beta1
kind: Config
metadata:
name: config-sample
spec:
groups:
- name: all_distributions
title: Example Group
description: This group always displays.
items:
- name: example_item
title: This item always displays.
type: text
- name: not_kurl
title: Non-kURL Cluster Group
description: This group displays only if the cluster is not provisioned by kURL.
when: 'repl{{ not IsKurl }}'
items:
- name: example_item_non_kurl
title: The cluster is not provisioned by kURL.
type: label
```
As shown in the image below, both the `all_distributions` and `non_kurl` groups are displayed on the **Config** page when KOTS is _not_ running in a kURL cluster:

[View a larger version of this image](/images/config-example-iskurl-false.png)
However, when KOTS is running in a kURL cluster, only the `all_distributions` group is displayed, as shown below:

[View a larger version of this image](/images/config-example-iskurl-true.png)
### License field value equality check
You can show or hide configuration fields based on the values in a license to ensure that users only see configuration options for the features and entitlements granted by their license.
In the following example, the `when` property of the `new_feature_config` item uses the LicenseFieldValue template function to determine if the user's license contains a `newFeatureEntitlement` field that is set to `true`. For more information about the LicenseFieldValue template function, see [LicenseFieldValue](/reference/template-functions-license-context#licensefieldvalue) in _License Context_.
```yaml
apiVersion: kots.io/v1beta1
kind: Config
metadata:
name: config-sample
spec:
groups:
- name: example_settings
title: My Example Config
description: Example fields for using LicenseFieldValue template function
items:
- name: new_feature_config
type: label
title: "You have the new feature entitlement"
when: '{{repl (LicenseFieldValue "newFeatureEntitlement") }}'
```
As shown in the image below, the **Config** page displays the `new_feature_config` item when the user's license contains `newFeatureEntitlement: true`:

[View a larger version of this image](/images/config-example-newfeature.png)
### Show messaging for unavailable features
When all items in a group are hidden by `when` conditions, the entire group is hidden, including its title and description. To display a message to users when a feature is unavailable (for example, to inform them that they need to upgrade their license to access certain configuration options), add a `label` item to the group that is shown in the negated condition.
In the following example, the `enterprise_features` group contains two items that are shown only when the user's license includes the `enterprise_features` field set to `true`. The `upgrade_notice` item uses `type: label` with a negated `when` condition so that it is displayed when the entitlement is missing, ensuring the group remains visible with an informational message.
```yaml
apiVersion: kots.io/v1beta1
kind: Config
metadata:
name: config-sample
spec:
groups:
- name: enterprise_features
title: Enterprise Features
description: Advanced configuration options.
items:
- name: advanced_setting
title: Advanced Setting
type: text
when: '{{repl (LicenseFieldValue "enterprise_features" | ParseBool) }}'
- name: another_advanced_setting
title: Another Advanced Setting
type: text
when: '{{repl (LicenseFieldValue "enterprise_features" | ParseBool) }}'
- name: upgrade_notice
type: label
title: "Upgrade your license to access these features."
when: '{{repl not (LicenseFieldValue "enterprise_features" | ParseBool) }}'
```
In this example, when the `enterprise_features` license field is missing or false, only the `upgrade_notice` label is shown and the group remains visible. When the entitlement is present, the label is hidden and the actual configuration items are shown.
### License field value integer comparison
You can show or hide configuration fields based on the values in a license to ensure that users only see configuration options for the features and entitlements granted by their license. You can also compare integer values from license fields to control the configuration experience for your users.
The following example uses:
* Replicated [LicenseFieldValue](/reference/template-functions-license-context#licensefieldvalue) template function to evaluate the number of seats permitted by the license
* Sprig [atoi](https://masterminds.github.io/sprig/conversion.html) function to convert the string values returned by LicenseFieldValue to integers
* [Go binary comparison operators](https://pkg.go.dev/text/template#hdr-Functions) `gt`, `lt`, `ge`, and `le` to compare the integers
```yaml
# Replicated Config custom resource
apiVersion: kots.io/v1beta1
kind: Config
metadata:
name: config-sample
spec:
groups:
- name: example_group
title: Example Config
items:
- name: small
title: Small (100 or Fewer Seats)
type: text
default: Default for small teams
# Use le and atoi functions to display this config item
# only when the value of the numSeats entitlement is
# less than or equal to 100
when: repl{{ le (atoi (LicenseFieldValue "numSeats")) 100 }}
- name: medium
title: Medium (101-1000 Seats)
type: text
default: Default for medium teams
# Use ge, le, and atoi functions to display this config item
# only when the value of the numSeats entitlement is
# greater than or equal to 101 and less than or equal to 1000
when: repl{{ (and (ge (atoi (LicenseFieldValue "numSeats")) 101) (le (atoi (LicenseFieldValue "numSeats")) 1000)) }}
- name: large
title: Large (More Than 1000 Seats)
type: text
default: Default for large teams
# Use gt and atoi functions to display this config item
# only when the value of the numSeats entitlement is
# greater than 1000
when: repl{{ gt (atoi (LicenseFieldValue "numSeats")) 1000 }}
```
As shown in the image below, if the user's license contains `numSeats: 150`, then the `medium` item is displayed on the **Config** page and the `small` and `large` items are not displayed:
[View a larger version of this image](/images/config-example-numseats.png)
### User-supplied value check
You can show or hide configuration fields based on user-supplied values on the **Config** page to ensure that users only see options that are relevant to their selections.
In the following example, the `database_host` and `database_passwords` items use the ConfigOptionEquals template function to evaluate if the user selected the `external` database option for the `db_type` item. For more information about the ConfigOptionEquals template function, see [ConfigOptionEquals](/reference/template-functions-config-context#configoptionequals) in _Config Context_.
```yaml
apiVersion: kots.io/v1beta1
kind: Config
metadata:
name: config-sample
spec:
groups:
- name: database_settings_group
title: Database Settings
items:
- name: db_type
title: Database Type
type: radio
default: external
items:
- name: external
title: External Database
- name: embedded
title: Embedded Database
- name: database_host
title: Database Hostname
type: text
when: '{{repl (ConfigOptionEquals "db_type" "external")}}'
- name: database_password
title: Database Password
type: password
when: '{{repl (ConfigOptionEquals "db_type" "external")}}'
```
As shown in the images below, when the user selects the external database option, the `database_host` and `database_passwords` items are displayed. Alternatively, when the user selects the embedded database option, the items are _not_ displayed:

[View a larger version of this image](/images/config-example-external-db.png)

[View a larger version of this image](/images/config-example-embedded-db.png)
## Use multiple conditions in the `when` property
You can use more than one template function in the `when` property to create more complex conditional statements. This allows you to show or hide configuration fields based on multiple conditions being true.
The following example includes `when` properties that use both the ConfigOptionEquals and IsKurl template functions:
```yaml
apiVersion: kots.io/v1beta1
kind: Config
metadata:
name: config-sample
spec:
groups:
- name: ingress_settings
title: Ingress Settings
description: Configure Ingress
items:
- name: ingress_type
title: Ingress Type
help_text: |
Select how traffic will ingress to the appliction.
type: radio
items:
- name: ingress_controller
title: Ingress Controller
- name: load_balancer
title: Load Balancer
default: "ingress_controller"
required: true
when: 'repl{{ not IsKurl }}'
- name: ingress_host
title: Hostname
help_text: Hostname used to access the application.
type: text
default: "hostname.example.com"
required: true
when: 'repl{{ and (not IsKurl) (ConfigOptionEquals "ingress_type" "ingress_controller") }}'
- name: ingress_annotations
type: textarea
title: Ingress Annotations
help_text: See your ingress controller’s documentation for the required annotations.
when: 'repl{{ and (not IsKurl) (ConfigOptionEquals "ingress_type" "ingress_controller") }}'
- name: ingress_tls_type
title: Ingress TLS Type
type: radio
items:
- name: self_signed
title: Self Signed (Generate Self Signed Certificate)
- name: user_provided
title: User Provided (Upload a TLS Certificate and Key Pair)
required: true
default: self_signed
when: 'repl{{ and (not IsKurl) (ConfigOptionEquals "ingress_type" "ingress_controller") }}'
- name: ingress_tls_cert
title: TLS Cert
type: file
when: '{{repl and (ConfigOptionEquals "ingress_type" "ingress_controller") (ConfigOptionEquals "ingress_tls_type" "user_provided") }}'
required: true
- name: ingress_tls_key
title: TLS Key
type: file
when: '{{repl and (ConfigOptionEquals "ingress_type" "ingress_controller") (ConfigOptionEquals "ingress_tls_type" "user_provided") }}'
required: true
- name: load_balancer_port
title: Load Balancer Port
help_text: Port used to access the application through the Load Balancer.
type: text
default: "443"
required: true
when: 'repl{{ and (not IsKurl) (ConfigOptionEquals "ingress_type" "load_balancer") }}'
- name: load_balancer_annotations
type: textarea
title: Load Balancer Annotations
help_text: See your cloud provider’s documentation for the required annotations.
when: 'repl{{ and (not IsKurl) (ConfigOptionEquals "ingress_type" "load_balancer") }}'
```
As shown in the image below, the configuration fields that are specific to the ingress controller display only when the user selects the ingress controller option and KOTS is _not_ running in a kURL cluster:

[View a larger version of this image](/images/config-example-ingress-controller.png)
Additionally, the options relevant to the load balancer display when the user selects the load balancer option and KOTS is _not_ running in a kURL cluster:

[View a larger version of this image](/images/config-example-ingress-load-balancer.png)
---
# Map user-supplied values
This topic describes how to map the values that your users provide in the Replicated Admin Console configuration screen to your application.
This topic assumes that you have already added custom fields to the Admin Console configuration screen by editing the Config custom resource. For more information, see [Create and Edit Configuration Fields](admin-console-customize-config-screen).
:::note
Replicated KOTS is available only for existing customers. For supporting installations into customer managed clusters, we recommend Helm. For more information, see [About Helm Installations with Replicated](/vendor/helm-install-overview).
KOTS is a Generally Available (GA) product for existing customers. For more information about the Replicated product lifecycle phases, see [Support Lifecycle Policy](/vendor/policies-support-lifecycle).
:::
## Overview of mapping values
You use the values that your users provide in the Admin Console configuration screen to render YAML in the manifest files for your application.
For example, if you provide an embedded database with your application, you might add a field on the Admin Console configuration screen where users input a password for the embedded database. You can then map the password that your user supplies in this field to the Secret manifest file for the database in your application.
For an example of mapping database configuration options in a sample application, see [Example: Adding Database Configuration Options](tutorial-adding-db-config).
You can also conditionally deploy custom resources depending on the user input for a given field. For example, if a customer chooses to use their own database with your application rather than an embedded database option, it is not desirable to deploy the optional database resources such as a StatefulSet and a Service.
For more information about including optional resources conditionally based on user-supplied values, see [Conditionally Including or Excluding Resources](packaging-include-resources).
## About mapping values with template functions
To map user-supplied values, you use Replicated template functions. The template functions are based on the Go text/template libraries. To use template functions, you add them as strings in the custom resource manifest files in your application.
For more information about template functions, including use cases and examples, see [About Replicated Template Functions](/reference/template-functions-about).
For more information about the syntax of the template functions for mapping configuration values, see [Config Context](/reference/template-functions-config-context) in the _Template Functions_ section.
## Map user-supplied values
Follow one of these procedures to map user inputs from the configuration screen, depending on if you use a Helm chart for your application:
* **Without Helm**: See [Map Values to Manifest Files](#map-values-to-manifest-files).
* **With Helm**: See [Map Values to a Helm Chart](#map-values-to-a-helm-chart).
### Map values to manifest files
To map user-supplied values from the configuration screen to manifest files in your application:
1. In the [Vendor Portal](https://vendor.replicated.com/apps), click **Releases**. Then, click **View YAML** next to the desired release.
1. Open the Config custom resource manifest file that you created in the [Add Fields to the Configuration Screen](admin-console-customize-config-screen#add-fields-to-the-configuration-screen) procedure. The Config custom resource manifest file has `kind: Config`.
1. In the Config manifest file, locate the name of the user-input field that you want to map.
**Example**:
```yaml
apiVersion: kots.io/v1beta1
kind: Config
metadata:
name: my-application
spec:
groups:
- name: smtp_settings
title: SMTP Settings
description: Configure SMTP Settings
items:
- name: smtp_host
title: SMTP Hostname
help_text: Set SMTP Hostname
type: text
```
In the example above, the field name to map is `smtp_host`.
1. In the same release in the Vendor Portal, open the manifest file where you want to map the value for the field that you selected.
1. In the manifest file, use the ConfigOption template function to map the user-supplied value in a key value pair. For example:
```yaml
hostname: '{{repl ConfigOption "smtp_host"}}'
```
For more information about the ConfigOption template function, see [Config Context](../reference/template-functions-config-context#configoption) in the _Template Functions_ section.
**Example**:
The following example shows mapping user-supplied TLS certificate and TLS private key files to the `tls.cert` and `tls.key` keys in a Secret custom resource manifest file.
For more information about working with TLS secrets, including a strategy for re-using the certificates uploaded for the Admin Console itself, see the [Configuring Cluster Ingress](packaging-ingress) example.
```yaml
apiVersion: v1
kind: Secret
metadata:
name: tls-secret
type: kubernetes.io/tls
data:
tls.crt: '{{repl ConfigOption "tls_certificate_file" }}'
tls.key: '{{repl ConfigOption "tls_private_key_file" }}'
```
1. Save and promote the release to a development environment to test your changes.
### Map values to a Helm chart
The `values.yaml` file in a Helm chart defines parameters that are specific to each environment in which the chart will be deployed. With Replicated KOTS, your users provide these values through the configuration screen in the Admin Console. You customize the configuration screen based on the required and optional configuration fields that you want to expose to your users.
To map the values that your users provide in the Admin Console configuration screen to your Helm chart `values.yaml` file, you create a HelmChart custom resource.
To map user inputs from the configuration screen to the `values.yaml` file:
1. In the [Vendor Portal](https://vendor.replicated.com/apps), click **Releases**. Then, click **View YAML** next to the desired release.
1. Open the Config custom resource manifest file that you created in the [Add Fields to the Configuration Screen](admin-console-customize-config-screen#add-fields-to-the-configuration-screen) procedure. The Config custom resource manifest file has `kind: Config`.
1. In the Config manifest file, locate the name of the user-input field that you want to map.
**Example**:
```yaml
apiVersion: kots.io/v1beta1
kind: Config
metadata:
name: my-application
spec:
groups:
- name: smtp_settings
title: SMTP Settings
description: Configure SMTP Settings
items:
- name: smtp_host
title: SMTP Hostname
help_text: Set SMTP Hostname
type: text
```
In the example above, the field name to map is `smtp_host`.
1. In the same release, create a HelmChart custom resource manifest file. A HelmChart custom resource manifest file has `kind: HelmChart`.
For more information about the HelmChart custom resource, see [HelmChart](../reference/custom-resource-helmchart) in the _Custom Resources_ section.
1. In the HelmChart manifest file, copy and paste the name of the property from your `values.yaml` file that corresponds to the field that you selected from the Config manifest file under `values`:
```yaml
values:
HELM_VALUE_KEY:
```
Replace `HELM_VALUE_KEY` with the property name from the `values.yaml` file.
1. Use the ConfigOption template function to set the property from the `values.yaml` file equal to the corresponding configuration screen field:
```yaml
values:
HELM_VALUE_KEY: '{{repl ConfigOption "CONFIG_SCREEN_FIELD_NAME" }}'
```
Replace `CONFIG_SCREEN_FIELD_NAME` with the name of the field that you created in the Config custom resource.
For more information about the KOTS ConfigOption template function, see [Config Context](../reference/template-functions-config-context#configoption) in the _Template Functions_ section.
**Example:**
```yaml
apiVersion: kots.io/v1beta1
kind: HelmChart
metadata:
name: samplechart
spec:
chart:
name: samplechart
chartVersion: 3.1.7
helmVersion: v3
useHelmInstall: true
values:
hostname: '{{repl ConfigOption "smtp_host" }}'
```
1. Save and promote the release to a development environment to test your changes.
---
# Use custom domains
This topic describes how to use the Replicated Vendor Portal to add and manage custom domains to alias Replicated endpoints, including the Replicated registry, the Replicated proxy registry, the Replicated app service, the Replicated Enterprise Portal, and the Replicated Download Portal.
For information about adding and managing custom domains with the Vendor API v3, see the [customHostnames](https://replicated-vendor-api.readme.io/reference/createcustomhostname) section in the Vendor API v3 documentation.
For more information about custom domains, see [About Custom Domains](custom-domains).
## Add a custom domain in the Vendor Portal {#add-domain}
To add and verify a custom domain:
1. In the [Vendor Portal](https://vendor.replicated.com), go to **Custom Domains**.
1. In the **Add custom domain** dropdown, select the target Replicated endpoint.
:::note
There is a known issue when using a custom domain for the Enterprise Portal if any of your customers use link transformers such as Microsoft Defender Safe Links. For more information, see [Known Issue](custom-domains#known-issue) in _About Custom Domains_.
:::
The **Configure a custom domain** wizard opens.
[View a larger version of this image](/images/custom-domains-download-configure.png)
1. For **Domain**, enter the custom domain. Click **Save & continue**.
1. For **Create CNAME**, copy the text string and use it to create a CNAME record in your DNS account. Click **Continue**.
1. For **Verify ownership**, ownership will be validated automatically using an HTTP token when possible.
If ownership cannot be validated automatically, copy the text string provided and use it to create a TXT record in your DNS account. Click **Validate & continue**. Your changes can take up to 24 hours to propagate.
1. For **TLS cert creation verification**, TLS verification will be performed automatically using an HTTP token when possible.
If TLS verification cannot be performed automatically, copy the text string provided and use it to create a TXT record in your DNS account. Click **Validate & continue**. Your changes can take up to 24 hours to propagate.
:::note
If you set up a [CAA record](https://letsencrypt.org/docs/caa/) for this hostname, you must include all Certificate Authorities (CAs) that Cloudflare partners with. The following CAA records are required to ensure proper certificate issuance and renewal:
```dns
@ IN CAA 0 issue "letsencrypt.org"
@ IN CAA 0 issue "pki.goog; cansignhttpexchanges=yes"
@ IN CAA 0 issue "ssl.com"
@ IN CAA 0 issue "amazon.com"
@ IN CAA 0 issue "cloudflare.com"
@ IN CAA 0 issue "google.com"
```
Failing to include any of these CAs might prevent certificate issuance or renewal, which can result in downtime for your customers. For additional security, you can add an IODEF record to receive notifications about certificate requests:
```dns
@ IN CAA 0 iodef "mailto:your-security-team@example.com"
```
:::
1. For **Use Domain**, to set the new domain as the default, click **Yes, set as default**. Otherwise, click **Not now**.
:::note
Replicated recommends that you do _not_ set a domain as the default until you are ready for it to be used by customers.
:::
After the verification checks for ownership and TLS certificate creation are complete, the Vendor Portal marks the domain as **Configured**.
1. (Optional) After a domain is marked as **Configured**, you can remove any TXT records that you created in your DNS account.
## Use custom domains
After you add one or more custom domains in the Vendor Portal, you can configure your application to use the domains.
### Configure Enterprise Portal domains {#enterprise-portal}
The New Enterprise Portal has its own domain settings. To add or manage a New Enterprise Portal custom domain, go to **Enterprise Portal > Domains**.
Teams that use only the New Enterprise Portal do not see Download Portal domains on the **Custom Domains** page. In mixed mode, use **Custom Domains** for Classic Enterprise Portal and Download Portal domains. Use **Enterprise Portal > Domains** for New Enterprise Portal domains.
### Configure Embedded Cluster to use custom domains {#ec}
You can configure Replicated Embedded Cluster to use your custom domains for the Replicated proxy registry and Replicated app service. For more information about Embedded Cluster, see [Embedded Cluster Overview](/embedded-cluster/v3/embedded-overview).
To configure Embedded Cluster to use your custom domains for the proxy registry and app service:
1. In the [Embedded Cluster Config](/embedded-cluster/v3/embedded-config) spec for your application, add `domains.proxyRegistryDomain` and `domains.replicatedAppDomain`. Set each field to your custom domain for the given service.
**Example:**
```yaml
apiVersion: embeddedcluster.replicated.com/v1beta1
kind: Config
spec:
domains:
# Your proxy registry custom domain
proxyRegistryDomain: proxy.yourcompany.com
# Your app service custom domain
replicatedAppDomain: updates.yourcompany.com
```
For more information, see [domains](/embedded-cluster/v3/embedded-config#domains) in _Embedded Cluster Config_.
1. Add the Embedded Cluster Config to a new release. Promote the release to a channel that your team uses for testing, and install with Embedded Cluster in a development environment to test your changes.
### Set a default domain
Setting a default domain is useful for ensuring that the same domain is used across channels for all your customers.
When you set a custom domain as the default, it is used by default for all new releases promoted to any channel, as long as the channel does not have a different domain assigned in its channel settings.
Only releases that are promoted to a channel _after_ you set a default domain use the new default domain. Any existing releases that were promoted before you set the default continue to use the same domain that they used previously.
:::note
In Embedded Cluster installations, the KOTS Admin Console will use the domains specified in the `domains.proxyRegistryDomain` and `domains.replicatedAppDomain` fields of the Embedded Cluster Config when making requests to the proxy registry and app service, regardless of the default domain or the domain assigned to the given release channel. For more information about using custom domains in Embedded Cluster installations, see [Configure Embedded Cluster to Use Custom Domains](#ec) above.
:::
To set a custom domain as the default:
1. In the Vendor Portal, go to **Custom Domains**.
1. Next to the target domain, click **Set as default**.
1. In the confirmation dialog that opens, click **Yes, set as default**.
### Assign a domain to a channel {#channel-domain}
You can assign a domain to an individual channel by editing the channel settings. When you specify a domain in the channel settings, new releases promoted to the channel use the selected domain even if there is a different domain set as the default on the **Custom Domains** page.
Assigning a domain to a release channel is useful when you need to override either the default Replicated domain or a default custom domain for a specific channel. For example:
* You need to use a different domain for releases promoted to your Beta and Stable channels.
* You need to test a domain in a development environment before you set the domain as the default for all channels.
:::note
In Embedded Cluster installations, the KOTS Admin Console will use the domains specified in the `domains.proxyRegistryDomain` and `domains.replicatedAppDomain` fields of the Embedded Cluster Config when making requests to the proxy registry and app service, regardless of the default domain or the domain assigned to the given release channel. For more information about using custom domains in Embedded Cluster installations, see [Configure Embedded Cluster to Use Custom Domains](#ec) above.
:::
To assign a custom domain to a channel:
1. In the Vendor Portal, go to **Channels** and click the settings icon for the target channel.
1. Under **Custom domains**, in the drop-down for the target Replicated endpoint, select the domain to use for the channel. For more information about channel settings, see [Channel Settings](releases-about#channel-settings) in _About Channels and Releases_.
[View a larger version of this image](/images/channel-settings.png)
## Reuse a custom domain for another application
If you have configured a custom domain for one application, you can reuse the custom domain for another application in the same team without going through the ownership and TLS certificate verification process again.
To reuse a custom domain for another application:
1. In the Vendor Portal, select the application from the dropdown list.
1. Click **Custom Domains**.
1. In the section for the target endpoint, click **Add your first custom domain** for your first domain, or click **Add new domain** for additional domains.
The **Configure a custom domain** wizard opens.
1. In the text box, enter the custom domain name that you want to reuse. Click **Save & continue**.
The last page of the wizard opens because the custom domain was verified previously.
1. Do one of the following:
- Click **Set as default**. In the confirmation dialog that opens, click **Yes, set as default**.
- Click **Not now**. You can come back later to set the domain as the default. The Vendor Portal shows shows that the domain has a Configured status because it was configured for a previous application, though it is not yet assigned as the default for this application.
## Remove a custom domain
You can remove a custom domain at any time, but you should plan the transition so that you do not break any existing installations or documentation.
Removing a custom domain for the Replicated registry, proxy registry, or Replicated app service will break existing installations that use the custom domain. Existing installations need to be upgraded to a version that does not use the custom domain before it can be removed safely.
If you remove a custom domain for the download portal, it is no longer accessible using the custom URL. You will need to point customers to an updated URL.
To remove a custom domain:
1. Log in to the [Vendor Portal](https://vendor.replicated.com) and click **Custom Domains**.
1. Verify that the domain is not set as the default nor in use on any channels. You can edit the domains in use on a channel in the channel settings. For more information, see [Channel Settings](releases-about#channel-settings) in _About Channels and Releases_.
:::important
When you remove a registry or Replicated app service custom domain, any installations that reference that custom domain will break. Ensure that the custom domain is no longer in use before you remove it from the Vendor Portal.
:::
1. Click **Remove** next to the unused domain in the list, and then click **Yes, remove domain**.
---
# About custom domains
This topic provides an overview and the limitations of using custom domains to alias the Replicated proxy registry, the Replicated app service, the Replicated Download Portal, and the Replicated registry.
For information about adding and managing custom domains, see [Use Custom Domains](custom-domains-using).
## Overview
You can use custom domains to alias Replicated endpoints by creating Canonical Name (CNAME) records for your domains.
Replicated domains are external to your domain and can require additional security reviews by your customer. Using custom domains as aliases can bring the domains inside an existing security review and reduce your exposure.
You can configure custom domains for the following services:
- **Proxy registry:** Images can be proxied from external private registries using the Replicated proxy registry. By default, the proxy registry uses the domain `proxy.replicated.com`. Replicated recommends using a CNAME such as `proxy.{your app name}.com`.
The image used by the [Replicated SDK](replicated-sdk-overview) Helm chart is automatically pulled through the Replicated proxy registry during deployment. This means that, when you add a custom domain for the proxy registry, the SDK image also uses that custom domain automatically. No additional configuration is required. For the default Replicated SDK image properties, see [values.yaml](https://github.com/replicatedhq/replicated-sdk/blob/main/chart/values.yaml#L52) in the replicated-sdk repository in GitHub.
:::note
If you use a custom domain for the proxy registry, you might see `/v2/token` authentication endpoints in logs or network traffic. These token requests are part of the standard Docker Registry v2 API and are expected behavior. For public images, these tokens are anonymous and do not contain sensitive information.
:::
- **Replicated app service:** Upstream application YAML and metadata, including a license ID, are pulled from the app service. By default, this service uses the domain `replicated.app`. Replicated recommends using a CNAME such as `updates.{your app name}.com`.
- **Enterprise Portal:** The Enterprise Portal is a web-based portal that provides end customers with a centralized location for managing their installation. By default, the Enterprise Portal uses the domain **`[DOMAIN].replicated.com`**. Replicated recommending using a CNAME such as `portal.{your app name}.com` or `enterprise.{your app name}.com`.
- **Download Portal:** The Download Portal can be used to share customer license files, air gap bundles, and so on. By default, the Download Portal uses the domain `get.replicated.com`. Replicated recommends using a CNAME such as `portal.{your app name}.com` or `enterprise.{your app name}.com`.
- **Replicated registry:** Images and Helm charts can be pulled from the Replicated registry. By default, the Replicated registry uses the domain `registry.replicated.com`. Replicated recommends using a CNAME such as `registry.{your app name}.com`.
## Limitations
Using custom domains has the following limitations:
- A single custom domain cannot be used for multiple endpoints. For example, a single domain can map to `registry.replicated.com` for any number of applications, but cannot map to both `registry.replicated.com` and `proxy.replicated.com`, even if the applications are different.
- Custom domains cannot be used to alias `api.replicated.com` (legacy customer-facing APIs) or kURL.
- Multiple custom domains can be configured, but only one custom domain can be the default for each Replicated endpoint. All configured custom domains work whether or not they are the default.
- Each custom domain can only be used by one team.
- For [Replicated Embedded Cluster](/embedded-cluster/v3/embedded-overview) installations, any Helm [`extensions`](/embedded-cluster/v3/embedded-config) that you add in the Embedded Cluster Config do not use custom domains. During deployment, Embedded Cluster pulls both the repo for the given chart and any images in the chart as written. Embedded Cluster does not rewrite image names to use custom domains.
## Known issue
If you use a custom domain for the Replicated [Enterprise Portal](/vendor/enterprise-portal-about) and any of your customers use link transformers such as Microsoft Defender Safe Links, then there is a known issue where legitimate URLs in emails generated by the Enterprise Portal can break due to rewrapping. To avoid this issue, request a "Do not rewrite the following URLs" exclusion policy for your custom Enterprise Portal domain.
---
# Configure custom metrics
This topic describes how to configure an application to send custom metrics to the Replicated Vendor Portal.
## Overview
In addition to the built-in insights displayed in the Vendor Portal by default (such as uptime and time to install), you can also configure custom metrics to measure instances of your application running customer environments. Custom metrics can be collected for application instances running in online or air gap environments.
Custom metrics can be used to generate insights on customer usage and adoption of new features, which can help your team to make more informed prioritization decisions. For example:
* Decreased or plateaued usage for a customer can indicate a potential churn risk
* Increased usage for a customer can indicate the opportunity to invest in growth, co-marketing, and upsell efforts
* Low feature usage and adoption overall can indicate the need to invest in usability, discoverability, documentation, education, or in-product onboarding
* High usage volume for a customer can indicate that the customer might need help in scaling their instance infrastructure to keep up with projected usage
## How the SDK sends custom metrics to the Vendor Portal
The Vendor Portal receives custom metrics from the Replicated SDK, which is installed in the cluster alongside the application.
The SDK exposes an in-cluster API where you can configure your application to PATCH and POST metric payloads. When an application sends data to the API, the SDK sends the data (including any custom and built-in metrics) to the Replicated app service. The app service is located at `replicated.app` or at your custom domain.
If any values in the metric payload are different from the current values for the instance, then a new event is generated and displayed in the Vendor Portal. This design reduces noise and helps you focus on actual changes in your customer deployments. For more information about how the Vendor Portal generates events, see [How the Vendor Portal Generates Events and Insights](/vendor/instance-insights-event-data#about-events) in _About Instance and Event Data_.
The following diagram demonstrates how a custom `activeUsers` metric is sent to the in-cluster API and ultimately displayed in the Vendor Portal, as described above:
[View a larger version of this image](/images/custom-metrics-flow.png)
## Requirements
* To support the collection of custom metrics in online and air gap environments, the Replicated SDK version 1.0.0-beta.12 or later must be running in the cluster alongside the application instance. If you have any customers running earlier versions of the SDK, Replicated recommends that you add logic to your application to gracefully handle a 404 from the in-cluster APIs. For more information about the Replicated SDK, see [About the Replicated SDK](/vendor/replicated-sdk-overview).
* The `PATCH` and `DELETE` methods described on this page require the Replicated SDK version 1.0.0-beta.23 or later.
## Limitations
* The label that is used to display metrics in the Vendor Portal cannot be customized. Metrics are sent to the Vendor Portal with the same name used in the `POST` or `PATCH` payload. The Vendor Portal automatically converts camel case or snake case to title case: for example, `activeUsers` or `active_users` is displayed as Active Users.
* The SDK API accepts only JSON scalar values for metrics. Any requests containing nested objects or arrays are rejected.
## Define custom metrics in JSON payload
You can define the custom metrics for your application as a set of key value pairs in a JSON metric payload. The payload must be valid JSON with proper content type headers.
**Example:**
```json
{
"data": {
"active_users": 150, // Number
"cpu_usage_percent": 75.5, // Number
"sso_enabled": true, // Boolean
"deployment_region": "us-east-1", // String
}
}
```
### Supported data types
Custom metric names (keys) must be strings.
Custom metric values support these JSON types:
- Numbers (integers or decimals)
- Strings
- Booleans
- Null
The JSON payload must contain only scalar values. Nested objects or arrays are not supported.
### Best practices for naming custom metrics
Metrics are displayed in the Vendor Portal with the same name that is used in the JSON payload. The Vendor Portal automatically converts camel case or snake case to title case: for example, `activeUsers` or `active_users` is displayed as Active Users.
To make it easier for team members to understand the instance reporting data for your application, Replicated recommends that you follow these best practices when naming custom metrics:
* Use descriptive names like `active_users`. Avoid abbreviations like `au`, vague names like `user_metric`, or overly verbose names like `current_active_users`.
* Use camel case or snake case. Don't use hyphenated names like `active-users`.
* Use camel or snake case consistently across all of your custom metrics.
## Send custom metrics
You can configure your application to `PATCH` or `POST` a JSON metric payload to the SDK in-cluster API. For information about when to use `PATCH` or `POST`, see [PATCH vs POST](#patch-vs-post) on this page.
The SDK API custom metrics endpoint is available at `http://replicated:3000/api/v1/app/custom-metrics`.
### Nodejs example
The following example shows a NodeJS application that sends metrics on a weekly interval to the in-cluster API exposed by the SDK:
```javascript
async function sendMetrics(db) {
const projectsQuery = "SELECT COUNT(*) as num_projects from projects";
const numProjects = (await db.getConnection().queryOne(projectsQuery)).num_projects;
const usersQuery =
"SELECT COUNT(*) as active_users from users where DATEDIFF('day', last_active, CURRENT_TIMESTAMP) < 7";
const activeUsers = (await db.getConnection().queryOne(usersQuery)).active_users;
const metrics = { data: { numProjects, activeUsers }};
const res = await fetch('https://replicated:3000/api/v1/app/custom-metrics', {
method: 'POST',
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(metrics),
});
if (res.status !== 200) {
throw new Error(`Failed to send metrics: ${res.statusText}`);
}
}
async function startMetricsLoop(db) {
const ONE_DAY_IN_MS = 1000 * 60 * 60 * 24
// send metrics once on startup
await sendMetrics(db)
.catch((e) => { console.log("error sending metrics: ", e) });
// schedule weekly metrics payload
setInterval( () => {
sendMetrics(db, licenseId)
.catch((e) => { console.log("error sending metrics: ", e) });
}, ONE_DAY_IN_MS);
}
startMetricsLoop(getDatabase());
```
### Patch vs post
Both the `PATCH` and `POST` methods record metrics with a timestamp, but they differ in how they handle your current metric state:
* **`PATCH`:** Updates only the fields included in the JSON payload. Any other existing fields are unchanged. Use `PATCH` unless you need to explicitly remove metrics from the instance summary.
* **`POST`:** Replaces the current metric state. Any existing metrics that are not included in the JSON payload are removed from the instance summary. Use `POST` only when sending your complete metric set each time.
For example, if a component of your application initially sends the following with the `POST` method:
```json
{
"numProjects": 5,
"activeUsers": 10,
}
```
Then, the component later sends the following with the `PATCH` method:
```json
{
"usingCustomReports": false
}
```
Then the instance detail will show `Num Projects: 5`, `Active Users: 10`, `Using Custom Reports: false`, which represents the merged and upserted payload:
```json
{
"numProjects": 5,
"activeUsers": 10,
"usingCustomReports": false
}
```
However, if you use `POST` for the second call instead of `PATCH`, then the instance detail will show only `Active Users: 10` and `Using Custom Reports: false`:
```json
{
"activeUsers": 10,
"usingCustomReports": false
}
```
In this case, the previously-sent `numProjects` value is removed from the instance summary (though it remains accessible in the instance events history).
### How often to send custom metrics
Replicated recommends that you add logic to your application to send metrics at regular intervals, such as daily or weekly.
Avoid sending metrics too frequently as it creates unnecessary noise. Custom metrics are best for periodic product statistics reporting rather than real-time monitoring.
For an example of application logic that sends custom metrics on a weekly interval, see [NodeJS Example](#nodejs-example) on this page.
## Remove a custom metric
To remove an existing custom metric, use `DELETE` with the custom metric name. For example:
```bash
DELETE http://replicated:3000/api/v1/app/custom-metrics/num_projects
```
## View custom metrics
You can view the custom metrics that you configure for each active instance of your application on the **Instance Details** page in the Vendor Portal.
The following shows an example of an instance with custom metrics:
[View a larger version of this image](/images/instance-custom-metrics.png)
As shown in the image above, the **Custom Metrics** section of the **Instance Details** page includes the following information:
* The timestamp when the custom metric data was last updated.
* Each custom metric that you configured, along with the most recent value for the metric.
* A time-series graph depicting the historical data trends for the selected metric.
Custom metrics are also included in the **Instance activity** stream of the **Instance Details** page. For more information, see [Instance Activity](/vendor/instance-insights-details#instance-activity) in _Instance Details_.
## Export custom metrics
You can use the Vendor API v3 `/app/{app_id}/events` endpoint to programmatically access historical timeseries data containing instance level events, including any custom metrics that you have defined. For more information about the endpoint, see [Export Customer and Instance Data](/vendor/instance-data-export).
## Troubleshoot custom metrics
### Custom metrics not showing up in the Vendor Portal
#### Symptom
After your application sends a custom metric payload to the SDK API, one or more custom metrics are not displayed in the instance details in the Vendor Portal.
#### Cause
There are several possible reasons why a custom metric might not be showing up in the Vendor Portal, such as using an unsupported version of the SDK, invalid JSON, using POST rather than PATCH, or network connectivity issues.
#### Solution
To troubleshoot this issue:
- Ensure that the application instance is using the Replicated SDK version 1.0.0-beta.12 or later. If your application is using the `PATCH` and `DELETE` methods, version 1.0.0-beta.23 or later of the SDK is required.
- Verify that your payload only contains scalar values (no nested objects or arrays), and is valid JSON with proper content type headers
- Test network connectivity by confirming that the application can reach `http://replicated:3000`
- Check that your application is using the intended method (PATCH or POST). If a metric payload is sent using the POST method, any existing metrics that are not included in the payload are removed from the instance summary. For more information, see [PATCH vs POST](#patch-vs-post).
### Duplicate events for unchanged values
#### Symptom
Instance reporting in the Vendor Portal displays duplicate events for one of your custom metrics, even though the metric's value was unchanged.
#### Cause
Your application logic might be computing values differently between calls.
#### Solution
To troubleshoot this issue:
- Review your metric collection logic to ensure consistent value calculation
- Check for floating-point precision issues with numeric values
- Verify that boolean values are consistently true or false and are not truthy or falsy conversions
---
# Adoption report
This topic describes the insights in the **Adoption** section on the Replicated Vendor Portal **Dashboard** page.
## About adoption rate
The **Adoption** section on the **Dashboard** provides insights about the rate at which your customers upgrade their instances and adopt the latest versions of your application. As an application vendor, you can use these adoption rate metrics to learn if your customers are completing upgrades regularly, which is a key indicator of the discoverability and ease of application upgrades.
The Vendor Portal generates adoption rate data from all your customer's application instances that have checked-in during the selected time period. For more information about instance check-ins, see [How the Vendor Portal Collects Instance Data](instance-insights-event-data#about-reporting) in _About Instance and Event Data_.
The following screenshot shows an example of the **Adoption** section on the **Dashboard**:

[View a larger version of this image](/images/customer_adoption_rates.png)
As shown in the screenshot above, the **Adoption** report includes a graph and key adoption rate metrics. For more information about how to interpret this data, see [Adoption Graph](#graph) and [Adoption Metrics](#metrics) below.
The **Adoption** report also displays the number of customers assigned to the selected channel and a link to the report that you can share with other members of your team.
You can filter the graph and metrics in the **Adoption** report by:
* License type (Paid, Trial, Dev, or Community)
* Time period (the previous month, three months, six months, or twelve months)
* Release channel to which instance licenses are assigned, such as Stable or Beta
## Adoption graph {#graph}
The **Adoption** report includes a graph that shows the percent of active instances that are running different versions of your application within the selected time period.
The following shows an example of an adoption rate graph with three months of data:

[View a larger version of this image](/images/adoption_rate_graph.png)
As shown in the image above, the graph plots the number of active instances in each week in the selected time period, grouped by the version each instance is running. The key to the left of the graph shows the unique color that is assigned to each application version. You can use this color-coding to see at a glance the percent of active instances that were running different versions of your application across the selected time period.
Newer versions will enter at the bottom of the area chart, with older versions shown higher up.
You can also hover over a color-coded section in the graph to view the number and percentage of active instances that were running the version in a given period.
If there are no active instances of your application, then the adoption rate graph displays a "No Instances" message.
## Adoption metrics {#metrics}
The **Adoption** section includes metrics that show how frequently your customers discover and complete upgrades to new versions of your application. It is important that your users adopt new versions of your application so that they have access to the latest features and bug fixes. Additionally, when most of your users are on the latest versions, you can also reduce the number of versions for which you provide support and maintain documentation.
The following shows an example of the metrics in the **Adoption** section:

[View a larger version of this image](/images/adoption_rate_metrics.png)
As shown in the image above, the **Adoption** section displays the following metrics:
* Instances on last three versions
* Unique versions
* Median relative age
* Upgrades completed
Based on the time period selected, each metric includes an arrow that shows the change in value compared to the previous period. For example, if the median relative age today is 68 days, the selected time period is three months, and three months ago the median relative age was 55 days, then the metric would show an upward-facing arrow with an increase of 13 days.
The following table describes each metric in the **Adoption** section, including the formula used to calculate its value and the recommended trend for the metric over time:
| Metric | Description | Target Trend |
|---|---|---|
| Instances on last three versions |
Percent of active instances that are running one the latest three versions of your application. Formula: |
Increase towards 100% |
| Unique versions |
Number of unique versions of your application running in active instances. Formula: |
Decrease towards less than or equal to three |
| Median relative age |
The relative age of a single instance is the number of days between the date that the instance's version was promoted to the channel and the date when the latest available application version was promoted to the channel. Median relative age is the median value across all active instances for the selected time period and channel. Formula: |
Depends on release cadence. For vendors who ship every four to eight weeks, decrease the median relative age towards 60 days or fewer. |
| Upgrades completed |
Total number of completed upgrades across active instances for the selected time period and channel. An upgrade is a single version change for an instance. An upgrade is considered complete when the instance deploys the new application version. The instance does not need to become available (as indicated by reaching a Ready state) after deploying the new version for the upgrade to be counted as complete. Formula: |
Increase compared to any previous period, unless you reduce your total number of live instances. |
[View a larger version of this image](/images/customer-reporting-install-attempts-expanded.png)
The **Install Attempts** section includes the following details about each installation attempt:
* The installation status (succeeded, stalled, or failed)
* The date and time when the installation attempt was started
* The email address of the user that initiated the installation attempt
* Installation environment details:
* **OS** or **K8s**: The operating system of the VM or bare metal server. Or, the distribution of Kubernetes running in the installation environment.
* **Mode**: If the installation is online (internet-connected) or air gap (offline).
* **Registry**: If the image registry used is online (accessed over the internet) or offline (a local registry is used). For air gap installations, the registry is always offline. Users can also optionally use a local image registry in online installations.
* Installation progress details, including when the installation was started and completed as well as other progress indicators that are specific to the installation type. For example:
* For installations with Helm, the Enterprise Portal reports when your image registry was accessed and when application images were pulled, as shown below:

[View a larger version of this image](/images/customer-reporting-install-attempts-helm.png)
* For installations with Replicated Embedded Cluster on VMs or bare metal servers, the Enterprise Portal reports when the installation assets were downloaded, as shown below:

[View a larger version of this image](/images/customer-reporting-install-attempts-vm.png)
---
# Data availability and continuity
Replicated uses redundancy and a cloud-native architecture in support of availability and continuity of vendor data.
## Data storage architecture
To ensure availability and continuity of necessary vendor data, Replicated uses a cloud-native architecture. This cloud-native architecture includes clustering and network redundancies to eliminate single point of failure.
Replicated stores vendor data in various Amazon Web Services (AWS) S3 buckets and multiple databases. Data stored in the AWS S3 buckets includes registry images and air gap build data.
The following diagram shows the flow of air gap build data and registry images from vendors to enterprise customers.

[View a larger version of this image](/images/data-storage.png)
As shown in the diagram above, vendors push application images to an image registry. Replicated stores this registry image data in AWS S3 buckets, which are logically isolated by vendor portal Team. Instances of the vendor's application that are installed by enterprise customers pull data from the image registry.
For more information about how Replicated secures images pushed to the Replicated registry, see [Replicated Registry Security](packaging-private-registry-security).
The diagram also shows how enterprise customers access air gap build data from the customer download portal. Replicated stores this air gap build data in AWS S3 buckets.
## Data recovery
Our service provider's platform automatically restores customer applications and databases in the case of an outage. The provider's platform is designed to dynamically deploy applications within its cloud, monitor for failures, and recover failed platform components including customer applications and databases.
For more information, see the [Replicated Trust Center](https://trust.replicated.com/).
## Data availability
Replicated availability is continuously monitored. For availability reports, see https://status.replicated.com.
---
# About managing stateful services
This topic provides recommendations for managing stateful services that you install into existing clusters.
:::note
Replicated KOTS is available only for existing customers. For supporting installations into customer managed clusters, we recommend Helm. For more information, see [About Helm Installations with Replicated](/vendor/helm-install-overview).
KOTS is a Generally Available (GA) product for existing customers. For more information about the Replicated product lifecycle phases, see [Support Lifecycle Policy](/vendor/policies-support-lifecycle).
:::
## Preflight checks for stateful services
If you expect to also install stateful services into existing clusters, you will likely want to expose [preflight analyzers that check for the existence of a storage class](https://troubleshoot.sh/reference/analyzers/storage-class/).
If you are allowing end users to provide connection details for external databases, you can often use a troubleshoot.sh built-in [collector](https://troubleshoot.sh/docs/collect/) and [analyzer](https://troubleshoot.sh/docs/analyze/) to validate the connection details for [Postgres](https://troubleshoot.sh/docs/analyze/postgresql/), [Redis](https://troubleshoot.sh/docs/collect/redis/), and many other common datastores. These can be included in both `Preflight` and `SupportBundle` specifications.
## About adding persistent datastores
You can integrate persistent stores, such as databases, queues, and caches. There are options to give an end user, such as embedding an instance alongside the application or connecting an application to an external instance that they will manage.
For an example of integrating persistent datastores, see [Example: Adding Database Configuration Options](tutorial-adding-db-config).
---
# About the Enterprise Portal
This topic provides an overview of the Replicated Enterprise Portal.
:::note
Looking for the new Enterprise Portal? See [About the Enterprise Portal](/vendor/enterprise-portal-v2-about) in the Enterprise Portal (New) section.
:::
## Overview
The Enterprise Portal is a customizable, web-based portal for customers that install using either Replicated Embedded Cluster or the Helm CLI.
From the Enterprise Portal, your customers can:
* View application install and update instructions for Embedded Cluster and Helm CLI installations
* Manage their team members and service accounts
* Upload support bundles
* View insights about their active and inactive instances
* And more
The following shows an example of the Enterprise Portal dashboard:

[View a larger version of this image](/images/enterprise-portal-dashboard.png)
Your customers can access the Enterprise Portal outside their application installation environment at a custom domain that you specify, making it easier for teams to manage instances and get support.
The following diagram shows how customers can use the Enterprise Portal to access release assets and installation instructions, as well as upload support bundles:

[View a larger version of this image](/images/enterprise-portal-overview.png)
As shown in the diagram above, your licensed customers can access the installation and update instructions for one or more application releases by logging in to the Enterprise Portal. The Enterprise Portal tracks the customer's installation attempts and progress, and shares those insights back to the Vendor Portal. After installing, customers can also upload support bundles in the Enterprise Portal. Support bundles uploaded to the Enterprise Portal are automatically made available to you in the Vendor Portal.
You can enable and disable access to the Enterprise Portal for all customers, or on a per-customer basis. For more information about how to enable access, see [Manage Customer Access](/vendor/enterprise-portal-invite#manage-ep-access).
For information about using the Enterprise Portal, see [Access and Use the Enterprise Portal](enterprise-portal-use).
## Limitations
* Installation and upgrade instructions are available only for Embedded Cluster and Helm CLI installations. The Enterprise Portal does not provide instructions for installing and upgrading with KOTS in existing clusters or with kURL.
* Air gap instance records do not appear in the Enterprise Portal until the end customer creates an air gap instance record by either uploading a support bundle for that instance or manually entering instance information. For more information, see [View Active and Inactive Instances](/vendor/enterprise-portal-use#view-active-and-inactive-instances) in _Access and Use the Enterprise Portal_.
* The Enterprise Portal limits support bundle uploads to 500 MB. For larger bundles, use the [Replicated SDK API](/reference/replicated-sdk-apis#post-supportbundle) upload endpoint, which has no size restriction.
* There is a known issue when using a custom domain for the Enterprise Portal if any of your customers use link transformers such as Microsoft Defender Safe Links. For more information, see [Known Issue](custom-domains#known-issue) in _About Custom Domains_.
## Comparison to the Download Portal
The Enterprise Portal is the next generation version of the Replicated Download Portal. Compared to the Download Portal, the Enterprise Portal not only provides access to installation assets and instructions, but also allows users to track available updates, manage their team and service accounts, view the status of their instances, view license details, and more. These features are designed to make it easier for your customers to manage their instances of your application from a centralized location outside of the installation environment.
For more information about enabling Enterprise Portal access for your customers that install using either Embedded Cluster or the Helm CLI, see [Manage Customer Access to the Enterprise Portal](enterprise-portal-invite).
:::note
The Entprise Portal supports Embedded Cluster and Helm CLI installation methods only. Customers that use KOTS in an existing cluster or kURL can continue to use the Download Portal.
:::
For more information about the Download Portal, see [Access a Customer's Download Portal](/vendor/releases-share-download-portal).
## About customizing the Enterprise Portal
You can configure the Enterprise Portal to use a custom domain, add links and contact information, customize the look and feel of the Enterprise Portal, edit the content of invitation and notification emails, and more. Customizing the Enterprise Portal helps ensure that your customers have a consistent branding experience and can access application- and vendor-specific information.
For more information about customizing the Enterprise Portal, see [Customize the Enterprise Portal](enterprise-portal-configure).
For information about how to set a custom domain for the Enterprise Portal, see [Use Custom Domains](/vendor/custom-domains-using).
## About instance reporting with the Enterprise Portal
This section describes the instance reporting functionality of the Enterprise Portal.
### Active and inactive instances
The Enterprise Portal provides insights to end users about their active and inactive instances, including the application version installed, the instance status, computed metrics like the first and most recent times the instance sent data to the Vendor Portal, and more. For more information about the instance insights available in the Enterprise Portal, see [View Active and Inactive Instances](/vendor/enterprise-portal-use#view-active-and-inactive-instances) in _Access and Use the Enterprise Portal_.

[View a larger version of this image](/images/enterprise-portal-instance-status-details.png)
### Customer reporting
The Enterprise Portal sends insights back to the Vendor Portal, which are surfaced on the **Customer Reporting** page. For more information, see [Enterprise Portal](/vendor/customer-reporting#enterprise-portal) in _Customer Reporting_.
These insights include details about the customer's install attempts. The Enterprise Portal tracks and reports on install attempts by creating unique, _just-in-time_ service accounts. These service accounts allow the Enterprise Portal to send data back to the Vendor Portal when the user starts and completes the installation or takes other actions that are specific to the installation type. The service accounts also provide realtime feedback to the user on their installation progress using checkboxes and status indicators, and allow users to pause and return to an installation attempt. For more information, see [Install Attempts](/vendor/customer-reporting#install-attempts-beta) in _Customer Reporting_.
The following shows an example of the **Install Attempts** section:
[View a larger version of this image](/images/customer-reporting-install-attempts-expanded.png)
---
# View a customer's Enterprise Portal
This topic describes how you can log in to the Enterprise Portal for a customer from the Vendor Portal. This is useful when testing your application installation and upgrade instructions, previewing customizations that you made to the Enterprise Portal, or managing Enterprise Portal users on behalf of one of your customers.
:::note
Looking for the new Enterprise Portal? See [View a customer's Enterprise Portal](/vendor/enterprise-portal-v2-access) in the Enterprise Portal (New) section.
:::
For information about how end users can sign up for an account and log in to the Enterprise Portal, see [Log In To and Use the Enterprise Portal](enterprise-portal-use).
## Log in using a one-time link
You can access the Enterprise Portal for a customer using a one-time login. This is useful for quickly accessing the Enteprise Portal, or if you must not create an account in the customer's Enterprise Portal.
To access the Enterprise Portal for a customer with a one-time login:
1. In the Vendor Portal, go to **Customers > [Customer Name] > Enterprise Portal Access**.
1. In the **Login to portal** section, click **Login to portal**. This generates a one-time login and opens the Enterprise Portal for the customer.

[View a larger version of this image](/images/enterprise-portal-one-time-login.png)
## Log in with an account
:::note
If your email address is not yet added to the customer's Enterprise Portal team, send an invitation before attempting to log in. For information about how to add users to a customer's Enterprise Portal from the Vendor Portal, see [Invite Users](enterprise-portal-invite#invite-users) in _Manage Customer Access to the Enterprise Portal_.
:::
To access the Enterprise Portal for a customer by logging in with an account:
1. In the Vendor Portal, do one of the following to get the unique Enterprise Portal link for the customer:
* Go to **Customers > [Customer Name] > Enterprise Portal Access**. Click **View customer's portal link**.

[View a larger version of this image](/images/customer-enterprise-portal-access-toggle.png)
* Go to **Customers > [Customer Name] > Reporting** and click **View** in the **Enterprise Portal** section.

[View a larger version of this image](/images/customer-reporting-enterprise-portal.png)
1. In the dialog, enter the email address for the existing Enterprise Portal user and click **Continue with email**. The Vendor Portal generates a verification code and sends it to the email address.
---
# Customize the Enterprise Portal
This topic describes how to customize the Enterprise Portal, including using a custom domain, changing the branding, editing the content of invitation and notification emails, and adding custom documentation.
:::note
Looking for the new Enterprise Portal? The new portal uses a GitHub content repo and `theme.yaml` for customization. See [Customize Portal Content](/vendor/enterprise-portal-v2-content) and [Customize Portal Branding](/vendor/enterprise-portal-v2-branding) in the Enterprise Portal (New) section.
:::
## Manage Enterprise Portal settings
You can edit the settings for the Enterprise Portal to use a custom domain, provide custom links and contact information, customize the look and feel of the Enterprise Portal, and more.
To manage Enterprise Portal settings:
1. In the Vendor Portal, go to **Enterprise Portal > Portal Settings**.

[View a larger version of this image](/images/enterprise-portal-settings.png)
1. Edit the settings as desired:
| Field | Description |
|---|---|
| URL | The URL where customers can access the Enterprise Portal. You can change the URL to use a custom domain. For information, see [Use Custom Domains](custom-domains-using). |
| Title | The title of the Enterprise Portal. The title is displayed at the top of each page in the Enterprise Portal and is also used in email notifications. |
| Page overview | An overview of the Enterprise Portal. |
| Support portal link | The URL for the portal that your customers can use to get support. This link is provided on the Enterprise Portal **Support** page. |
| Contact email | The email address that customers can use to contact you. This email address is provided on the Enterprise Portal **Support** page. |
| Logo | Upload a custom PNG logo for the Enterprise Portal. The minimum size for the logo is 160px by 160px. |
| Favicon | Upload a custom favicon for the Enterprise Portal. The favicon is displayed in the browser tab. |
| Background | Select or customize the background for the Enterprise Portal. |
| Colors | Set the primary and secondary colors for the Enterprise Portal. |
| Variable | Description | Example |
|---|---|---|
{`{app.name}`} |
Application name | `My Application` |
{`{app.slug}`} |
Application slug (identifier) | `my-app` |
{`{channel.channelName}`} |
Channel name | `Stable` |
{`{channel.channelSlug}`} |
Channel slug | `stable` |
{`{release.versionLabel}`} |
Release version number | `1.2.3` |
{`{release.releaseSequence}`} |
Release sequence number | `42` |
{`{release.releaseNotes}`} |
Release notes in markdown | ` |
{`{release.isRequired}`} |
Boolean: is this a required release | Add a ConditionalRender when={`{release.isRequired}`} to generate a special message |
{`{installOptions.isAirgap}`} |
Boolean: air gap installation | Add a ConditionalRender when={`{!installOptions.isAirgap}`} to add an extra Pull Images step |
{`{installOptions.installType}`} |
Installation type (helm, linux, embedded) | Add a ConditionalRender when={`{installOptions.installType === 'helm'}`} to generate different cluster preparation instructions |
{`{installOptions.adminConsoleUrl}`} |
Admin Console URL (user input, dynamic) | `https://admin.example.com` |
{`{installOptions.proxyUrl}`} |
HTTP/HTTPS proxy URL (user input, dynamic) | `https://proxy.example.com:8080` |
{`{installOptions.privateRegistryUrl}`} |
Private registry hostname (user input, dynamic) | `registry.example.com:5000` |
{`{branding?.title}`} |
Enterprise Portal title (optional) | `MyApp Enterprise Portal` |
{`{branding?.logo}`} |
Custom logo URL (optional) | `www.mycompany.com/logo` |
{`{branding?.primaryColor}`} |
Primary brand color (optional) | `#4a53b0` |
{`{branding?.secondaryColor}`} |
Primary brand color (optional) | `#0066cc` |
{`{branding?.supportPortalLink}`} |
Support portal URL (optional) | `https://support.example.com` |
{`{installation.licenseId}`} |
Unique Customer license ID | `2cHXb1RCttzpR0xvnNWyaZCgDBP` |
{`{installation.serviceAccountId}`} |
Service account identifier | `2cHXb1RCttzpR0xvnNWyaZCgDBP` |
{`{installation.customerEmail}`} |
Email address associated with the customer installation. Used for registry authentication as the username in Helm CLI installation instructions. | `customer@example.com` |
{`{installation.serviceAccountToken}`} |
Authentication token for the service account. Used for registry authentication as the password in Helm CLI installation instructions. | `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...` |
{`{images.raw}`} |
Array of image names without registry (Helm only) | `["nginx:1.19", "postgres:13"]` |
{`{images.full}`} |
Array of complete image references (Helm only) | `["registry.replicated.com/..."]` |
| Name | Description | Props |
|---|---|---|
| ` |
Display callout boxes with different styles. | `icon` (boolean, optional): Show or hide the icon in the callout. |
| ` |
General purpose alert with customizable type |
|
| ` |
Display inline code. To use template variables inside CodeBlock, wrap them in template literals using curly braces: `{`...`}`. For example, ``` Limitation: Dynamic user input variables (like `installOptions.privateRegistryUrl`, `installOptions.proxyUrl`, `installOptions.adminConsoleUrl`) are not supported in code components. Use placeholders like ` |
None |
| ` |
Display multi-line code blocks with syntax highlighting. To use template variables inside CodeBlock, wrap them in template literals using curly braces: `{`...`}`. For examples of this, see [Example](#example). Limitation: Dynamic user input variables (like `installOptions.privateRegistryUrl`, `installOptions.proxyUrl`, `installOptions.adminConsoleUrl`) are not supported in code components. Use placeholders like ` |
|
| ` |
Display shell commands with copy functionality. To use template variables inside CommandBlock, wrap them in template literals using curly braces: `{`...`}`. For examples of this, see [Example](#example). Limitation: Dynamic user input variables (like `installOptions.privateRegistryUrl`, `installOptions.proxyUrl`, `installOptions.adminConsoleUrl`) are not supported in code components. Use placeholders like ` |
|
| Name | Description | Props |
|---|---|---|
| ` |
Create tabbed content sections | `defaultActiveTab` (number, optional): Index of initially active tab |
| ` |
Individual tab within a Tabs container | `title` (string, required): Tab label text |
| ` |
Create collapsible content sections | `title` (string, required), `defaultOpen` (boolean, optional) |
| ` |
Show or hide content based on conditions | `when` (string, required): JavaScript expression to evaluate |
| Name | Description | Props |
|---|---|---|
| ` |
Numbered installation step |
|
| ` |
Display prerequisites section | `title` (string, optional): Custom title for the section |
| ` |
Display troubleshooting section | `title` (string, optional): Custom title for the section |
| Name | Description | Props |
|---|---|---|
| ` |
Collect proxy URL from user |
|
| ` |
Collect registry credentials |
|
| ` |
Collect Admin Console URL |
|
| Name | Description | Props |
|---|---|---|
| ` |
Link to support resources |
|
[View a larger version of this image](/images/self-serve-signup-screen.png)
To get the sign-up URL for your application:
1. In the Vendor Portal, go to **Enterprise Portal > Self Serve Signup**.
1. Under **Enable self-service sign-ups**, copy the **Sign-Up URL**.
## View pending trials {#pending-user}
When users request access to your application through a self-service sign-up, they are added to a list of **Pending Trials**. After the user confirms their account through the automated confirmation email, an active customer record is created for the user on the **Customers** page.
To view pending trials:
1. In the Vendor Portal, go to **Enterprise Portal > Self Serve Signup**.
1. Under **Pending Trials**, review details about any pending self-service sign-ups, including the user's email address, company, sign-up date and time, and more.

[View a larger version of this image](/images/pending-trial-user.png)
---
# Log in to and use the Enterprise Portal
This topic describes how to log in to the Replicated Enterprise Portal as a user, and how to use the features in the Enterprise Portal.
:::note
Looking for the new Enterprise Portal? See [Log in to and use the Enterprise Portal](/vendor/enterprise-portal-v2-use) in the Enterprise Portal (New) section.
:::
## Log in to the Enterprise Portal
:::note
If SAML authentication has been enabled and configured for the Enterprise Portal it will be the preferred login method and attempted automatically. See [Configure SAML Authentication (Alpha)](#saml) below.
:::
This section describes how end customers can log in to their Enterprise Portal. Vendors can also log in to the Enterprise Portal for a customer from the Vendor Portal. For more information, see [View a Customer's Enterprise Portal](enterprise-portal-access).
### Log in from the invitation email
Users can log in to the Enterprise Portal after they are invited to join a team. See [Invite or Delete Users](#invite-or-delete-users) below.
* Go to your email account and open the automated invitation email. Click **Activate your account** to log in.
[View a larger version of this image](/images/enterprise-portal-invitation-email.png)
### Sign up for a self-service account
If self-service sign-ups are enabled for the application, users can create an account in the Enterprise Portal without being invited. The primary use case for self-service account creation is to sign up for a trial or community version of the software.
:::note
For information about how to enable self-service sign-ups from the Vendor Portal, see [Enable Self-Service Sign-Ups](/vendor/enterprise-portal-self-serve-signup).
:::
To sign up for a self-service account and log in to the Enteprise Portal:
1. Go to the sign-up page URL.
:::note
For information about how to find the unique sign-up URL in the Vendor Portal, see [Share Your Sign-Up URL](/vendor/enterprise-portal-self-serve-signup#share-trial-url) in _Enable Self-Service Sign-Ups_.
:::
1. Enter your company name and email address, agree to the terms and conditions, and click **Create account**.
The following shows an example of a self-service sign-up page for an application:
[View a larger version of this image](/images/self-serve-signup-screen.png)
1. Go to your email account and open the automated account creation email. Follow the link provided in the email to log in.
### About SAML logins (Alpha) {#about-saml}
:::note
SAML Authentication to the Enterprise Portal is Alpha and subject to change. To access this feature, a feature flag must be enabled for your team. For more information, reach out to your Replicated account representative.
:::
When SAML authentication is enabled and configured for your Enterprise Portal team, you can log in with your single sign-on (SSO) credentials either through your SAML Identity Provider (IdP) or the Enterprise Portal. For more information about how to configure SAML, see [Configure SAML Authentication (Alpha)](#saml) below.
#### Just-in-time user provisioning
The first time that you attempt to log in with SAML using your SSO credentials, if you do not already have an Enterprise Portal account, then your account is automatically created using just-in-time (JIT) user provisioning. JIT is handled differently depending on if you attempt to log in through your IdP or the Enterprise Portal:
* IdP-initiated SAML login attempts always allow for JIT user provisioning
* Enterprise Portal-initiated SAML login attempts allow for JIT user provisioning if your email address has already been invited to the team. See [Invite or Delete Users](#invite-or-delete-users) below.
## Access with multiple teams
If your email address has been invited to more than one customer team, you can switch between teams in the Enterprise Portal. To switch teams, click your name in the top right of the page and select a different team from the list. Each team has its own license, pull tokens, and portal content based on its assigned channel.
All users invited to the same customer team share access to the same pull tokens, license credentials, and portal content.
## View install and update instructions
This section describes how to view install and update instructions in the Enterprise Portal.
The install and update instructions available in the Enterprise Portal are automatically generated based on the install types and options enabled in the customer's license. For more information about managing the installation types and options, see [Manage Install Types for a License](/vendor/licenses-install-types).
### View install instructions
To view install instructions in the Enterprise Portal:
1. Log in to the Enterprise Portal and go to **Install**.
1. On the panel on the left, if there are multiple installation types available for the customer's license, select the installation type to use (Helm or Embedded Cluster).
The installation options displayed in the Enterprise Portal are based on the customer's license. For more information, see [Manage Install Types for a License](/vendor/licenses-install-types).
1. Follow the instructions provided to install. Status indicators track your progress throughout the installation.
If you exit the Enterprise Portal before completing the installation, you can resume the installation process by clicking **Continue installation** on the **Install** page, as shown below:

[View a larger version of this image](/images/enterprise-portal-continue-install.png)
### View update instructions
To view update instructions in the Enterprise Portal:
1. Log in to the Enterprise Portal and go to **Update**.
For any online instances, the Enterprise Portal displays an **Update available** button when a new version is available.
1. If an **Update available** button is displayed, click it to view and follow the update instructions for the given instance.
## View instance records
Users can view their active and inactive instances in the Enterprise Portal, including the instance status and other details.
:::note
Air gap instance records do not appear in the Enterprise Portal until the user adds a record by either uploading a support bundle for the instance or manually entering instance information. See [Create an Air Gap Instance Record](#create-an-air-gap-instance-record) below.
:::
### View active and inactive instances
To view instances in the Enterprise Portal:
1. In the Enterprise Portal, go to **Updates**.
1. Under **Active Instances**, view details about the active instances. Select **View inactive instances** to view details about inactive instances.

[View a larger version of this image](/images/enterprise-portal-instance-details.png)
The following table describes the instance details available on the **Updates** page:
| Field | Description |
|---|---|
| Instance ID | The unique identifier for the instance. |
| Version | The application version installed. |
| Instance status | The status of the instance, based on the status informers configured for the application. For more information, see [Enable and Understand Application Status](/vendor/insights-app-status). |
| First check-in | The timestamp when the instance first sent data to the Vendor Portal. |
| Last check-in | The timestamp when the instance most recently sent data to the Vendor Portal. |
| First ready | The timestamp when the instance first reached a ready state. For more information about the ready state, see [About Resource Statuses](/vendor/insights-app-status#resource-statuses) in Enable and Understand Application Status. |
| Instance labels | Any labels applied to the instance. |
[View a larger version of this image](/images/enterprise-portal-create-air-gap-instance.png)
1. In the **Extract instance info from a support bundle** dialog, upload the support bundle and click **Upload bundle**:
[View a larger version of this image](/images/enterprise-portal-extract-air-gap-instance-bundle.png)
#### Manually create an air gap instance record
To create an air gap instance record manually:
1. On the **Update** page, under **Air gap instances**, click **Create air gap instance record > Enter information manually**.
[View a larger version of this image](/images/enterprise-portal-create-air-gap-instance.png)
1. In the **Manually create air gap instance record** dialog, complete the fields and click **Create instance**.
[View a larger version of this image](/images/enterprise-portal-manually-create-air-gap-instance.png)
## View release history
To view the release history in the Enterprise Portal:
1. In the Enterprise Portal, go to **Release History**.
1. In the **Version History** panel on the left, select a version to view details about the given release.
## View license details
Customers can view license information, including expiration dates and available features.
To manage licenses in the Enterprise Portal:
1. In the Enterprise Portal, go to **License**.
1. Under **License Details**, view license information including the expiration date, status, associated release channels, custom license fields, and more.

[View a larger version of this image](/images/enterprise-portal-license-details.png)
## Manage team settings
This section includes information about how to manage users, service accounts, and SAML authentication in the Enterprise Portal.
### Invite or delete users
Customers can invite additional users to the portal and manage their access.
To manage invite and manage users in the Enterprise Portal:
1. In the Enterprise Portal, open the user account dropdown in the top right of the page and select **Team settings**.

[View a larger version of this image](/images/enterprise-portal-user-account.png)
1. Click **Users**.
1. Manage users as desired:
* To invite a new user, click **Invite user**.
* To delete a user, find the target user in the table and open the menu. Select **Delete user**.
### Manage service accounts
To manage service accounts in the Enterprise Portal:
1. In the Enterprise Portal, open the user account dropdown in the top right of the page and select **Team settings**.

[View a larger version of this image](/images/enterprise-portal-user-account.png)
1. Click **Service accounts**.
1. Manage service accounts as desired:
* To create a new service account, click **Create Service Account**.
* To view a service account token, find the target service account in the table and click **View** under **Token**.
* The revoke a service account's token, find the target service account in the table and open the menu under **Actions**. Select **Revoke**.
### Configure SAML authentication (Alpha) {#saml}
:::note
SAML Authentication to the Enterprise Portal is Alpha and subject to change. To access this feature, a feature flag must be enabled for your team. For more information, reach out to your Replicated account representative.
:::
:::note
SAML authentication must be enabled for the customer in the Vendor Portal before they can configure SAML for their Enterprise Portal team. For more information, see [Enable SAML Authentication (Alpha)](enterprise-portal-invite#enable-saml).
:::
To configure SAML authentication for your account:
1. In the Enterprise Portal, open the user account dropdown in the top right of the page and select **Team settings**.

[View a larger version of this image](/images/enterprise-portal-user-account.png)
1. Click **SAML Authentication**.
1. For **Service provider information**, copy the values provided and use them to configure your identity provider (IdP).

[View a larger version of this image](/images/enterprise-portal-saml-sp-info.png)
1. Upload the required metadata XML and public certificate from your IdP.

[View a larger version of this image](/images/enterprise-portal-saml-config.png)
1. After the file upload is complete, the **Enable SAML authentication** toggle is automatically enabled.

[View a larger version of this image](/images/enterprise-portal-saml-enable.png)
:::note
If you disable SAML authentication, the SAML configuration details that you added to the Enterprise Portal are saved.
:::
## Manage user settings
Each user can manage their settings in the Enterprise Portal, including enabling and disabling email notifications for various system events.
To manage user settings in the Enterprise Portal:
1. In the Enterprise Portal, open the user account dropdown in the top right of the page and select **User settings**.

[View a larger version of this image](/images/enterprise-portal-user-account.png)
1. Edit the user settings as desired:
* Edit profile information
* Manage email notification preferences
## Collect, upload, and manage support bundles
End customers can use the portal to collect, upload, and manage support bundles.
The Enterprise Portal limits support bundle uploads to 500 MB. If your support bundle is larger than 500 MB, use the Replicated SDK API `POST /supportbundle` endpoint instead. This endpoint has no size limit because it uploads the bundle directly to cloud storage. For more information, see [supportbundle](/reference/replicated-sdk-apis) in _Replicated SDK API_.
To manage support bundles in the Enterprise Portal:
1. In the Enterprise Portal, go to **Support**.

[View a larger version of this image](/images/enterprise-portal-support.png)
1. Manage support bundles as desired:
* For **Support Bundle Collection**, follow the instructions provided to collect a support bundle based on the environment.
* To upload a support bundle, click **Upload support bundle**.
* To view, download, or delete previous support bundles, select **Download** or **Delete** in the **Support Bundles** table.
---
# About the Enterprise Portal
:::important Alpha Feature
Features described on this page are in alpha and subject to change. Some capabilities might require additional access.
:::
The Enterprise Portal gives your customers one central place to view their install and upgrade instructions for each version of your software, set up their environment, manage their team, and get troubleshooting support by uploading support bundles.
By connecting your own GitHub repo, you control the content your customers see. You can serve versioned documentation tied to your releases, auto-generate Helm chart reference docs, customize branding, and distribute Terraform modules through a license-gated proxy registry.
Content is driven by entitlements and channel assignment, so each customer sees only what applies to them.
## What your customers can do
- **Install and upgrade**: Step-by-step installation instructions for Helm and Embedded Cluster (Linux), with per-instance commands personalized to each customer's license and environment
- **Manage instances**: View all deployed instances, check for available updates, and follow inline upgrade instructions
- **Download install artifacts**: Download air gap bundles, Helm chart tarballs, and CLI tools directly from the portal. Available artifacts vary by install method and license entitlements
- **Access security data**: Review CVE reports, filter to fixable vulnerabilities, view per-instance upgrade recommendations, and download SBOMs for each release. Available for Helm and Embedded Cluster installs when Security Center is enabled
- **View release history**: Browse release notes and track what's changed between versions
- **Upload support bundles**: Generate and upload diagnostic bundles for faster troubleshooting
- **Manage their team**: Invite users, create service accounts, and configure SAML SSO
- **Download assets**: Access vendor-provided files (scripts, checklists, configuration templates) gated by entitlements
## What's new
The new Enterprise Portal is a complete rebuild of the customer portal experience. Key differences from the Classic Enterprise Portal:
- **Content repo driven**: All portal content (pages, navigation, branding) is managed through a GitHub repo you control, not through Vendor Portal UI forms
- **MDX components**: Interactive, customer-aware components (install commands, version selectors, upgrade paths) that adapt to each customer's license and instance state
- **Versioned docs**: Each Git branch becomes a version in the customer's portal, with smart resolution that automatically finds the right content for any release
- **Local preview**: `replicated enterprise-portal preview` lets you preview the full portal locally with live reload
- **Helm chart reference**: Auto-generated from your promoted releases with AI-enhanced descriptions
- **Terraform module distribution**: License-gated module registry with native `terraform init` integration (premium feature)
## Current limitations {#current-limitations}
- Installation and upgrade instructions are available only for Embedded Cluster and Helm CLI installations. The Enterprise Portal does not provide instructions for KOTS or kURL.
- Air gap instance records do not appear until the customer creates one from the Instances & Updates page, either by manually entering instance information or by extracting details from an uploaded support bundle.
- Security Center data (CVE reports and SBOMs) is available for Helm and Embedded Cluster installations only. Security data is not displayed for KOTS or kURL installations.
- If you have many version branches and need to make a change across all versions, you must update each branch individually.
## Requirements
Enterprise Portal uses a GitHub App integration to sync content from your repo. The App has read-only access and never writes to or modifies your repositories. You must have a GitHub organization. GitLab, Bitbucket, and other git providers are not supported.
Replicated enables the New Enterprise Portal by default for new teams. If your existing team uses the Classic Enterprise Portal, check the Vendor Portal for New Enterprise Portal pages. Contact your Replicated account representative if you do not see them.
Some Enterprise Portal capabilities require additional access:
* Customer email customization
* Security Center
* Terraform module distribution, available to teams on the Business or Enterprise pricing plan
## For vendors already using the Classic Enterprise Portal
If your team already uses the Classic Enterprise Portal, you can adopt the New Enterprise Portal incrementally. To avoid disrupting existing customers, run both portal versions in mixed mode.
The new Enterprise Portal runs at a different domain (`{appSlug}.enterpriseportal.app`) than Classic (`get.replicated.com/{appSlug}/...`). Both portals share the same backend, so customer data, licenses, and instance information are consistent across both.
### How to get started
1. **Enable mixed mode.** Contact Replicated to run the New Enterprise Portal alongside the Classic Enterprise Portal. Customers continue using their current portal until you move them to the new version.
1. **Connect a content repo.** Follow the setup steps in [Connect a Git Repo](/vendor/enterprise-portal-v2-connect-repo). Connecting a repo has zero effect on any customer's portal version. No customer sees the new portal until you explicitly switch them.
1. **Test it yourself.** Use the local CLI preview (`replicated enterprise-portal preview`) or open the new portal URL directly to see how your content renders. The Vendor Portal also has a "Login as customer" button on each customer's EP access tab.
1. **Move individual customers.** On the customer's **Enterprise Portal access** tab in Vendor Portal, set the **Portal Version** toggle to use the new Enterprise Portal. Only that customer is affected.
1. **Move customers back if needed.** Set the Portal Version toggle back to Classic at any time. The customer immediately returns to the Classic experience.
### Vendor Portal view vs. customer portal version
The **New Portal** / **Classic Portal** toggle appears only in mixed mode. It controls the Vendor Portal view that you see. It does not change which portal your customers see. Use the Portal Version toggle on each customer's EP access tab to change their portal.
---
# Test and Preview the Enterprise Portal
:::important Alpha Feature
Features described on this page are in alpha and subject to change. For access, contact your Replicated account representative.
:::
This topic describes how to preview and test the Enterprise Portal before and after inviting customers, including local preview for content development and logging in as a specific customer for production checks.
## Local preview
Run the Enterprise Portal locally using the Replicated CLI. This is the fastest way to iterate on content because you see changes on browser refresh without committing or pushing.
**Prerequisites:** Docker running, the `replicated` CLI installed, and your content repo checked out locally.
From anywhere on your machine:
```shell
replicated enterprise-portal preview /path/to/your-content-repo --app