Perform/Execute Salt state only once

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.

Synopsis

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

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
  1. The “command-to-run-once” state will execute because the file /etc/salt/.ran_command-to-run-once doesn’t exist
  2. 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
  3. 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)