reactor.rst 11 KB

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