Prerequisites

What you need before you install AnsibleForms

  1. Runtime
  2. Database
  3. Sizing
  4. Network
  5. Browser
  6. Scaling

Runtime

AnsibleForms runs as a container, as systemd services on the server itself or, for those who build it themselves, as a Node.js application:

Installation You need
Installer Linux on amd64 or arm64, curl or wget and sha256sum, and the needs of the engine it installs on (below)
Native Root, systemd and a supported Linux (Ubuntu, Debian, RHEL and its rebuilds, SUSE); the installer installs the rest
Docker Docker or Podman, and a MySQL server of your own
Docker Compose Docker Compose or podman-compose; the project starts MySQL too
Kubernetes A cluster, Helm 3 and a StorageClass (or pre-created PersistentVolumes)
From source Node.js 26 (24 at least) with npm, Git, and Ansible for the RTE process that runs the playbooks

The app image, ghcr.io/ansibleforms/ansibleforms, holds Node.js and the tools the server calls (git, ssh, the mariadb client and ytt), but no Python and no Ansible. Playbooks run on an RTE (runtime environment), a second container from ghcr.io/ansibleforms/ansibleforms-rte-full, or from an image you build on ansibleforms-rte-core (see Scaling). Forms that only launch templates on AWX, AAP, Ascender, Semaphore, Rundeck or Jenkins need no RTE.


Database

AnsibleForms stores its jobs, users, credentials and connections in MySQL 8 or later, or in MariaDB.

At the first start it creates the AnsibleForms schema itself. Give it a database user of its own, with rights on that schema only, not root:

CREATE USER 'ansibleforms'@'%' IDENTIFIED BY '<password>';
GRANT ALL PRIVILEGES ON `AnsibleForms`.* TO 'ansibleforms'@'%';

That is all it needs: it creates and patches the schema, makes its backups and, with several workers, ends the session of a dead one. The Status page and the log warn when the user has rights on every database. The app nodes and the workers connect with this user. An RTE in a socket mode (outbound or inbound, see Modes) holds no database credentials: only one in database mode, deprecated since 7.3.0, connects too. To create the schema yourself, set ALLOW_SCHEMA_CREATION to 0. The Docker Compose project and the Helm chart (which uses mysql:8.4) start a database for you.


Sizing

There are no measured requirements: the load depends mostly on how many jobs run at the same time and how much output they write. The Helm chart’s default resources are a reasonable starting point for a small team:

Component Requests Limits Volume
AnsibleForms 1 CPU, 1 GiB memory 4 CPU, 4 GiB memory 10 GiB
MySQL 0.5 CPU, 512 MiB memory 2 CPU, 2 GiB memory 10 GiB

The app container runs no playbook. Each playbook is an ansible-playbook process, with its forks, on an RTE: size every RTE’s CPU and memory for the playbooks it runs at once, at most RTE_MAX_JOBS (10 by default), and run more RTEs to run more. Jobs that run on AWX, AAP, Ascender or the other template runners cost AnsibleForms little.

Job output is kept in the database for ever by default. Set JOB_RETENTION_DAYS on a busy instance to keep the database from growing without limit.


Network

The app and each RTE listen on a port of their own, and open outbound connections to the systems that your forms and settings use.

Inbound

The server listens on port 8000 (PORT), over HTTP or, with HTTPS set to 1, over HTTPS. The Docker Compose project publishes it on port 443, and the Helm chart exposes it through a service or an ingress. An RTE listens on its own PORT too, but only the app calls it: keep it off the public network. An outbound RTE needs no inbound port at all: it dials the app on the app’s port.

Outbound

Open the connections from AnsibleForms to the systems you use:

Destination Used for
MySQL / MariaDB The AnsibleForms database (DB_HOST, DB_PORT, default 3306)
The RTE Dialing an inbound RTE at its runner’s address over one WebSocket, or calling one in database mode at its RTE_URL, which then connects to MySQL itself; an outbound RTE dials the app instead (see Modes)
AWX, AAP, Ascender, Semaphore, Rundeck, Jenkins Launching and following templates and jobs on runners, over their HTTP(S) API
The managed hosts Playbooks connect to them from the RTE, for example over SSH or WinRM
LDAP, Entra ID, OIDC Logging in with directory or single sign-on accounts
Git servers Cloning and pulling repositories, over HTTPS or SSH
REST APIs and databases The data sources of expressions and queries in your forms
HashiCorp Vault, CyberArk Reading credentials from a secret store
Mail servers, Slack, Teams, Telegram, webhooks Job notifications and approval requests, through the notification channels
Model provider The chat assistant, only when it is switched on

To limit which hosts the REST functions of expressions may call, see REST_ALLOWED_HOSTS and REST_DENIED_HOSTS.


Browser

The web application is built for current browsers: Chrome or Edge 111, Firefox 114, Safari 16.4 or newer. Older browsers are not supported.


Scaling

By default one AnsibleForms container runs the web app and the background work together, next to one RTE.

To serve more users, run several app nodes behind a load balancer (AF_ROLE=app) next to a worker (AF_ROLE=worker), which runs the schedules, the backups and the other background work; only one worker works at a time, and a second one waits to take over. They share the database, the persistent folder, ACCESS_TOKEN_SECRET and ENCRYPTION_SECRET. See Scaling. Run more RTEs to run more playbooks at once: see Several RTEs.