Profiles
One script, several deployments: a declaration inside with profile(...) only materializes when that profile is active.
One script, several deployments. A declaration inside with profile(...)
only materializes when that profile is active, and the same path may have
one variant per profile:
with profile("prod"):
inventory({"web": ["web1.example.com", "web2.example.com"]})
group_vars("all", workers=8)
with profile("dev"):
inventory({"web": ["localhost ansible_connection=local"]})
group_vars("all", workers=1)
$ imix site.py generate out/ -p prod
$ imix site.py run -p dev -C
Nesting is an AND (with profile("prod"): around with profile("eu"):
needs both), -p a,b and repeated -p activate several, -p '*'
activates everything, and INSTAMIX_PROFILE does the same from the
environment. enabled("prod") is a plain predicate you can branch on – a
profile is just Python state, read before the script body runs.
python site.py profiles lists the profiles the script mentions.
Dumping vs. running#
Two profiles are always present: dump while files are written out
(show, cat, generate, diff, lint) and run while they are
handed to ansible-playbook.
with profile("run"):
file("ansible.cfg", "[defaults]\nstdout_callback = yaml\n")
Functions can be gated the same way, so a script can call them unconditionally and you decide per invocation whether they are real:
@only_under("run")
def vault_password():
return subprocess.check_output(["pass", "ansible/vault"]).decode()
Scripts run through the imix command are executed in a namespace
instamix controls – they need no imports at all – and the same gating
applies to instamix’s own API there: run() belongs to the run profile,
so a script ending in a bare run() can still be dumped without touching
a host. register_profile("vault", provides=["run"]) extends that to other
API names.