First, I’d like to say that Salt is a great piece of software. I highly recommend it to anyone looking for either a configuration management system (e.g. Puppet, Chef) or a batch remote execution application (e.g. fabric). It’s simple, straight-forward and works.
The Salt state, cmd.run will execute every time a Salt synchronisation is run (state.highstate), provided the “unless” check returns a false (https://salt.readthedocs.org/en/latest/ref/states/all/salt.states.cmd.html?highlight=unless)
It’s not uncommon to have a command that you wish to run only once, such as an initialisation command or an “add” command. Running this command multiple times may have an undesirable result, such as clobbering a configuration.
The solution is very simple, but may not be immediately obvious:
command-to-run-once: cmd: - run - name: ls - unless: test -f /etc/salt/.ran_command-to-run-once create-after-first-execution: file: - managed - name: /etc/salt/.ran_command-to-run-once - require: - cmd: command-to-run-once
- The “command-to-run-once” state will execute because the file /etc/salt/.ran_command-to-run-once doesn’t exist
- The “create-after-first-execution” state will run after “command-to-run-once” has been executed (its a dependent), creating the file /etc/salt/.ran_command-to-run-once
- Subsequent executions of the state, “command-to-run-once” will not run because the file /etc/salt/.ran_command-to-run-once exists (created in step 2)