step
keys that every step has
A step is one action on a host: a module with its arguments, or a recipe.
Form
A step is a map. It has one module key, such as pkg or file, with the arguments of the module as a map. Or it has recipe with the name of a recipe. Run winch doc <module> for the arguments of a module.
Computed values
Any module argument can be a template or an expression, and so can then. when takes an expression. loop takes a list or an expression.
Evaluation
On each host, winch evaluates when. When it is false, winch skips the step. Then winch evaluates loop, and the arguments for each element. winch checks the step on the host, and apply changes what differs.
Results
A step that runs a command counts as changed: a cmd, and a service with restarted or reloaded. When a step fails, its host stops. Other hosts go on.
Key order
winch fmt puts the step keys in this order: name, the module or recipe, vars, when, loop, then, confirm_access, notify.
Keys
| Key | Type | Default | Meaning |
|---|---|---|---|
name | string | - | label in the plan and the logs |
recipe | string | - | recipe to run, in place of a module |
vars | map | - | variable values for this recipe step |
when | expression | - | skips the step when false |
loop | list or expression | - | elements to run the step for, as item |
then | string | - | command after a change |
confirm_access | boolean | false | access check with rollback, for a service step |
notify | string or list of strings | - | handlers to run after a change |
step.name
string
Label in the plan and the logs. Without it, the plan shows the module and its main argument.
step.recipe
string
Recipe to run, in place of a module. A recipe step has only name, recipe, vars, and when. A recipe runs at most once per host in a run.
step.vars
map
Variable values for this recipe step. A value can be an !expr or a !tpl, and an !expr can use match(). They beat the inventory, and --set beats them. Only a recipe step has vars.
step.when
expression
Skips the step when false. It is an !expr that gives true or false. winch evaluates none of the other keys of a skipped step. when runs once, before loop, and cannot use item.
step.loop
list or expression
Elements to run the step for, as item. An !expr gives the list. loop: [] runs nothing and notifies nothing. A null element fails the host.
step.then
string
Command after a change. It runs right after the step changes something, before the next step. A failure of then fails the step. With loop, then runs once after the last element and cannot use item. A then that did not run stays pending on the host, and the next run runs it.
step.confirm_access
boolean, default false
Access check with rollback, for a service step. Only a service step can use it, in steps or in handlers. A firewall step gets the same check without it.
Before the step, winch keeps the old state of each path that the changed steps of the recipe wrote or removed in this run. It starts a 60-second rollback timer in a process of its own.
After the step, winch runs the access check: it opens a new SSH connection and runs a command, through sudo -n when the login user is not root. It tries twice, 5 seconds apart.
When both tries fail, winch puts back the old files and runs daemon-reload after a unit file. It reverses a start or a stop of the step, and reloads or restarts the unit again. The host fails with the error "the access check failed: <error>; the old files are back". When the SSH connection ends first, winch rolls back as it ends. When the helper is gone, the timer rolls back.
When a run ends before a notified handler with confirm_access ran, winch puts back the files of that handler at once. The next run applies the change again.
A rollback puts back files only. It does not undo a change of a user or a group.
step.notify
string or list of strings
Handlers to run after a change. Not a template or an expression. With loop, notify fires once when any element changed. Run winch doc handlers.
Example
# winch.yaml
name: demo
hosts:
web1.example.com: {}
vars:
sites: [blog, shop]
steps:
- name: Install nginx
pkg:
name: nginx
- name: Write the sites
file:
path: !tpl /etc/nginx/sites-enabled/{{ .item }}.conf
content: !tpl "# {{ .item }}\n"
when: !expr len(vars.sites) > 0
loop: !expr vars.sites
then: nginx -t
notify: reload
handlers:
reload:
- service:
name: nginx
reloaded: true