Hosts and inventory
An inventory is just a list of hosts with connection details. For anything beyond a couple of machines, split it into its own file:
# inventory.yml
groups:
web:
hosts:
- name: web01
address: 203.0.113.42
- name: web02
address: 203.0.113.43
vars:
user: deploy
ssh_key: ~/.ssh/id_ed25519_deploy
db:
hosts:
- name: db01
address: 203.0.113.50
vars:
user: postgresReference it from a playbook with --inventory:
conflux apply site.yml --inventory inventory.yml --limit webModules
A module is a single declarative unit — “this package should be present”, “this file should have this content”, “this service should be running”. Conflux ships with a small built-in set:
| Module | Purpose |
|---|---|
package | Install/remove packages via the host’s native package manager |
file | Manage file content, ownership, permissions |
service | Start/stop/enable systemd units |
user | Create or modify system users |
cron | Manage crontab entries |
exec | Run an arbitrary command, with a change-detection guard |
Every module reports one of three states after running: unchanged, changed, or failed. Nothing is applied twice if it’s already in the desired state.
State tracking
Conflux does not keep a central database. Instead, each host keeps a small local manifest at /var/lib/conflux/state.json recording the last-applied checksum of each module. This is what lets conflux plan tell you what would change without a round trip to a server anywhere.
conflux state show web01web01 — last applied 2026-09-12 14:03 UTC
package.nginx checksum a1b2c3d (unchanged since 2026-08-01)
file./etc/nginx/nginx.conf checksum 9f8e7d6 (changed 2026-09-12)
service.nginx checksum 4c4c4c4 (unchanged since 2026-08-01)Idempotency guarantee
A module is only allowed to report changed if its post-condition differs from its pre-condition. This is enforced by the module framework itself, not left to convention — see Writing Custom Modules if you’re extending Conflux.