# salt.states.module

## Execution of Salt modules from within states

Note

As of the 3005 release, you no longer need to opt-in to the new style of calling `module.run`. The following config can be removed from `/etc/salt/minion`:

    use_superseded:
      - module.run

Both 'new' and 'legacy' styles of calling `module.run` are supported.

With module.run 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:
      module.run:
        - test.random_hash:
          - size: 42
          - hash_type: sha256

    # Legacy Style
    test.random_hash:
      module.run:
        - size: 42
        - hash_type: sha256

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

    Generate a random hash:
      module.run:
        - 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/foo.py`, 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:
      module.run:
      - name: foo.bar
      - 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
    Better:
      module.run:
      - foo.bar:
        - 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:
      module.run:
        - 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:

    test.random_hash:
      module.run:
        - size: 10
        - hash_type: md5

    test.nop:
      module.run

    test.arg:
      module.run:
        - args:
          - this
          - has
          - args
        - kwargs:
            and: kwargs
            isn't: that neat?

    test.version:
      module.run

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 module.run with args:
      module.run:
        - 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 module.run with args:
      module.run:
        # 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:
      module.run:
        - test.arg:
          - isn't
          - this
          - fun
          - this: that
          - salt: stack

### Modern Examples

Here are some other examples using the modern `module.run`:

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

A more complex example:

    eventsviewer:
      module.run:
        - 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:
      file.append:
        - name: /etc/hosts
        - text: 203.0.113.13     example.com

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

### Legacy (Default) Examples

If you're using the legacy `module.run`, 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:

    disable_nfs:
      module.run:
        - 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:

    mine.send:
      module.run:
        - func: network.ip_addrs
        - kwargs:
            interface: eth0

    cloud.create:
      module.run:
        - 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:

    mac_enable_ssh:
      module.run:
        - name: system.set_remote_login
        - enable: True

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

    eventsviewer:
      module.run:
        - 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'
        }

salt.states.module.mod_watch(**kwargs)

  This function is an alias of `run`.

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

  > param returner:

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

  > param kwargs:

  >   Pass any arguments needed to execute the function(s)

  >     some_id_of_state:
  >       module.run:
  >         - 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

  > return:

salt.states.module.run(**kwargs)

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

  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)

      some_id_of_state:
        module.run:
          - 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

  Returns:

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

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

  `name`

    The module function to execute

  `**kwargs`

    Pass any arguments needed to execute the function

  Note

  Like the `cmd.run` 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.

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

  This function is an alias of `wait`.

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

  > `name`

  >   The module function to execute

  > `**kwargs`

  >   Pass any arguments needed to execute the function

  > Note

  > Like the `cmd.run` 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.