Execution of Salt modules from within states


There are two styles of calling The legacy style will no longer be available starting in the Sodium release. To opt-in early to the new style you must add the following to your /etc/salt/minion config file:


With these states allow individual execution module calls to be made via states. Here's a contrived example, to show you how it's done:

# New Style
    - test.random_hash:
      - size: 42
      - hash_type: sha256

# Legacy Style
    - size: 42
    - hash_type: sha256

In the new style, the state ID (test.random_hash, in this case) is irrelevant when using It could have very well been written:

Generate a random hash:
    - test.random_hash:
      - size: 42
      - hash_type: sha256

For a simple state like that it's not a big deal, but if the module you're using has certain parameters, things can get cluttered, fast. Using the contrived custom module (stuck in /srv/salt/_modules/, or your configured file_roots):

def bar(name, names, fun, state, saltenv):
    return "Name: {name} Names: {names} Fun: {fun} State: {state} Saltenv: {saltenv}".format(**locals())

Your legacy state has to look like this:

# Legacy style
Unfortunate example:
  - name:
  - m_name: Some name
  - m_names:
    - Such names
    - very wow
  - m_state: Arkansas
  - m_fun: Such fun
  - m_saltenv: Salty

With the new style it's much cleaner:

# New style
    - name: Some name
    - names:
      - Such names
      - very wow
    - state: Arkansas
    - fun: Such fun
    - saltenv: Salty

The new style also allows multiple modules in one state. For instance, you can do this:

Do many things:
    - test.random_hash:
      - size: 10
      - hash_type: md5
    # Note the `:` at the end
    - test.true:
    - test.arg:
      - this
      - has
      - args
      - and: kwargs
      - isn't: that neat?
    # Note the `:` at the end, too
    - test.version:
    - test.fib:
      - 4

Where in the legacy style you would have had to split your states like this:

    - size: 10
    - hash_type: md5


    - args:
      - this
      - has
      - args
    - kwargs:
        and: kwargs
        isn't: that neat?


Another difference is that in the legacy style, unconsumed arguments to the module state were simply passed into the module function being executed:

show off with args:
    - name: test.random_hash
    - size: 42
    - hash_type: sha256

The new style is much more explicit, with the arguments and keyword arguments being nested under the name of the function:

show off with args:
    # Note the lack of `name: `, and trailing `:`
    - test.random_hash:
      - size: 42
      - hash_type: sha256

If the function takes *args, they can be passed in as well:

args and kwargs:
    - test.arg:
      - isn't
      - this
      - fun
      - this: that
      - salt: stack

Modern Examples

Here are some other examples using the modern

    - git.fetch:
      - cwd: /path/to/my/repo
      - user: myuser
      - opts: '--all'

A more complex example:

    - task.create_task:
      - name: events-viewer
      - user_name: System
      - action_type: Execute
      - cmd: 'c:\netops\scripts\events_viewer.bat'
      - trigger_type: 'Daily'
      - start_date: '2017-1-20'
      - start_time: '11:59PM'

It is sometimes desirable to trigger a function call after a state is executed, for this the module.wait state can be used:

add example to hosts:
    - name: /etc/hosts
    - text:

# New Style
    # Again, note the trailing `:`
    - hosts.list_hosts:
    - watch:
      - file: add example to hosts

Legacy (Default) Examples

If you're using the legacy, due to how the state system works, if a module function accepts an argument called, name, then m_name must be used to specify that argument, to avoid a collision with the name argument.

Here is a list of keywords hidden by the state system, which must be prefixed with m_:

  • fun

  • name

  • names

  • state

  • saltenv

For example:

    - name: service.disable
    - m_name: nfs

Note that some modules read all or some of the arguments from a list of keyword arguments. For example:

    - func: network.ip_addrs
    - kwargs:
        interface: eth0
    - func: cloud.create
    - provider: test-provider
    - m_names:
      - test-vlad
    - kwargs: {
          ssh_username: 'ubuntu',
          image: 'ami-8d6d9daa',
          securitygroup: 'default',
          size: 'c3.large',
          location: 'ap-northeast-1',
          delvol_on_destroy: 'True'

Other modules take the keyword arguments using this style:

    - name: system.set_remote_login
    - enable: True

Another example that creates a recurring task that runs a batch file on a Windows system:

    - name: task.create_task
    - m_name: 'events-viewer'
    - user_name: System
    - kwargs: {
          action_type: 'Execute',
          cmd: 'c:\netops\scripts\events_viewer.bat',
          trigger_type: 'Daily',
          start_date: '2017-1-20',
          start_time: '11:59PM'

Run a single module function or a range of module functions in a batch. Supersedes function, which requires m_ prefix to function-specific parameters.

  • returner -- Specify a common returner for the whole batch to send the return data

  • kwargs -- Pass any arguments needed to execute the function(s)

    - network.ip_addrs:
      - interface: eth0
    - cloud.create:
      - names:
        - test-isbm-1
        - test-isbm-2
      - ssh_username: sles
      - image: sles12sp2
      - securitygroup: default
      - size: 'c3.large'
      - location: ap-northeast-1
      - delvol_on_destroy: True

salt.states.module.wait(name, **kwargs)

Run a single module function only if the watch statement calls it


The module function to execute


Pass any arguments needed to execute the function


Like the state, this state will return True but not actually execute, unless one of the following two things happens:

  1. The state has a watch requisite, and the state which it is watching changes.

  2. Another state has a watch_in requisite which references this state, and the state wth the watch_in changes.