reactor.rst 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. =======================================
  2. Using Salt Cloud with the Event Reactor
  3. =======================================
  4. One of the most powerful features of the Salt framework is the Event Reactor.
  5. As the Reactor was in development, Salt Cloud was regularly updated to take
  6. advantage of the Reactor upon completion. As such, various aspects of both the
  7. creation and destruction of instances with Salt Cloud fire events to the Salt
  8. Master, which can be used by the Event Reactor.
  9. Event Structure
  10. ===============
  11. As of this writing, all events in Salt Cloud have a tag, which includes the ID
  12. of the instance being managed, and a payload which describes the task that is
  13. currently being handled. A Salt Cloud tag looks like:
  14. .. code-block:: yaml
  15. salt/cloud/<minion_id>/<task>
  16. For instance, the first event fired when creating an instance named ``web1``
  17. would look like:
  18. .. code-block:: yaml
  19. salt/cloud/web1/creating
  20. Assuming this instance is using the ``ec2-centos`` profile, which is in turn
  21. using the ``ec2-config`` provider, the payload for this tag would look like:
  22. .. code-block:: python
  23. {"name": "web1", "profile": "ec2-centos", "provider": "ec2-config:ec2"}
  24. Available Events
  25. ================
  26. When an instance is created in Salt Cloud, whether by map, profile, or directly
  27. through an API, a minimum of five events are normally fired. More may be
  28. available, depending upon the cloud provider being used. Some of the common
  29. events are described below.
  30. salt/cloud/<minion_id>/creating
  31. -------------------------------
  32. This event states simply that the process to create an instance has begun. At
  33. this point in time, no actual work has begun. The payload for this event
  34. includes:
  35. name
  36. profile
  37. provider
  38. salt/cloud/<minion_id>/requesting
  39. ---------------------------------
  40. Salt Cloud is about to make a request to the cloud provider to create an
  41. instance. At this point, all of the variables required to make the request have
  42. been gathered, and the payload of the event will reflect those variables which
  43. do not normally pose a security risk. What is returned here is dependent upon
  44. the cloud provider. Some common variables are:
  45. name
  46. image
  47. size
  48. location
  49. salt/cloud/<minion_id>/querying
  50. -------------------------------
  51. The instance has been successfully requested, but the necessary information to
  52. log into the instance (such as IP address) is not yet available. This event
  53. marks the beginning of the process to wait for this information.
  54. The payload for this event normally only includes the ``instance_id``.
  55. salt/cloud/<minion_id>/waiting_for_ssh
  56. --------------------------------------
  57. The information required to log into the instance has been retrieved, but the
  58. instance is not necessarily ready to be accessed. Following this event, Salt
  59. Cloud will wait for the IP address to respond to a ping, then wait for the
  60. specified port (usually 22) to respond to a connection, and on Linux systems,
  61. for SSH to become available. Salt Cloud will attempt to issue the ``date``
  62. command on the remote system, as a means to check for availability. If no
  63. ``ssh_username`` has been specified, a list of usernames (starting with
  64. ``root``) will be attempted. If one or more usernames was configured for
  65. ``ssh_username``, they will be added to the beginning of the list, in order.
  66. The payload for this event normally only includes the ``ip_address``.
  67. salt/cloud/<minion_id>/deploying
  68. --------------------------------
  69. The necessary port has been detected as available, and now Salt Cloud can log
  70. into the instance, upload any files used for deployment, and run the deploy
  71. script. Once the script has completed, Salt Cloud will log back into the
  72. instance and remove any remaining files.
  73. A number of variables are used to deploy instances, and the majority of these
  74. will be available in the payload. Any keys, passwords or other sensitive data
  75. will be scraped from the payload. Most of the variables returned will be
  76. related to the profile or provider config, and any default values that could
  77. have been changed in the profile or provider, but weren't.
  78. salt/cloud/<minion_id>/created
  79. ------------------------------
  80. The deploy sequence has completed, and the instance is now available, Salted,
  81. and ready for use. This event is the final task for Salt Cloud, before returning
  82. instance information to the user and exiting.
  83. The payload for this event contains little more than the initial ``creating``
  84. event. This event is required in all cloud providers.
  85. Filtering Events
  86. ================
  87. When creating a VM, it is possible with certain tags to filter how much
  88. information is sent to the event bus. The tags that can be filtered on any
  89. provider are:
  90. * ``salt/cloud/<minion_id>/creating``
  91. * ``salt/cloud/<minion_id>/requesting``
  92. * ``salt/cloud/<minion_id>/created``
  93. Other providers may allow other tags to be filtered; when that is the case,
  94. the documentation for that provider will contain more details.
  95. To filter information, create a section in your ``/etc/salt/cloud`` file called
  96. ``filter_events``. Create a section for each tag that you want to filter, using
  97. the last segment of the tag. For instance, use ``creating`` to represent
  98. ``salt/cloud/<minion_id>/creating``:
  99. .. code-block:: yaml
  100. filter_events:
  101. creating:
  102. keys:
  103. - name
  104. - profile
  105. - provider
  106. Any keys listed here will be added to the default keys that are already set to
  107. be displayed for that provider. If you wish to start with a clean slate and
  108. only show the keys specified, add another option called ``use_defaults`` and
  109. set it to ``False``.
  110. .. code-block:: yaml
  111. filter_events:
  112. creating:
  113. keys:
  114. - name
  115. - profile
  116. - provider
  117. use_defaults: False
  118. Configuring the Event Reactor
  119. =============================
  120. The Event Reactor is built into the Salt Master process, and as such is
  121. configured via the master configuration file. Normally this will be a YAML
  122. file located at ``/etc/salt/master``. Additionally, master configuration items
  123. can be stored, in YAML format, inside the ``/etc/salt/master.d/`` directory.
  124. These configuration items may be stored in either location; however, they may
  125. only be stored in one location. For organizational and security purposes, it
  126. may be best to create a single configuration file, which contains only Event
  127. Reactor configuration, at ``/etc/salt/master.d/reactor``.
  128. The Event Reactor uses a top-level configuration item called ``reactor``. This
  129. block contains a list of tags to be watched for, each of which also includes a
  130. list of ``sls`` files. For instance:
  131. .. code-block:: yaml
  132. reactor:
  133. - 'salt/minion/*/start':
  134. - '/srv/reactor/custom-reactor.sls'
  135. - 'salt/cloud/*/created':
  136. - '/srv/reactor/cloud-alert.sls'
  137. - 'salt/cloud/*/destroyed':
  138. - '/srv/reactor/cloud-destroy-alert.sls'
  139. The above configuration configures reactors for three different tags: one which
  140. is fired when a minion process has started and is available to receive commands,
  141. one which is fired when a cloud instance has been created, and one which is
  142. fired when a cloud instance is destroyed.
  143. Note that each tag contains a wildcard (``*``) in it. For each of these tags,
  144. this will normally refer to a ``minion_id``. This is not required of event tags,
  145. but is very common.
  146. Reactor SLS Files
  147. =================
  148. Reactor ``sls`` files should be placed in the ``/srv/reactor/`` directory for
  149. consistency between environments, but this is not currently enforced by Salt.
  150. Reactor ``sls`` files follow a similar format to other ``sls`` files in
  151. Salt. By default they are written in YAML and can be templated using Jinja, but
  152. since they are processed through Salt's rendering system, any available
  153. renderer (JSON, Mako, Cheetah, etc.) can be used.
  154. As with other ``sls`` files, each stanza will start with a declaration ID,
  155. followed by the function to run, and then any arguments for that function. For
  156. example:
  157. .. code-block:: yaml
  158. # /srv/reactor/cloud-alert.sls
  159. new_instance_alert:
  160. cmd.pagerduty.create_event:
  161. - tgt: alertserver
  162. - kwarg:
  163. description: "New instance: {{ data['name'] }}"
  164. details: "New cloud instance created on {{ data['provider'] }}"
  165. service_key: 1626dead5ecafe46231e968eb1be29c4
  166. profile: my-pagerduty-account
  167. When the Event Reactor receives an event notifying it that a new instance has
  168. been created, this ``sls`` will create a new incident in PagerDuty, using the
  169. configured PagerDuty account.
  170. The declaration ID in this example is ``new_instance_alert``. The function
  171. called is ``cmd.pagerduty.create_event``. The ``cmd`` portion of this function
  172. specifies that an execution module and function will be called, in this case,
  173. the ``pagerduty.create_event`` function.
  174. Because an execution module is specified, a target (``tgt``) must be specified
  175. on which to call the function. In this case, a minion called ``alertserver``
  176. has been used. Any arguments passed through to the function are declared in the
  177. ``kwarg`` block.
  178. Example: Reactor-Based Highstate
  179. ================================
  180. When Salt Cloud creates an instance, by default it will install the Salt Minion
  181. onto the instance, along with any specified minion configuration, and
  182. automatically accept that minion's keys on the master. One of the configuration
  183. options that can be specified is ``startup_states``, which is commonly set to
  184. ``highstate``. This will tell the minion to immediately apply a :ref:`highstate
  185. <running-highstate>`, as soon as it is able to do so.
  186. This can present a problem with some system images on some cloud hosts. For
  187. instance, Salt Cloud can be configured to log in as either the ``root`` user, or
  188. a user with ``sudo`` access. While some hosts commonly use images that
  189. lock out remote ``root`` access and require a user with ``sudo`` privileges to
  190. log in (notably EC2, with their ``ec2-user`` login), most cloud hosts fall
  191. back to ``root`` as the default login on all images, including for operating
  192. systems (such as Ubuntu) which normally disallow remote ``root`` login.
  193. For users of these operating systems, it is understandable that a
  194. :ref:`highstate <running-highstate>` would include configuration to block
  195. remote ``root`` logins again. However, Salt Cloud may not have finished
  196. cleaning up its deployment files by the time the minion process has started,
  197. and kicked off a :ref:`highstate <running-highstate>` run. Users have reported
  198. errors from Salt Cloud getting locked out while trying to clean up after
  199. itself.
  200. The goal of a startup state may be achieved using the Event Reactor. Because a
  201. minion fires an event when it is able to receive commands, this event can
  202. effectively be used inside the reactor system instead. The following will point
  203. the reactor system to the right ``sls`` file:
  204. .. code-block:: yaml
  205. reactor:
  206. - 'salt/cloud/*/created':
  207. - '/srv/reactor/startup_highstate.sls'
  208. And the following ``sls`` file will start a :ref:`highstate
  209. <running-highstate>` run on the target minion:
  210. .. code-block:: yaml
  211. # /srv/reactor/startup_highstate.sls
  212. reactor_highstate:
  213. cmd.state.apply:
  214. - tgt: {{ data['name'] }}
  215. Because this event will not be fired until Salt Cloud has cleaned up after
  216. itself, the :ref:`highstate <running-highstate>` run will not step on
  217. salt-cloud's toes. And because every file on the minion is configurable,
  218. including ``/etc/salt/minion``, the ``startup_states`` can still be configured
  219. for future minion restarts, if desired.