Skip to main content

Salt Mine & Orchestrate

Victoria Harbour, Hong Kong

Sharing Data with Salt Mine

Salt Mine data can be configured inside the Minion configuration or inside Pillar. E.g. create a file nano /srv/pillar/mine.sls and add all functions that you need to execute in an regular interval - the default interval is 60 minutes:

mine_functions:
  network.ip_addrs: []

And add it to your top file to assign it to all or selected minions nano /srv/pillar/top.sls:

base:
  '*':
    - name
    - mine

Then make sure that all minions update their copy of the Pillar data:

salt '*' saltutil.refresh_pillar

All functions inside your mine will now be executed every 60 minutes you can test run your function with:

mine.send & cache.mine

salt '*' mine.send network.ip_addrs

This will trigger your mine function on every assigned minion. All those minions will then send their reply to the salt master. You can query this data from mine.cache:

salt-run cache.mine '*'                                                                                       

ubuntuAsus:
    ----------
    network.ip_addrs:
        - 10.1.88.0
        - 172.17.0.1
        - 172.18.0.1
        - 172.19.0.1
        - 172.22.0.1
        - 192.168.2.111

You can also populate the cache manually by sending a specific function call:

salt '*' mine.send status.uptime
salt-run cache.mine '*'    
                                                                                   
ubuntuAsus:
    ----------
    network.ip_addrs:
        - 10.1.88.0
        - 172.17.0.1
        - 172.18.0.1
        - 172.19.0.1
        - 172.22.0.1
        - 192.168.2.111
        
    status.uptime:
        ----------
        days:
            0
        seconds:
            27426
        since_iso:
            2020-08-07T06:50:43.445585
        since_t:
            1596783043
        time:
            7:37
        users:
            1

mine.get

To get a specific value from your minions send this from your master:

salt '*' mine.get '*' network.ip_addrs

ubuntuAsus:
    ----------
    ubuntuAsus:
        - 10.1.88.0
        - 172.17.0.1
        - 172.18.0.1
        - 172.19.0.1
        - 172.22.0.1
        - 192.168.2.111

Or this when you are on a minion:

salt-call mine.get '*' network.ip_addrs

local:
    ----------
    ubuntuAsus:
        - 10.1.88.0
        - 172.17.0.1
        - 172.18.0.1
        - 172.19.0.1
        - 172.22.0.1
        - 192.168.2.111

Or in JSON:

salt-call mine.get '*' network.ip_addrs --out=json 
                                                           
{
    "local": {
        "ubuntuAsus": [
            "10.1.88.0",
            "172.17.0.1",
            "172.18.0.1",
            "172.19.0.1",
            "172.22.0.1",
            "192.168.2.111"
        ]
    }
}

Orchestrate Complex State Runs

Executing states or highstate on a minion is perfect when you want to ensure that minion configured and running the way you want. Sometimes however you want to configure a set of minions all at once.

For example, if you want to set up a load balancer in front of a cluster of web servers you can ensure the load balancer is set up first, and then the same matching configuration is applied consistently across the whole cluster.

Orchestration is the way to do this.

The Orchestrate Runner

The orchestrate runner generalizes the Salt state system to a Salt master context. Whereas the state.sls, state.highstate, et al. functions are concurrently and independently executed on each Salt minion, the state.orchestrate runner is executed on the master, giving it a master-level view and control over requisites, such as state ordering and conditionals. This allows for inter minion requisites, like ordering the application of states on different minions that must not happen simultaneously, or for halting the state run on all minions if a minion fails one of its states.

The state.sls, state.highstate, et al. functions allow you to statefully manage each minion and the state.orchestrate runner allows you to statefully manage your entire infrastructure.

call_execution_functions

mkdir /srv/salt/orch

nano /srv/salt/orch/test_function.sls

test_function.sls

call_execution_function:
  salt.function:
    - tgt: '*'
    - name: cmd.run
    - arg:
      - date
salt-run state.orchestrate orch.test_fun

ubuntuserver_master:
----------
          ID: call_execution_function
    Function: salt.function
        Name: cmd.run
      Result: True
     Comment: Function ran successfully. Function cmd.run ran on ubuntuMaster, ubuntuAsus.
     Started: 16:00:02.407973
    Duration: 187.085 ms
     Changes:   
              ubuntuMaster:
                  Fri Aug  7 16:00:02 UTC 2020
              ubuntuAsus:
                  Fri Aug  7 16:00:02 UTC 2020

Summary for ubuntuserver_master
------------
Succeeded: 1 (changed=1)
Failed:    0
------------
Total states run:     1
Total run time: 187.085 ms

call_state_functions

test_function.sls

call_execution_function:
  salt.function:
    - tgt: '*'
    - name: cmd.run
    - arg:
      - date
      
call_state_function:
  salt.state:
    - tgt: 'ubuntuAsus'
    - sls:
      - apache.welcome
salt-run state.orchestrate orch.test_fun

ubuntuserver_master:
----------
          ID: call_execution_function
    Function: salt.function
        Name: cmd.run
      Result: True
     Comment: Function ran successfully. Function cmd.run ran on ubuntuMaster, ubuntuAsus.
     Started: 16:12:21.741197
    Duration: 186.882 ms
     Changes:   
              ubuntuMaster:
                  Fri Aug  7 16:12:21 UTC 2020
              ubuntuAsus:
                  Fri Aug  7 16:12:21 UTC 2020
----------
          ID: call_state_function
    Function: salt.state
      Result: True
     Comment: States ran successfully. No changes made to ubuntuAsus.
     Started: 16:12:21.928273
    Duration: 452.633 ms
     Changes:   

Summary for ubuntuserver_master
------------
Succeeded: 2 (changed=1)
Failed:    0
------------
Total states run:     2
Total run time: 639.515 ms

Execution Order

Making sure that function one is called before function two:

test_function.sls

call_execution_function:
  salt.function:
    - tgt: '*'
    - name: cmd.run
    - arg:
      - date
      
call_state_functions_one:
  salt.state:
    - tgt: 'ubuntuAsus'
    - sls:
      - apache.welcome
      
call_state_functions_two:
  salt.state:
    - tgt: 'ubuntuMaster'
    - sls:
      - apache.welcome
    - require:
      - salt: call_state_functions_one

wait_for_event

The following example blocks until all the listed minions complete a restart and reconnect to the Salt master:

reboot_all_minions:
  salt.function:
    - name: system.reboot
    - tgt: '*'

wait_for_reboots:
  salt.wait_for_event:
    - name: salt/minion/*/start
    - id_list:
      - jerry
      - stuart
      - dave
      - phil
      - kevin
      - mike
    - require:
      - salt: reboot_all_minions