So far as I can see in the Salt documentation (e.g. here) there are two main types of modules supported: state modules and execution modules (I know there’re also renderers, returners and so on). Most of examples of SLS files contain statements related only to state modules (under salt.state namespace) whereas for execution modules only command line examples are shown. For example we have two modules named “service”: salt.states.service and salt.modules.service. Right now I have problems using execution modules in SLS files and it seems that either they’re not available at all or I’m missing something to make them available. My question is: is it possible to use execution modules in SLS files and how for example can I restart a service on Ubuntu machine using salt.modules.service.restart function? Also I don’t clearly get the difference between these modules types.

My service name is selenium-node and I tried several combinations and all of them failed:

# First attempt:
selenium-node:
  service.restart

# Another one:
service:
  - restart
  - name: selenium-node

# Or even:
selenium-node:
  service:
    - restart

I faced the same issue when working with git state and execution modules. However when I run the following command on the minion (as shown in the documentation) it succeeds:

$ sudo salt-call service.restart selenium-node

You are correct that there are significant differences between execution modules and state modules. Unfortunately the term module is a bit overloaded.

An execution module is a command sent to a Salt Minion to be executed immediately. Examples are “install apache” or “restart memcached”.

A state module tells the Salt Minion what the end result, or “state” should be. Examples would be “make sure apache is installed” or “make sure this specific config file exists on the filesystem”. The important difference is that a state module will check the system to see if the machine conforms with the desired state before doing anything. So in the case of “make sure apache is installed” the Salt Minion will check to see if Apache is installed and do nothing if Apache is installed. If it’s not obvious, Salt will install Apache if needed.

Now to accomplish restarting the selenium-node like you noted in your question you’ll want to have your service watch something; usually a package change and/or config change. That way Selenium will only restart when needed. Here’s a rough example. I’m not familiar with installation of selenium-node so please consider the following sls file an example. I’m assuming selenium-node can be installed from your system’s package repo.

cat /srv/salt/selenium-node.sls

selenium-node:
  pkg:
    - installed
  service:
    - running
    - watch:
      - pkg: selenium-node
      - file: /etc/selenium-node.conf
  file:
    - managed
    - name: /etc/selenium-node.conf
    - source: salt://selenium/selenium-node.conf # assuming config located at /srv/salt/selenium/selenium-node.conf  on the Salt Master

Here we have 3 states under the “selenium-node” ID Declaration. We’re managing the system package, the service and a config file. You’ll notice that the service is watching both the selenium-node package and the config file. When a service is watching something the service will restart, by default, when the “watched” thing reports a change.

This is generally how you want to handle causing a service restart when using Salt States. This way the service will only get restarted when needed. This helps your Salt States be idempotent and only cause changes to your system when actually needed.

Now, to answer the second part of your question. Yes, it is possible to run an execution module from within a state or sls file. You can accomplish this through the “module.run” state. Docs are here: http://docs.saltstack.com/ref/states/all/salt.states.module.html#module-salt.states.module

Here’s how you would cause your service to restart every time you run this state or sls file:

cat /srv/salt/selenium/selenium-restart.sls

restart_selenium:
  module.run:
    - name: service.restart
    - m_name: selenium-node   # m_name gets passed to the execution module as "name"