Docs / Build your stack
Ansible
Planned design. TractorStack is in development. This page describes how it is designed to work; nothing here is available to install yet. See the roadmap for the status of each part.
Ansible configures everything inside the machines that OpenTofu creates. It connects over SSH, so there is no agent to install or keep updated on each host, and it describes the desired state in plain YAML files that live in your Git repository.
What it is planned to do
The design splits the work into roles, each one small enough to read in a few minutes:
- OS hardening: a CIS-style baseline, users and SSH keys, sudo rules, the host firewall, time sync and log forwarding.
- Docker: the engine and the Compose plugin from a pinned package source, plus daemon settings such as log rotation.
- Data services: PostgreSQL with pgBackRest, RustFS, and Valkey when it is used. These stay Ansible-managed VMs up to stage 3.
- Kubernetes install: TractorStack’s own self-managed Kubernetes stack, installed, configured and upgraded by Ansible from stage 3 on, one node at a time.
- Routine checks: restore tests, patching with a test group first, certificate expiry and disk space.
Role in each stage
| Stage | Main Ansible work |
|---|---|
| 1 | Harden one host, install Docker, set up PostgreSQL and RustFS, schedule backups |
| 2 | Same roles on a second host, set up the streaming replica, off-site copies |
| 3 | Install and upgrade the Kubernetes cluster; data VMs unchanged |
| 4 | Node preparation and cluster upgrades; most data services move to operators |
Inventory from OpenTofu
Hosts are not listed by hand. The plan is to generate the inventory from OpenTofu outputs, grouped by role, so a new VM appears in the right group as soon as it exists.
Planned configuration
A planned example of the top-level playbook. Names and layout may change.
# Planned example only: ansible/site.yml
- hosts: all
become: true
roles:
- baseline # CIS-style hardening
- docker
- hosts: postgres
become: true
roles:
- postgresql
- pgbackrest
- hosts: k8s_nodes # stage 3 and later
become: true
roles:
- kubernetes # self-managed cluster, installed and upgraded by Ansible
Dry runs and idempotence
Before any change on a production host you can run ansible-playbook site.yml --check --diff. Check mode reports what would change without changing it, and --diff shows the file differences. Every role is meant to be idempotent: running it a second time on a host that is already correct should report zero changes. A run that keeps reporting changes is treated as a bug in the role.
Tags are also planned on each task so you can run just one part, for example only the SSH settings, and so that tasks can later be linked to compliance controls Exploring.
What stays yours
- The
ansible/directory, including any roles you add for your own software - SSH keys and vault passwords, which stay on your admin machines
- Decisions on which baseline items to relax, written down in the repository rather than done by hand
Limits and caveats
- Check mode is not a full simulation. Tasks that run raw commands are skipped, and tasks that depend on an earlier change may report wrongly.
- A hardening baseline can break software that expects looser settings. The plan is to test on a small group of hosts first, as described in security.
- Ansible applies changes when it runs. If someone edits a host by hand between runs, you only find out at the next run or check.
- In offline sites, Ansible collections and packages need to come from local mirrors. See offline installs.
Last updated 25 October 2026 · Questions or corrections: sales@infratractor.com