1
0

orchestrate_runner.rst 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. .. _orchestrate-runner:
  2. ==================
  3. Orchestrate Runner
  4. ==================
  5. Executing states or highstate on a minion is perfect when you want to ensure that
  6. minion configured and running the way you want. Sometimes however you want to
  7. configure a set of minions all at once.
  8. For example, if you want to set up a load balancer in front of a cluster of web
  9. servers you can ensure the load balancer is set up first, and then the same
  10. matching configuration is applied consistently across the whole cluster.
  11. Orchestration is the way to do this.
  12. The Orchestrate Runner
  13. ----------------------
  14. .. versionadded:: 0.17.0
  15. .. note:: Orchestrate Deprecates OverState
  16. The Orchestrate Runner (originally called the state.sls runner) offers all
  17. the functionality of the OverState, but with some advantages:
  18. * All :ref:`requisites` available in states can be
  19. used.
  20. * The states/functions will also work on salt-ssh minions.
  21. The Orchestrate Runner replaced the OverState system in Salt 2015.8.0.
  22. The orchestrate runner generalizes the Salt state system to a Salt master
  23. context. Whereas the ``state.sls``, ``state.highstate``, et al. functions are
  24. concurrently and independently executed on each Salt minion, the
  25. ``state.orchestrate`` runner is executed on the master, giving it a
  26. master-level view and control over requisites, such as state ordering and
  27. conditionals. This allows for inter minion requisites, like ordering the
  28. application of states on different minions that must not happen simultaneously,
  29. or for halting the state run on all minions if a minion fails one of its
  30. states.
  31. The ``state.sls``, ``state.highstate``, et al. functions allow you to statefully
  32. manage each minion and the ``state.orchestrate`` runner allows you to
  33. statefully manage your entire infrastructure.
  34. Writing SLS Files
  35. ~~~~~~~~~~~~~~~~~
  36. Orchestrate SLS files are stored in the same location as State SLS files. This
  37. means that both ``file_roots`` and ``gitfs_remotes`` impact what SLS files are
  38. available to the reactor and orchestrator.
  39. It is recommended to keep reactor and orchestrator SLS files in their own
  40. uniquely named subdirectories such as ``_orch/``, ``orch/``, ``_orchestrate/``,
  41. ``react/``, ``_reactor/``, etc. This will avoid duplicate naming and will help
  42. prevent confusion.
  43. Executing the Orchestrate Runner
  44. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  45. The Orchestrate Runner command format is the same as for the ``state.sls``
  46. function, except that since it is a runner, it is executed with ``salt-run``
  47. rather than ``salt``. Assuming you have a state.sls file called
  48. ``/srv/salt/orch/webserver.sls`` the following command, run on the master,
  49. will apply the states defined in that file.
  50. .. code-block:: bash
  51. salt-run state.orchestrate orch.webserver
  52. .. note::
  53. ``state.orch`` is a synonym for ``state.orchestrate``
  54. .. versionchanged:: 2014.1.1
  55. The runner function was renamed to ``state.orchestrate`` to avoid confusion
  56. with the :mod:`state.sls <salt.modules.state.sls>` execution function. In
  57. versions 0.17.0 through 2014.1.0, ``state.sls`` must be used.
  58. Masterless Orchestration
  59. ~~~~~~~~~~~~~~~~~~~~~~~~
  60. .. versionadded:: 2016.11.0
  61. To support salt orchestration on masterless minions, the Orchestrate Runner is
  62. available as an execution module. The syntax for masterless orchestration is
  63. exactly the same, but it uses the ``salt-call`` command and the minion
  64. configuration must contain the ``file_mode: local`` option. Alternatively,
  65. use ``salt-call --local`` on the command line.
  66. .. code-block:: bash
  67. salt-call --local state.orchestrate orch.webserver
  68. .. note::
  69. Masterless orchestration supports only the ``salt.state`` command in an
  70. sls file; it does not (currently) support the ``salt.function`` command.
  71. Examples
  72. ~~~~~~~~
  73. Function
  74. ^^^^^^^^
  75. To execute a function, use :mod:`salt.function <salt.states.saltmod.function>`:
  76. .. code-block:: yaml
  77. # /srv/salt/orch/cleanfoo.sls
  78. cmd.run:
  79. salt.function:
  80. - tgt: '*'
  81. - arg:
  82. - rm -rf /tmp/foo
  83. .. code-block:: bash
  84. salt-run state.orchestrate orch.cleanfoo
  85. If you omit the "name" argument, the ID of the state will be the default name,
  86. or in the case of ``salt.function``, the execution module function to run. You
  87. can specify the "name" argument to avoid conflicting IDs:
  88. .. code-block:: yaml
  89. copy_some_file:
  90. salt.function:
  91. - name: file.copy
  92. - tgt: '*'
  93. - arg:
  94. - /path/to/file
  95. - /tmp/copy_of_file
  96. - kwarg:
  97. remove_existing: true
  98. .. _orchestrate-runner-fail-functions:
  99. Fail Functions
  100. **************
  101. When running a remote execution function in orchestration, certain return
  102. values for those functions may indicate failure, while the function itself
  103. doesn't set a return code. For those circumstances, using a "fail function"
  104. allows for a more flexible means of assessing success or failure.
  105. A fail function can be written as part of a :ref:`custom execution module
  106. <writing-execution-modules>`. The function should accept one argument, and
  107. return a boolean result. For example:
  108. .. code-block:: python
  109. def check_func_result(retval):
  110. if some_condition:
  111. return True
  112. else:
  113. return False
  114. The function can then be referenced in orchestration SLS like so:
  115. .. code-block:: yaml
  116. do_stuff:
  117. salt.function:
  118. - name: modname.funcname
  119. - tgt: '*'
  120. - fail_function: mymod.check_func_result
  121. .. important::
  122. Fail functions run *on the master*, so they must be synced using ``salt-run
  123. saltutil.sync_modules``.
  124. State
  125. ^^^^^
  126. To execute a state, use :mod:`salt.state <salt.states.saltmod.state>`.
  127. .. code-block:: yaml
  128. # /srv/salt/orch/webserver.sls
  129. install_nginx:
  130. salt.state:
  131. - tgt: 'web*'
  132. - sls:
  133. - nginx
  134. .. code-block:: bash
  135. salt-run state.orchestrate orch.webserver
  136. Highstate
  137. ^^^^^^^^^
  138. To run a highstate, set ``highstate: True`` in your state config:
  139. .. code-block:: yaml
  140. # /srv/salt/orch/web_setup.sls
  141. webserver_setup:
  142. salt.state:
  143. - tgt: 'web*'
  144. - highstate: True
  145. .. code-block:: bash
  146. salt-run state.orchestrate orch.web_setup
  147. Runner
  148. ^^^^^^
  149. To execute another runner, use :mod:`salt.runner <salt.states.saltmod.runner>`.
  150. For example to use the ``cloud.profile`` runner in your orchestration state
  151. additional options to replace values in the configured profile, use this:
  152. .. code-block:: yaml
  153. # /srv/salt/orch/deploy.sls
  154. create_instance:
  155. salt.runner:
  156. - name: cloud.profile
  157. - prof: cloud-centos
  158. - provider: cloud
  159. - instances:
  160. - server1
  161. - opts:
  162. minion:
  163. master: master1
  164. To get a more dynamic state, use jinja variables together with
  165. ``inline pillar data``.
  166. Using the same example but passing on pillar data, the state would be like
  167. this.
  168. .. code-block:: jinja
  169. # /srv/salt/orch/deploy.sls
  170. {% set servers = salt['pillar.get']('servers', 'test') %}
  171. {% set master = salt['pillar.get']('master', 'salt') %}
  172. create_instance:
  173. salt.runner:
  174. - name: cloud.profile
  175. - prof: cloud-centos
  176. - provider: cloud
  177. - instances:
  178. - {{ servers }}
  179. - opts:
  180. minion:
  181. master: {{ master }}
  182. To execute with pillar data.
  183. .. code-block:: bash
  184. salt-run state.orch orch.deploy pillar='{"servers": "newsystem1",
  185. "master": "mymaster"}'
  186. .. _orchestrate-runner-return-codes-runner-wheel:
  187. Return Codes in Runner/Wheel Jobs
  188. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  189. .. versionadded:: 2018.3.0
  190. State (``salt.state``) jobs are able to report failure via the :ref:`state
  191. return dictionary <state-return-data>`. Remote execution (``salt.function``)
  192. jobs are able to report failure by setting a ``retcode`` key in the
  193. ``__context__`` dictionary. However, runner (``salt.runner``) and wheel
  194. (``salt.wheel``) jobs would only report a ``False`` result when the
  195. runner/wheel function raised an exception. As of the 2018.3.0 release, it is
  196. now possible to set a retcode in runner and wheel functions just as you can do
  197. in remote execution functions. Here is some example pseudocode:
  198. .. code-block:: python
  199. def myrunner():
  200. ...
  201. do stuff
  202. ...
  203. if some_error_condition:
  204. __context__['retcode'] = 1
  205. return result
  206. This allows a custom runner/wheel function to report its failure so that
  207. requisites can accurately tell that a job has failed.
  208. More Complex Orchestration
  209. ~~~~~~~~~~~~~~~~~~~~~~~~~~
  210. Many states/functions can be configured in a single file, which when combined
  211. with the full suite of :ref:`requisites`, can be used
  212. to easily configure complex orchestration tasks. Additionally, the
  213. states/functions will be executed in the order in which they are defined,
  214. unless prevented from doing so by any :ref:`requisites`, as is the default in
  215. SLS files since 0.17.0.
  216. .. code-block:: yaml
  217. bootstrap_servers:
  218. salt.function:
  219. - name: cmd.run
  220. - tgt: 10.0.0.0/24
  221. - tgt_type: ipcidr
  222. - arg:
  223. - bootstrap
  224. storage_setup:
  225. salt.state:
  226. - tgt: 'role:storage'
  227. - tgt_type: grain
  228. - sls: ceph
  229. - require:
  230. - salt: webserver_setup
  231. webserver_setup:
  232. salt.state:
  233. - tgt: 'web*'
  234. - highstate: True
  235. Given the above setup, the orchestration will be carried out as follows:
  236. 1. The shell command ``bootstrap`` will be executed on all minions in the
  237. 10.0.0.0/24 subnet.
  238. 2. A Highstate will be run on all minions whose ID starts with "web", since
  239. the ``storage_setup`` state requires it.
  240. 3. Finally, the ``ceph`` SLS target will be executed on all minions which have
  241. a grain called ``role`` with a value of ``storage``.
  242. .. note::
  243. Remember, salt-run is *always* executed on the master.
  244. .. _orchestrate-runner-parsing-results-programatically:
  245. Parsing Results Programmatically
  246. --------------------------------
  247. Orchestration jobs return output in a specific data structure. That data
  248. structure is represented differently depending on the outputter used. With the
  249. default outputter for orchestration, you get a nice human-readable output.
  250. Assume the following orchestration SLS:
  251. .. code-block:: yaml
  252. good_state:
  253. salt.state:
  254. - tgt: myminion
  255. - sls:
  256. - succeed_with_changes
  257. bad_state:
  258. salt.state:
  259. - tgt: myminion
  260. - sls:
  261. - fail_with_changes
  262. mymod.myfunc:
  263. salt.function:
  264. - tgt: myminion
  265. mymod.myfunc_false_result:
  266. salt.function:
  267. - tgt: myminion
  268. Running this using the default outputter would produce output which looks like
  269. this:
  270. .. code-block:: text
  271. fa5944a73aa8_master:
  272. ----------
  273. ID: good_state
  274. Function: salt.state
  275. Result: True
  276. Comment: States ran successfully. Updating myminion.
  277. Started: 21:08:02.681604
  278. Duration: 265.565 ms
  279. Changes:
  280. myminion:
  281. ----------
  282. ID: test succeed with changes
  283. Function: test.succeed_with_changes
  284. Result: True
  285. Comment: Success!
  286. Started: 21:08:02.835893
  287. Duration: 0.375 ms
  288. Changes:
  289. ----------
  290. testing:
  291. ----------
  292. new:
  293. Something pretended to change
  294. old:
  295. Unchanged
  296. Summary for myminion
  297. ------------
  298. Succeeded: 1 (changed=1)
  299. Failed: 0
  300. ------------
  301. Total states run: 1
  302. Total run time: 0.375 ms
  303. ----------
  304. ID: bad_state
  305. Function: salt.state
  306. Result: False
  307. Comment: Run failed on minions: myminion
  308. Started: 21:08:02.947702
  309. Duration: 177.01 ms
  310. Changes:
  311. myminion:
  312. ----------
  313. ID: test fail with changes
  314. Function: test.fail_with_changes
  315. Result: False
  316. Comment: Failure!
  317. Started: 21:08:03.116634
  318. Duration: 0.502 ms
  319. Changes:
  320. ----------
  321. testing:
  322. ----------
  323. new:
  324. Something pretended to change
  325. old:
  326. Unchanged
  327. Summary for myminion
  328. ------------
  329. Succeeded: 0 (changed=1)
  330. Failed: 1
  331. ------------
  332. Total states run: 1
  333. Total run time: 0.502 ms
  334. ----------
  335. ID: mymod.myfunc
  336. Function: salt.function
  337. Result: True
  338. Comment: Function ran successfully. Function mymod.myfunc ran on myminion.
  339. Started: 21:08:03.125011
  340. Duration: 159.488 ms
  341. Changes:
  342. myminion:
  343. True
  344. ----------
  345. ID: mymod.myfunc_false_result
  346. Function: salt.function
  347. Result: False
  348. Comment: Running function mymod.myfunc_false_result failed on minions: myminion. Function mymod.myfunc_false_result ran on myminion.
  349. Started: 21:08:03.285148
  350. Duration: 176.787 ms
  351. Changes:
  352. myminion:
  353. False
  354. Summary for fa5944a73aa8_master
  355. ------------
  356. Succeeded: 2 (changed=4)
  357. Failed: 2
  358. ------------
  359. Total states run: 4
  360. Total run time: 778.850 ms
  361. However, using the ``json`` outputter, you can get the output in an easily
  362. loadable and parsable format:
  363. .. code-block:: bash
  364. salt-run state.orchestrate test --out=json
  365. .. code-block:: json
  366. {
  367. "outputter": "highstate",
  368. "data": {
  369. "fa5944a73aa8_master": {
  370. "salt_|-good_state_|-good_state_|-state": {
  371. "comment": "States ran successfully. Updating myminion.",
  372. "name": "good_state",
  373. "start_time": "21:35:16.868345",
  374. "result": true,
  375. "duration": 267.299,
  376. "__run_num__": 0,
  377. "__jid__": "20171130213516897392",
  378. "__sls__": "test",
  379. "changes": {
  380. "ret": {
  381. "myminion": {
  382. "test_|-test succeed with changes_|-test succeed with changes_|-succeed_with_changes": {
  383. "comment": "Success!",
  384. "name": "test succeed with changes",
  385. "start_time": "21:35:17.022592",
  386. "result": true,
  387. "duration": 0.362,
  388. "__run_num__": 0,
  389. "__sls__": "succeed_with_changes",
  390. "changes": {
  391. "testing": {
  392. "new": "Something pretended to change",
  393. "old": "Unchanged"
  394. }
  395. },
  396. "__id__": "test succeed with changes"
  397. }
  398. }
  399. },
  400. "out": "highstate"
  401. },
  402. "__id__": "good_state"
  403. },
  404. "salt_|-bad_state_|-bad_state_|-state": {
  405. "comment": "Run failed on minions: test",
  406. "name": "bad_state",
  407. "start_time": "21:35:17.136511",
  408. "result": false,
  409. "duration": 197.635,
  410. "__run_num__": 1,
  411. "__jid__": "20171130213517202203",
  412. "__sls__": "test",
  413. "changes": {
  414. "ret": {
  415. "myminion": {
  416. "test_|-test fail with changes_|-test fail with changes_|-fail_with_changes": {
  417. "comment": "Failure!",
  418. "name": "test fail with changes",
  419. "start_time": "21:35:17.326268",
  420. "result": false,
  421. "duration": 0.509,
  422. "__run_num__": 0,
  423. "__sls__": "fail_with_changes",
  424. "changes": {
  425. "testing": {
  426. "new": "Something pretended to change",
  427. "old": "Unchanged"
  428. }
  429. },
  430. "__id__": "test fail with changes"
  431. }
  432. }
  433. },
  434. "out": "highstate"
  435. },
  436. "__id__": "bad_state"
  437. },
  438. "salt_|-mymod.myfunc_|-mymod.myfunc_|-function": {
  439. "comment": "Function ran successfully. Function mymod.myfunc ran on myminion.",
  440. "name": "mymod.myfunc",
  441. "start_time": "21:35:17.334373",
  442. "result": true,
  443. "duration": 151.716,
  444. "__run_num__": 2,
  445. "__jid__": "20171130213517361706",
  446. "__sls__": "test",
  447. "changes": {
  448. "ret": {
  449. "myminion": true
  450. },
  451. "out": "highstate"
  452. },
  453. "__id__": "mymod.myfunc"
  454. },
  455. "salt_|-mymod.myfunc_false_result-mymod.myfunc_false_result-function": {
  456. "comment": "Running function mymod.myfunc_false_result failed on minions: myminion. Function mymod.myfunc_false_result ran on myminion.",
  457. "name": "mymod.myfunc_false_result",
  458. "start_time": "21:35:17.486625",
  459. "result": false,
  460. "duration": 174.241,
  461. "__run_num__": 3,
  462. "__jid__": "20171130213517536270",
  463. "__sls__": "test",
  464. "changes": {
  465. "ret": {
  466. "myminion": false
  467. },
  468. "out": "highstate"
  469. },
  470. "__id__": "mymod.myfunc_false_result"
  471. }
  472. }
  473. },
  474. "retcode": 1
  475. }
  476. The 2018.3.0 release includes a couple fixes to make parsing this data easier and
  477. more accurate. The first is the ability to set a :ref:`return code
  478. <orchestrate-runner-return-codes-runner-wheel>` in a custom runner or wheel
  479. function, as noted above. The second is a change to how failures are included
  480. in the return data. Prior to the 2018.3.0 release, minions that failed a
  481. ``salt.state`` orchestration job would show up in the ``comment`` field of the
  482. return data, in a human-readable string that was not easily parsed. They are
  483. now included in the ``changes`` dictionary alongside the minions that
  484. succeeded. In addition, ``salt.function`` jobs which failed because the
  485. :ref:`fail function <orchestrate-runner-fail-functions>` returned ``False``
  486. used to handle their failures in the same way ``salt.state`` jobs did, and this
  487. has likewise been corrected.
  488. Running States on the Master without a Minion
  489. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  490. The orchestrate runner can be used to execute states on the master without
  491. using a minion. For example, assume that ``salt://foo.sls`` contains the
  492. following SLS:
  493. .. code-block:: yaml
  494. /etc/foo.conf:
  495. file.managed:
  496. - source: salt://files/foo.conf
  497. - mode: 0600
  498. In this case, running ``salt-run state.orchestrate foo`` would be the
  499. equivalent of running a ``state.sls foo``, but it would execute on the master
  500. only, and would not require a minion daemon to be running on the master.
  501. This is not technically orchestration, but it can be useful in certain use
  502. cases.
  503. Limitations
  504. ^^^^^^^^^^^
  505. Only one SLS target can be run at a time using this method, while using
  506. :py:func:`state.sls <salt.modules.state.sls>` allows for multiple SLS files to
  507. be passed in a comma-separated list.