Version 2023.3

This manual covers the installation of Gradle Enterprise into an existing Kubernetes cluster.

Time to completion: 60 minutes

Before Installation

Gradle Enterprise is a Kubernetes-based application, distributed as a Helm Chart.

The Kubernetes installation of Gradle Enterprise described in this manual covers the installation of Gradle Enterprise into an existing Kubernetes cluster, using the Helm Kubernetes package manager.

Helm manages all Gradle Enterprise components.

For those installing Gradle Enterprise on a host without public network connectivity, please follow sections marked Airgap.

Prerequisites

1. A Gradle Enterprise License

If you have purchased Gradle Enterprise or started a trial, you should already have a license file called gradle-enterprise.license. Otherwise, you may request a Gradle Enterprise trial license.

Host Requirements

This section outlines the host requirements for the installation.

1. Kubernetes Versions

Gradle Enterprise has been tested as compatible with Kubernetes API versions 1.11.x to 1.27.x. Later versions may be compatible but have not been verified to work.

2. Kubernetes Platforms

Gradle Enterprise does not use any platform specific features and is expected to work on all platforms, but not all are verified to work.

3. Helm Requirements

Please check the Helm Version Support Policy to ensure compatibility with your Kubernetes version.

4. Resource Requirements

Node Group Specification

If you are planning to provision a dedicated cluster for your Gradle Enterprise installation, our recommended node group specification for that cluster is 3 nodes, each with roughly 4 CPU units and 16 GiB memory.

Resource Requests and Limits

If you are planning to install Gradle Enterprise in an existing cluster, we recommend ensuring access to at least 8 CPU units and 16 GiB memory.

The Gradle Enterprise Helm Chart’s total resource requests and limits are:

  • Resource requests (the minimal resources required by the application to start): 6.85 CPU units, 13.53125 GiB memory.

  • Resource limits (the maximum resources that might be used by the application if available): 15.55 CPU units, 25.03125 GiB memory.

5. Database

By default, Gradle Enterprise stores its data in a PostgreSQL database that runs as part of the application itself, with data being stored in a persistent volume. This is referred to as the embedded database.

It is also possible to store Build Scans, build cache node, and test distribution data in a user-managed database. A user-managed database can be any PostgreSQL 12, 13, or 14 compatible database.

6. Storage

Gradle Enterprise uses persistent volume claims for storing data, logs and backups.

You will need to provide the name of the desired storage class to be used for provisioning persistent volumes. Different storage classes can be specified for the three different types of storage used.

Some pods are associated with multiple persistent volumes and for Kubernetes platforms with multiple availability zones, the pods and their persistent volumes must be located in the same zone. In this case it is recommended to use a storage class with a volumeBindingMode of WaitForFirstConsumer to ensure that all persistent volumes are provisioned in the same zone that the pod was scheduled in.

It is strongly recommended to use storage classes that allow persistent volume claim expansion if available. This makes expanding storage used as usage of Gradle Enterprise increases straightforward.

Capacity

The recommended minimum capacities for the persistent volumes are:

Description Size in GB

Build Scans

250

Build Scans backups

250

Build Cache

10

Test Distribution

10

Logs and Monitoring

22

If you are producing many Build Scans in a day (> 1GB) or intend to retain Build Scans for long periods of time (30 days+) you may want to consider provisioning more storage.

If your storage class does not allow expanding volumes, you should also consider preparing for future data growth by adding additional disk capacity upfront.

Performance

For production workloads, the data storage class should exhibit SSD-class disk performance of at least 3000 IOPS (input/output operations per second).

The storage classes used for logs and backup volumes may be slower.

Disk performance has a significant impact on Gradle Enterprise performance.

7. Networking

By default, Gradle Enterprise requires a cluster whose nodes can pull images from the internet. It also requires network connectivity for periodic license validation.

An installation of Gradle Enterprise will not start if it cannot connect to both registry.gradle.com and harbor.gradle.com.

For clusters with limited or no internet connectivity, please follow the Airgap installation steps.

The next sections highlight networking options for your Gradle Enterprise installation which must be considered for the subsequent Helm Configuration section.

Verifying Connectivity

Internet connectivity to https://helm.gradle.com is required on the host where you run Helm.

For Airgap installations, a connection to the internet on a machine is required to download Gradle Enterprise installation bundles. You must ensure that you can transfer the files to the host (with limited internet connectivity) at installation time.

Connectivity can be tested by running the following command:

$ curl -sw \\n --fail-with-body --show-error https://helm.gradle.com/ping
$ kubectl run gradle-registry-test -q --rm --attach --restart=Never \
    --image=curlimages/curl -- -sw \\n --fail-with-body --show-error \
    https://registry.gradle.com/ping
$ kubectl run gradle-harbor-test -q --rm --attach --restart=Never \
    --image=curlimages/curl -- -sw \\n --fail-with-body --show-error \
    https://harbor.gradle.com/ping

All three of these commands should return SUCCESS.

HTTP / HTTPS

Connecting to the application over HTTPS with a trusted certificate is strongly recommended.

When using the Gradle Enterprise supplied Ingress, HTTPS is enabled by default with a self-signed certificate.

SSL certificates, trusted or untrusted, must be provided by your organization to Helm.

In many setups, a reverse proxy or load balancer will perform SSL termination. In these cases SSL certificates must be configured with that infrastructure.

Ports

The ports that the application accepts traffic on can be altered from the default of 443 (or 80 if accepting plain HTTP) during Helm Configuration.

Make sure any additional ports such as K3s or user-managed database ports are reachable if necessary.

Proxy

In case your organization requires all outbound HTTP traffic to go through an HTTP proxy, this must be addressed during Helm Configuration.

Hostname

When installing Gradle Enterprise, a hostname such as ge.example.com is required.

Make sure to configure the DNS records accordingly.

Add an A record for the hostname that points to the public IP address of your host.

ge.example.com A 12.34.56.78

Verify that your DNS record works correctly before installing Gradle Enterprise by running dig ge.example.com or ping ge.example.com within the terminal.

If running Gradle Enterprise behind a cloud load balancer, use /ping for the load balancer’s health check. It will respond as healthy when Gradle Enterprise is capable of handling requests, even if limited to the interactive starting page while the instance is starting. Using the load balancer to manage fail-over may be undesirable for highly available installations.

If you are installing Gradle Enterprise in a highly available setup, we recommend submitting a ticket at support.gradle.com for assistance.

8. Kubernetes Permissions

The user running Helm or applying its output should have permission to create Kubernetes resources in the designated namespace.

If your Kubernetes environment has fine-grained permissions such that your Kubernetes account may not be able to create certain types of resources, it is recommended to inspect the resources that Gradle Enterprise creates by running helm template and viewing the output.

Helm Configuration

Installation options for Grade Enterprise are depicted in a Helm values file.

Follow the instructions in the Kubernetes Helm Chart Configuration Guide and return to this document with a complete values.yaml file.

Installation

In this section you will install Gradle Enterprise on your host.

To install Gradle Enterprise, commands will need to be executed on a host with connectivity to your Kubernetes cluster.

For those installing Gradle Enterprise on a host without public network connectivity, please follow the Airgap installation instructions.

1. Install Helm

Develocity requires Helm version 3.5.x (or later) to install.

It is recommended to use the latest version available as this will have all known security vulnerabilities addressed. This document describes the maximum version skew supported between Helm and Kubernetes.

For more information on installing Helm (including alternate installation approaches), see Installing Helm.

Install Helm by running the command:

$ curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

Verify that helm is installed and working:

$ helm version

The expected output should be similar to this:

version.BuildInfo{Version:"v3.11.1", GitCommit:"293b50c65d4d56187cd4e2f390f0ada46b4c4737", GitTreeState:"clean", GoVersion:"go1.19.5"}

2. Install the Helm chart

Develocity is distributed from the Develocity Helm repository.

Add the Develocity Helm repository to your Helm installation and fetch its contents into the local cache:

$ helm repo add gradle https://helm.gradle.com/
$ helm repo update gradle

Verify that the Develocity chart is accessible:

$ helm search repo gradle-enterprise

This will report the latest versions available for the two Develocity charts:

NAME                               	CHART VERSION	APP VERSION	DESCRIPTION
gradle/gradle-enterprise           	2023.3.4        2023.3.4    Official Develocity chart for Kubernetes cluster installations
gradle/gradle-enterprise-standalone	2023.3.4        2023.3.4    Official Develocity chart for standalone installations
This guide covers installation of the gradle-enterprise chart. Installation of the gradle-enterprise-standalone chart is covered in the Self-Hosted Standalone Installation Guide.

3. Install Gradle Enterprise

The recommended way to install Develocity is letting Helm manage the installation. For alternatives, see Advanced installation.

Install Develocity:

$ helm install \
    --create-namespace --namespace develocity \(1)
    ge \(2)
    gradle/gradle-enterprise \(3)
    --values values.yaml \(4)
    --set-file global.license.file=./develocity.license (5)
1 This example uses develocity as the namespace, but it can be a custom name. If you use a custom name, update all other example commands accordingly. Running with --create-namespace will create the namespace if it does not already exist.
The namespace option may not be required for OpenShift if oc login has been run and the active project for the current context is set.
2 This is the Helm release name. It is used by Helm to identify the Develocity installation.
3 The Develocity chart to install, in this case, gradle/gradle-enterprise.
To install a specific version, use --version 2023.3.4.
4 The Helm values file with configuration values, including items such as the hostname.
5 The Develocity license file (if not already included in your values file).

4. Start Gradle Enterprise

At this point, it should be possible to see the Helm release installed:

$ helm --namespace gradle-enterprise list
NAME	NAMESPACE        	REVISION	UPDATED                               	STATUS  	CHART                     	    APP VERSION
ge  	gradle-enterprise	1       	2023-11-20 04:59:38.62408043 +0000 UTC	deployed	gradle-enterprise-2023.3.4  	2023.3.4

You can inspect the status of the Gradle Enterprise pods:

$ kubectl --namespace gradle-enterprise get pods
NAME                                               READY   STATUS    RESTARTS   AGE
gradle-enterprise-operator-76694c949d-md5dh        1/1     Running   0          84m
gradle-monitoring-5545d7d5d8-lpm9x                 1/1     Running   0          84m
gradle-proxy-0                                     1/1     Running   0          83m
gradle-database-65d975cf8-dk7kw                    2/2     Running   0          83m
gradle-enterprise-app-0                            1/1     Running   0          83m
gradle-metrics-cfcd8f7f7-zqds9                     1/1     Running   0          83m
gradle-test-distribution-broker-6fd84c6988-x6jvw   1/1     Running   0          83m
gradle-build-cache-node-57b9bdd46d-2txf5           1/1     Running   0          84m
gradle-keycloak-0                                  1/1     Running   0          83m

Gradle Enterprise has a /ping endpoint, which can be used to verify network connectivity with Gradle Enterprise.

Connectivity to Gradle Enterprise installation can be tested by running the following command on hosts / computers which need to connect to Gradle Enterprise:

$ curl -sw \\n --fail-with-body --show-error https://«gradle-enterprise-host»/ping

It should return SUCCESS.

Once all pods have a status of Running and the system is up and connected, you can interact with Gradle Enterprise by visiting its URL in a web browser (i.e. the hostname).

gradle enterprise

Congratulations Gradle Enterprise is installed and running. Head over to the Post Installation section for next steps.

Airgap Installation

Airgap installations require a Docker or compatible registry available on an internal network that is accessible from the cluster to which Gradle Enterprise images can be pushed.

Airgap installations require a specific entitlement on your license. If you need an Airgap-enabled license, please contact your customer success representative.

For Airgap installations:

  • The installation files must be downloaded on a host with access to the internet

  • The images must be uploaded to the internal container registry on a host with network access to the internal container registry (no internet access required)

  • Helm must be run on a host with network access to the Kubernetes cluster (no internet access required)

  • There must be some mechanism for transferring the downloaded installation files to where they will be used

1. Overview

Airgap installation involves downloading files, transferring them, installing supporting software, and running helm install.

We recommend you save all the files into a single transfer directory so that it is easy to transfer to other hosts. For example:

$ mkdir develocity-installation-files && cd develocity-installation-files

2. Download Helm

Download and verify the Helm binary:

$ curl -L -o helm-linux-amd64.tar.gz https://get.helm.sh/helm-v3.11.1-linux-amd64.tar.gz
$ echo "0b1be96b66fab4770526f136f5f1a385a47c41923d33aab0dcb500e0f6c1bf7c  helm-linux-amd64.tar.gz" | \
    sha256sum -c

3. Download Bundle

Save your Develocity license to the transfer directory as develocity.license.

Download and verify the airgap bundle:

$ curl -LOJd @develocity.license \
    https://registry.gradle.com/airgap/gradle-enterprise-2023.3.4-bundle.tar.gz
$ curl -LOJd @develocity.license \
    https://registry.gradle.com/airgap/gradle-enterprise-2023.3.4-bundle.tar.gz.sha256
$ sha256sum -c gradle-enterprise-2023.3.4-bundle.tar.gz.sha256

If checksum verification fails, check the contents of the downloaded files for error messages. If the error message indicates that your license is invalid/expired/not airgap enabled, you will need to request an updated license file by contacting your customer success representative.

Instead of running the above curl commands, you can download the airgap bundle by navigating to https://registry.gradle.com/airgap in your browser and following the instructions on the page.

4. Download Helm Values File

Download and verify the example Helm values file:

$ curl -L -o example.values.yaml \
    https://docs.gradle.com/enterprise/helm-kubernetes-installation/values-2023.3/gradle-enterprise-values-2023.3.yaml
$ curl -L -o example.values.yaml.sha256 \
    https://docs.gradle.com/enterprise/helm-kubernetes-installation/values-2023.3/gradle-enterprise-values-2023.3.yaml.sha256
$ echo "$(cat example.values.yaml.sha256)  example.values.yaml" | sha256sum -c

5. Configure Helm Values File

Before installing Gradle Enterprise and its prerequisites, make sure your Helm values file from the Helm Configuration section is available on your local workstation.

You can use the example values.yaml file from the previous section to check for any missing configuration.

6. Transfer Files

Check that the transfer directory contains the following files (additional files are fine):

  • helm-linux-amd64.tar.gz

  • develocity.license

  • values.yaml

  • gradle-enterprise-2023.3.4-bundle.tar.gz

  • Optional: SSL certificates

Once you’ve verified that you have the required files, transfer them to the host with connectivity to the internal container registry and Kubernetes cluster.

7. Upload Images

Follow these instructions on the host with connectivity to the internal container registry with your transferred files present in the current directory.

You must be logged in to the registry prior to running these commands.

Expand the bundle:

$ tar zxvf gradle-enterprise-2023.3.4-bundle.tar.gz

Upload the images to the internal container registry:

$ ./upload-images.sh --registry=registry.example.com/gradle-enterprise

8. Install Helm

Follow these instructions on the host with connectivity to the Kubernetes cluster with your transferred files present in the current directory.

To install Helm:

$ tar -zxvf helm-linux-amd64.tar.gz
$ sudo mv linux-amd64/helm /usr/local/bin/helm

Verify that helm is installed and working:

$ helm version

The expected output should be similar to this:

version.BuildInfo{Version:"v3.11.1", GitCommit:"293b50c65d4d56187cd4e2f390f0ada46b4c4737", GitTreeState:"clean", GoVersion:"go1.19.5"}

9. Install Gradle Enterprise

The recommended way to install Develocity is letting Helm manage the installation. For alternatives, see Advanced installation.

Follow these instructions on the host with connectivity to the Kubernetes cluster with your transferred files present in the current directory.

Expand the bundle (may have already been expanded if you uploaded the images on this host):

$ tar zxvf gradle-enterprise-2023.3.4-bundle.tar.gz

Install Develocity:

$ helm install \
    --create-namespace --namespace develocity \(1)
    ge \(2)
    ./gradle-enterprise-2023.3.4.tgz \(3)
    --values values.yaml \(4)
    --set-file global.license.file=./develocity.license (5)
1 This example uses develocity as the namespace, but it can be a custom name. If you use a custom name, update all other example commands accordingly. Running with --create-namespace will create the namespace if it does not already exist.
The namespace option may not be required for OpenShift if oc login has been run and the active project for the current context is set.
2 This is the Helm release name. It is used by Helm to identify the Develocity installation.
3 The Develocity chart to install. This is the .tgz file included in the airgap bundle.
4 The Helm values file with configuration values, including items such as the hostname.
5 The Develocity license file (if not already included in values file).

10. Start Gradle Enterprise

You can see the status of Gradle Enterprise starting up by examining its pods.

$ kubectl --namespace gradle-enterprise get pods
NAME                                              READY   STATUS              RESTARTS   AGE
gradle-enterprise-operator-76694c949d-md5dh       1/1     Running             0          39s
gradle-monitoring-5545d7d5d8-lpm9x                1/1     Running             0          39s
gradle-database-65d975cf8-dk7kw                   0/2     Init:0/2            0          39s
gradle-build-cache-node-57b9bdd46d-2txf5          0/1     Init:0/1            0          39s
gradle-proxy-0                                    0/1     ContainerCreating   0          39s
gradle-metrics-cfcd8f7f7-zqds9                    0/1     Running             0          39s
gradle-test-distribution-broker-6fd84c6988-x6jvw  0/1     Init:0/1            0          39s
gradle-keycloak-0                                 0/1     Pending             0          39s
gradle-enterprise-app-0                           0/1     Pending             0          39s

Eventually the pods should all report as Running:

$ kubectl --namespace gradle-enterprise get pods
NAME                                               READY   STATUS    RESTARTS   AGE
gradle-enterprise-operator-76694c949d-md5dh        1/1     Running   0          4m
gradle-monitoring-5545d7d5d8-lpm9x                 1/1     Running   0          4m
gradle-proxy-0                                     1/1     Running   0          3m
gradle-database-65d975cf8-dk7kw                    2/2     Running   0          3m
gradle-enterprise-app-0                            1/1     Running   0          3m
gradle-metrics-cfcd8f7f7-zqds9                     1/1     Running   0          3m
gradle-test-distribution-broker-6fd84c6988-x6jvw   1/1     Running   0          3m
gradle-build-cache-node-57b9bdd46d-2txf5           1/1     Running   0          4m
gradle-keycloak-0                                  1/1     Running   0          3m

Once all pods have a status of Running and the system is up and connected, you can interact with it by visiting its URL in a web browser (i.e. the hostname).

11. Cleanup

It is recommended to remove the following files after installation:

  • helm-linux-amd64.tar.gz

  • gradle-enterprise-2023.3.4-bundle.tar.gz

  • gradle-enterprise-2023.3.4.tgz

  • gradle-enterprise-2023.3.4-images.tar

Once Gradle Enterprise has been installed, files used during installation are not required at runtime and can be removed if desired. However, the following files may be useful to preserve, as they may aid in future upgrades or maintenance:

  • Helm values files

  • SSL certificates

  • Gradle Enterprise license

Care should be applied when handling these files as they may be considered sensitive.

Congratulations Gradle Enterprise is installed and running.

Post-Installation

Many features of Gradle Enterprise, including access control, database backups, and Build Scan retention can be configured in Gradle Enterprise, once it is running. Consult the Gradle Enterprise Administration guide to learn more.

For instructions on how to start using Gradle Enterprise in your builds, consult the Getting Started with Gradle Enterprise guide.

Appendix

Appendix A: Advanced installation

Chart download and selection options

When asking Helm to install or process a chart, it is possible to pick a number of sources:

  • A chart from a repository directly.

  • A downloaded chart archive.

  • An expanded chart directory.

Which of these to use depends somewhat on network and policy requirements.

Direct selection

This involves simply running helm commands using the above gradle/gradle-enterprise chart name. Helm will download the chart if necessary during execution, so this option requires internet connectivity on the host that Helm is executed on.

Examples:

$ helm install ge gradle/gradle-enterprise «options»
$ helm template gradle/gradle-enterprise «options»

In the absence of reasons not to, Gradle recommends installing Gradle Enterprise charts in this manner, and this method is used in the main installation section above.

Downloaded archive

Helm can download a chart archive, and can execute using the downloaded archive. This is most useful when the host with internet connectivity does not have access to the Kubernetes cluster.

Example:

$ helm pull gradle/gradle-enterprise

Downloads the latest version to an archive in the current directory e.g. gradle-enterprise-2023.3.4.tgz.

Then later, possibly on a different host:

$ helm install ge gradle-enterprise-2023.3.4.tgz «options»

This is also the installation method used for airgap installations.

Expanded chart directory

It is common for users of Helm to download a chart, edit the included Helm values file, and then commit the result to source control. It is recommended to keep configuration in a separate values file, and install a pristine Gradle Enterprise chart with configuration provided alongside. However, if your organisation’s processes expect Helm Charts to be edited inline, it is possible using this method.

Example:

$ helm pull gradle/gradle-enterprise --untar

Downloads the latest version, and expands it into a gradle-enterprise directory in the current directory.

Or for airgap customers, simply extract the chart .tgz file included in the bundle:

$ mkdir -p gradle-enterprise && \
    tar zxvf path/to/gradle-enterprise-2023.3.4.tgz -C gradle-enterprise

At this point gradle-enterprise/values.yaml can be edited, and the directory committed to source control.

Later:

$ helm install ge ./gradle-enterprise «options»

Installs Gradle Enterprise from a directory with the expanded chart.

Helm post-processing

Many organisations require the ability to customise Kubernetes manifests prior to applying them to their cluster. Kustomize is one commonly used tool to do this. It is possible to alter the Helm-generated Kubernetes manifests prior to Helm applying them to the cluster, using Helm Post Rendering via the --post-renderer flag. In this way, manifests can be customised while still allowing Helm to manage what is applied to the cluster.

$ helm install \
    --create-namespace --namespace gradle-enterprise \
    ge gradle/gradle-enterprise \
    --values values.yaml \
    --set-file global.license.file=./gradle-enterprise.license \
    --post-renderer path/to/post-renderer.sh

The --post-renderer option specifies an executable script that is given the Helm-rendered manifests as input (from stdin), and produces manifests with further customisations as output (to stdout).

An example of a Helm post-renderer that uses Kustomize is provided below:

#!/usr/bin/env bash
set -eo pipefail
cat <&0 > /absolute/path/to/kustomizations/gradle-enterprise.yaml
kustomize build /absolute/path/to/kustomizations

In this example, the gradle-enterprise.yaml file contains the output of the Helm rendering step. This file should then be used by the kustomization.yaml as an input, as shown below:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - gradle-enterprise.yaml

# Rest of kustomization

User-managed installation

An alternative to running helm install directly on your cluster is to have Helm generate Kubernetes manifests that can then be applied via kubectl or other Kubernetes tooling. In this mode, Helm does not keep track of previously installed versions - the resources in the cluster are not tracked and Helm cannot report on the currently installed version.

The most common reasons to do a user-managed installation are:

  • Requirements that the final applied manifests are committed to source control.

  • Need to modify the manifests prior to applying them to the cluster in a way that is not supported by Helm post-processing.

  • Preference or policy to have manifests applied and managed by other tooling.

  • Need to execute Helm on a host separated from the cluster.

There are some other downsides:

  • Some manual cleanup of resources is required after upgrades or uninstallation.

Running helm template

By default, Helm will generate a combined Kubernetes manifest and write it to standard output.

$ helm template \
    gradle/gradle-enterprise \(1)
    --values values.yaml \(2)
    --set-file global.license.file=./gradle-enterprise.license \(3)
    > gradle-enterprise.yaml (4)
1 The Gradle Enterprise chart to install - gradle/gradle-enterprise.
To install a specific version, pass this as additional parameters, e.g. --version 2023.3.4.
2 The Helm values file with configuration values, including items such as the hostname.
3 The Gradle Enterprise license file.
4 Save all the rendered manifests to a single yaml file.

You may wish to pass other files using --set-file, such as certificates for HTTPS.

Configuration values can be provided to Helm in a variety of ways. This includes:

  • providing a Helm values file (which can contain inline files) with --values

  • providing files (such as the Develocity license or certificates) with --set-file

  • setting individual values with --set

Choose a combination that works for your own configuration management processes.

The generated manifest can be committed to version control, copied or processed at this point.

Manifests can also be generated as a set of files in a directory, broken up into logical groupings, by calling Helm with the --output-dir argument:

$ helm template \
    gradle/gradle-enterprise \
    --values values.yaml \
    --set-file global.license.file=./gradle-enterprise.license \
    --output-dir ./my-gradle-enterprise-manifests

The above will create files under the specified directory. This may be a preferred form for customisation, including using tools such as Kustomize.

Invariant output

By default, the Gradle Enterprise Helm Chart randomly generates several secrets during rendering. For example, the embedded database user credentials. This means that by default, repeated invocations of helm template will result in non-identical manifests, because the randomly generated secrets will be different each time, as a security precaution. This can cause unnecessary restarts in Gradle Enterprise installations, where automated tooling uses changes in rendering output to trigger redeployment.

It is possible to configure Helm such that the output of helm template is invariant. This can be done by setting secret values directly or by specifying a user-managed secret. You also can combine the two solutions if appropriate for your installation, by specifying some secret values directly, and some using user-managed secrets.

The secrets which you’ll need to specify to get invariant output, are shown in the table below.

Helm value Secret data key(s) Usage

For these Helm value keys, you can set either 'value' or 'secretName' under them, to either directly set the secret’s value, or to instead use a user-managed secret, respectively.

When creating user-managed secrets, the secret should have the verbatim data key(s) given in this column. Dots (.) should not be interpreted as nesting or indentation. For example, a secret data key like 'abc.def' should appear in your created secret like this:

apiVersion: v1
kind: Secret
metadata:
  name: gradle-abc-def-secret
data:
  abc.def: "a-secret-value"

database.credentials.app

username, password

The credentials used by the app to connect to the database

username must be set to ge_app

database.credentials.migrator

username, password

The credentials used when running database migrations

username must be set to ge_migrator

enterprise.session.key

client.side.session.key

The symmetric encryption key used for client-side session data

enterprise.session.token

client.side.session.token

The token used for signing the data associated with client sessions

buildCacheNode.buildCacheBuiltin

build.cache.builtin.secret

The shared secret value used by the app to register the built-in build cache node

authenticationBroker.clientSecret

keycloak.client.secret

The client secret used by the app when connecting to keycloak

authenticationBroker.adminPassword

keycloak.admin.password

The password for the keycloak admin user

unatttended.configuration.systemPassword

None. Must be provided via unattended configuration.

The hash of the system user password. If not specified, then gradle-default-system-password-secret is generated.

Below shows an example Helm values yaml you can use to get invariant output by specifying user-managed secrets.

database:
  credentials:
   app:
     secretName: <user-managed kubernetes secret resource name>
   migrator:
     secretName: <user-managed kubernetes secret resource name>

enterprise:
  session:
   key:
     secretName: <user-managed kubernetes secret resource name>
   token:
     secretName: <user-managed kubernetes secret resource name>

buildCacheNode:
  buildCacheBuiltin:
   secretName: <user-managed kubernetes secret resource name>

authenticationBroker:
  clientSecret:
   secretName: <user-managed kubernetes secret resource name>
  adminPassword:
   secretName: <user-managed kubernetes secret resource name>

unattended:
  configuration:
    version: 6
    systemPassword: ...

To get invariant output by specifying secret values directly in your Helm values.yaml:

database:
  credentials:
    app:
      password: <secret value>
    migrator:
      password: <secret value>

enterprise:
  session:
    key:
      value: <secret value>
    token:
      value: <secret value>

buildCacheNode:
  buildCacheBuiltin:
    value: <secret value>

authenticationBroker:
  clientSecret:
    value: <secret value>
  adminPassword:
    value: <secret value>

unattended:
  configuration:
    version: 6
    systemPassword: ...

As with other values, it is also possible to set these by passing --set or --set-file when Helm is invoked.

To create a user-managed secret value, you can use kubectl. Below is an example of using kubectl to create embedded database credential secrets, named db-app-user-credentials and db-migrator-user-credentials:

# Add this to your `helm install` command: `--set database.credentials.app.secretName=db-app-user-credentials`
kubectl -n gradle-enterprise create secret generic db-app-user-credentials --from-literal=username=ge_app --from-literal=password=<your password here>

# Add this to your `helm install` command: `--set database.credentials.migrator.secretName=db-migrator-user-credentials`
kubectl -n gradle-enterprise create secret generic db-migrator-user-credentials --from-literal=username=ge_migrator --from-literal=password=<your password here>
When you create a secret and reference it by name in your Gradle Enterprise installation (e.g. using a secretName value), Helm is not managing this secret. If you change the secret value (e.g. when periodically cycling a password), then Gradle Enterprise may need to be restarted manually into order for the changes to be reflected. To do this, restart all the pods in the Gradle Enterprise Helm installation.

Mirroring the Helm Charts

An internal Helm Chart repository can be used to mirror the Gradle Enterprise Helm Charts.

Using helm pull to fetch the charts is the recommended approach since the Gradle Enterprise Helm repo index uses relative urls.

$ helm search repo gradle-enterprise --versions --output json | jq -r '"helm pull " + .[].name + " --version " + .[].version' | sort | uniq | bash