Kubernetes
Install AnsibleForms and its MySQL database with the Helm chart
- Prerequisites
- 1. Get the chart values
- 2. Configure the storage
- 3. Set the credentials
- 4. Choose the RTE image
- 5. Install the chart
- 6. Check the install
- 7. Open AnsibleForms
- 8. Sign in
- A Runner on Kubernetes
- Next steps
The Helm chart deploys AnsibleForms with MySQL and the RTE that runs the playbooks (see the values reference). The installer installs the chart too, from a few questions, and upgrades a release it did not install. The same chart also installs a Runner on its own, for an AnsibleForms that runs elsewhere (see A Runner on Kubernetes).
Prerequisites
Before you start, you need:
- Kubernetes cluster : with
kubectlconfigured to reach it - Helm 3 : to install and upgrade the chart
- Storage : a StorageClass for dynamic provisioning, or pre-created PersistentVolumes
- Ingress controller : only if you want to expose AnsibleForms through an ingress
1. Get the chart values
Fetch the chart’s default values into a file of your own, from the chart repository or from the OCI registry:
helm repo add ansibleforms https://ansibleforms.com/helm-charts/
helm repo update
helm show values ansibleforms/ansibleforms > my_values.yaml
No repository to add: the chart is pulled from the GitHub Container Registry.
helm show values oci://ghcr.io/ansibleforms/charts/ansibleforms > my_values.yaml
2. Configure the storage
Both AnsibleForms and MySQL store their data on a persistent volume. Set the StorageClass and size of each:
storages:
server:
className: longhorn
size: 5Gi
accessMode: ReadWriteOnce
mysql:
className: longhorn
size: 5Gi
accessMode: ReadWriteOnce
An empty className uses the cluster’s default StorageClass. The access mode defaults to ReadWriteMany, which many storage classes do not offer; ReadWriteOnce is fine with a single replica. For pre-created PersistentVolumes, see the chart’s README.
3. Set the credentials
AnsibleForms needs an admin account, a database password and an ENCRYPTION_SECRET, the key that encrypts the credentials stored in AnsibleForms. To change that key later, set ENCRYPTION_SECRET_PREVIOUS to the old one for one start: every stored secret is then re-encrypted with the new key. Supply them in one of three ways:
Set them in my_values.yaml. The chart stores them in a Secret named <release>-secrets:
applications:
server:
env:
ADMIN_USERNAME: admin
ADMIN_PASSWORD: a-strong-password
ENCRYPTION_SECRET: a-random-string-of-32-characters
mysql:
password: a-strong-database-password
Let the chart generate whatever you do not supply, on the first install. It keeps the same values on every upgrade afterwards:
--set secrets.generate=true
This does not work with Argo CD or Flux, which render the chart without access to the cluster. The generated Secret survives helm uninstall; back it up, because ENCRYPTION_SECRET cannot be recovered.
Point the chart at a Secret you manage, for example with External Secrets, Sealed Secrets or SOPS. The chart then creates none:
secrets:
existingSecret: ansibleforms-credentials
The Secret must hold DB_USER, DB_PASSWORD, ENCRYPTION_SECRET, ADMIN_USERNAME and ADMIN_PASSWORD.
4. Choose the RTE image
AnsibleForms 7 runs no playbook itself: the RTE (runtime environment) does. The chart runs it as a second container in the server pod, on the same volume, and registers it as the default runner rte, so playbook forms work without any setup. Since 7.3.0 the app dials it on 127.0.0.1 and keeps one WebSocket open (RTE_MODE=inbound, see Modes): the RTE gets no database settings and no encryption key. The chart’s config seed declares an RTE credential with the token and that address, and the runner, mode inbound, that signs in with it.
The default image, ghcr.io/ansibleforms/ansibleforms-rte-full, holds ansible with its collections and the Python libraries the 6.5 image had. For more, or less, build your own on one of the three RTE layers (ansibleforms-rte-base, -rte-core or -rte-full, see The RTE images) and point the chart at it:
containers:
rte:
image: registry.example.com/my-rte:7.0.0
applications:
rte:
env:
ANSIBLE_PATH: /app/dist/persistent/playbooks
The token between the app and the RTE, and the key that signs the sessions, are generated on the first install into the <release>-keys Secret and kept on every upgrade. With a config seed of your own, add that credential and runner to it: the notes Helm prints after the install show how (see the chart’s README).
5. Install the chart
Install the chart into its own namespace with your values:
helm upgrade --install ansibleforms ansibleforms/ansibleforms \
--namespace ansibleforms --create-namespace \
--values my_values.yaml
With the OCI registry, use oci://ghcr.io/ansibleforms/charts/ansibleforms as the chart. In anything that runs unattended, pin the chart version with --version, so that a new release is never installed on its own.
6. Check the install
The chart includes a test that checks both the web server and the database connection:
helm test ansibleforms --namespace ansibleforms --logs
The test ends with OK when AnsibleForms answers and its database accepts connections.
7. Open AnsibleForms
How you reach AnsibleForms depends on how the server is exposed:
With the default ClusterIP service and no ingress, nothing is exposed outside the cluster. Forward a local port to have a look:
kubectl -n ansibleforms port-forward svc/ansibleforms-server 8080:80
Then open http://127.0.0.1:8080/.
Set services.server.type: LoadBalancer (optionally with a fixed address in services.server.loadbalancer.ip), then wait for the service to get its address:
kubectl -n ansibleforms get svc ansibleforms-server -w
Enable the ingress and set the host name that routes to your ingress controller:
ingress:
enabled: true
className: nginx
hostname: ansibleforms.example.com
tls:
enabled: true
The chart’s README covers TLS behind an ingress, including the backend setting that HTTPS on the server needs.
8. Sign in
Sign in as the admin user, admin by default. To read the password from the Secret:
kubectl -n ansibleforms get secret ansibleforms-secrets \
-o jsonpath='{.data.ADMIN_PASSWORD}' | base64 -d
With secrets.existingSecret, read it from your own Secret instead.
A Runner on Kubernetes
With runner.enabled, the chart installs only an RTE: a Runner for an AnsibleForms installed elsewhere, in another namespace, another cluster or on a VM. It dials the app and keeps one WebSocket open (RTE_MODE=outbound, see Modes), so it needs no database, no encryption key and no inbound port. It renders no app, no MySQL, no Service and no Ingress:
helm install runner1 ansibleforms/ansibleforms \
--namespace runners --create-namespace \
--set runner.enabled=true \
--set runner.appUrl=https://forms.example.com \
--set runner.name=zone-a \
--set runner.joinToken=afj_...
| Value | What it does |
|---|---|
runner.enabled | Installs only the Runner: no app, no MySQL, no Service, no Ingress |
runner.appUrl | The app’s address as people open it, with its BASE_URL if any. Required |
runner.name | The runner name it joins as (RTE_NAME). Empty: the release name |
runner.joinToken | A join token made in the app, read on the first start to approve the Runner at once |
runner.appTlsVerify | false accepts the app’s self-signed certificate (APP_TLS_VERIFY=0), inside one trusted network only |
Without a join token, the Runner asks to join and waits until an admin approves it under Connections > Runners. Once approved, it signs in with its own RTE_TOKEN, kept in the <release>-keys Secret: keep that Secret with the release. The installer installs this runner mode too, when you choose the Runner role and Kubernetes.
Next steps
The chart’s README covers the rest of the configuration:
- Your own database : set
mysql.enabled: falseand point AnsibleForms at an existing MySQL server - Forms from ConfigMaps : provide
config.yamland the form files through ConfigMaps - HTTPS behind an ingress, resources, node placement and private registries
- The RTE : its token, an RTE image of your own, or no RTE at all
To move to a newer release, see Upgrading on Kubernetes.