1.. _grains: 2 3====== 4Grains 5====== 6 7Salt comes with an interface to derive information about the underlying system. 8This is called the grains interface, because it presents salt with grains of 9information. Grains are collected for the operating system, domain name, 10IP address, kernel, OS type, memory, and many other system properties. 11 12The grains interface is made available to Salt modules and components so that 13the right salt minion commands are automatically available on the right 14systems. 15 16Grain data is relatively static, though if system information changes 17(for example, if network settings are changed), or if a new value is assigned 18to a custom grain, grain data is refreshed. 19 20.. note:: 21 22 Grains resolve to lowercase letters. For example, ``FOO``, and ``foo`` 23 target the same grain. 24 25 26Listing Grains 27============== 28 29Available grains can be listed by using the 'grains.ls' module: 30 31.. code-block:: bash 32 33 salt '*' grains.ls 34 35Grains data can be listed by using the 'grains.items' module: 36 37.. code-block:: bash 38 39 salt '*' grains.items 40 41 42.. _static-custom-grains: 43 44Using grains in a state 45======================= 46 47To use a grain in a state you can access it via `{{ grains['key'] }}`. 48 49Grains in the Minion Config 50=========================== 51 52Grains can also be statically assigned within the minion configuration file. 53Just add the option :conf_minion:`grains` and pass options to it: 54 55.. code-block:: yaml 56 57 grains: 58 roles: 59 - webserver 60 - memcache 61 deployment: datacenter4 62 cabinet: 13 63 cab_u: 14-15 64 65Then status data specific to your servers can be retrieved via Salt, or used 66inside of the State system for matching. It also makes it possible to target based on specific data about your deployment, as in the example above. 67 68 69Grains in /etc/salt/grains 70========================== 71 72If you do not want to place your custom static grains in the minion config 73file, you can also put them in ``/etc/salt/grains`` on the minion. They are configured in the 74same way as in the above example, only without a top-level ``grains:`` key: 75 76.. code-block:: yaml 77 78 roles: 79 - webserver 80 - memcache 81 deployment: datacenter4 82 cabinet: 13 83 cab_u: 14-15 84 85.. note:: 86 87 Grains in ``/etc/salt/grains`` are ignored if you specify the same grains in the minion config. 88 89.. note:: 90 91 Grains are static, and since they are not often changed, they will need a grains refresh when they are updated. You can do this by calling: ``salt minion saltutil.refresh_modules`` 92 93.. note:: 94 95 You can equally configure static grains for Proxy Minions. 96 As multiple Proxy Minion processes can run on the same machine, you need 97 to index the files using the Minion ID, under ``/etc/salt/proxy.d/<minion ID>/grains``. 98 For example, the grains for the Proxy Minion ``router1`` can be defined 99 under ``/etc/salt/proxy.d/router1/grains``, while the grains for the 100 Proxy Minion ``switch7`` can be put in ``/etc/salt/proxy.d/switch7/grains``. 101 102Matching Grains in the Top File 103=============================== 104 105With correctly configured grains on the Minion, the :term:`top file <Top File>` used in 106Pillar or during Highstate can be made very efficient. For example, consider 107the following configuration: 108 109.. code-block:: yaml 110 111 'roles:webserver': 112 - match: grain 113 - state0 114 115 'roles:memcache': 116 - match: grain 117 - state1 118 - state2 119 120For this example to work, you would need to have defined the grain 121``role`` for the minions you wish to match. 122 123.. _writing-grains: 124 125Writing Grains 126============== 127 128.. include:: ../../_incl/grains_passwords.rst 129 130The grains are derived by executing all of the "public" functions (i.e. those 131which do not begin with an underscore) found in the modules located in the 132Salt's core grains code, followed by those in any custom grains modules. The 133functions in a grains module must return a :ref:`Python dictionary 134<python:typesmapping>`, where the dictionary keys are the names of grains, and 135each key's value is that value for that grain. 136 137Custom grains modules should be placed in a subdirectory named ``_grains`` 138located under the :conf_master:`file_roots` specified by the master config 139file. The default path would be ``/srv/salt/_grains``. Custom grains modules 140will be distributed to the minions when :mod:`state.highstate 141<salt.modules.state.highstate>` is run, or by executing the 142:mod:`saltutil.sync_grains <salt.modules.saltutil.sync_grains>` or 143:mod:`saltutil.sync_all <salt.modules.saltutil.sync_all>` functions. 144 145Grains modules are easy to write, and (as noted above) only need to return a 146dictionary. For example: 147 148.. code-block:: python 149 150 def yourfunction(): 151 # initialize a grains dictionary 152 grains = {} 153 # Some code for logic that sets grains like 154 grains["yourcustomgrain"] = True 155 grains["anothergrain"] = "somevalue" 156 return grains 157 158The name of the function does not matter and will not factor into the grains 159data at all; only the keys/values returned become part of the grains. 160 161When to Use a Custom Grain 162-------------------------- 163 164Before adding new grains, consider what the data is and remember that grains 165should (for the most part) be static data. 166 167If the data is something that is likely to change, consider using :ref:`Pillar 168<pillar>` or an execution module instead. If it's a simple set of 169key/value pairs, pillar is a good match. If compiling the information requires 170that system commands be run, then putting this information in an execution 171module is likely a better idea. 172 173Good candidates for grains are data that is useful for targeting minions in the 174:ref:`top file <states-top>` or the Salt CLI. The name and data structure of 175the grain should be designed to support many platforms, operating systems or 176applications. Also, keep in mind that Jinja templating in Salt supports 177referencing pillar data as well as invoking functions from execution modules, 178so there's no need to place information in grains to make it available to Jinja 179templates. For example: 180 181.. code-block:: text 182 183 ... 184 ... 185 {{ salt['module.function_name']('argument_1', 'argument_2') }} 186 {{ pillar['my_pillar_key'] }} 187 ... 188 ... 189 190.. warning:: 191 192 Custom grains will not be available in the top file until after the first 193 :ref:`highstate <running-highstate>`. To make custom grains available on a 194 minion's first highstate, it is recommended to use :ref:`this example 195 <minion-start-reactor>` to ensure that the custom grains are synced when 196 the minion starts. 197 198Loading Custom Grains 199--------------------- 200 201If you have multiple functions specifying grains that are called from a ``main`` 202function, be sure to prepend grain function names with an underscore. This prevents 203Salt from including the loaded grains from the grain functions in the final 204grain data structure. For example, consider this custom grain file: 205 206.. code-block:: python 207 208 #!/usr/bin/env python 209 def _my_custom_grain(): 210 my_grain = {"foo": "bar", "hello": "world"} 211 return my_grain 212 213 214 def main(): 215 # initialize a grains dictionary 216 grains = {} 217 grains["my_grains"] = _my_custom_grain() 218 return grains 219 220The output of this example renders like so: 221 222.. code-block:: console 223 224 # salt-call --local grains.items 225 local: 226 ---------- 227 <Snipped for brevity> 228 my_grains: 229 ---------- 230 foo: 231 bar 232 hello: 233 world 234 235However, if you don't prepend the ``my_custom_grain`` function with an underscore, 236the function will be rendered twice by Salt in the items output: once for the 237``my_custom_grain`` call itself, and again when it is called in the ``main`` 238function: 239 240.. code-block:: console 241 242 # salt-call --local grains.items 243 local: 244 ---------- 245 <Snipped for brevity> 246 foo: 247 bar 248 <Snipped for brevity> 249 hello: 250 world 251 <Snipped for brevity> 252 my_grains: 253 ---------- 254 foo: 255 bar 256 hello: 257 world 258 259 260Precedence 261========== 262 263Core grains can be overridden by custom grains. As there are several ways of 264defining custom grains, there is an order of precedence which should be kept in 265mind when defining them. The order of evaluation is as follows: 266 2671. Core grains. 2682. Custom grains in ``/etc/salt/grains``. 2693. Custom grains in ``/etc/salt/minion``. 2704. Custom grain modules in ``_grains`` directory, synced to minions. 271 272Each successive evaluation overrides the previous ones, so any grains defined 273by custom grains modules synced to minions that have the same name as a core 274grain will override that core grain. Similarly, grains from 275``/etc/salt/minion`` override both core grains and custom grain modules, and 276grains in ``_grains`` will override *any* grains of the same name. 277 278For custom grains, if the function takes an argument ``grains``, then the 279previously rendered grains will be passed in. Because the rest of the grains 280could be rendered in any order, the only grains that can be relied upon to be 281passed in are ``core`` grains. This was added in the 2019.2.0 release. 282 283 284Examples of Grains 285================== 286 287The core module in the grains package is where the main grains are loaded by 288the Salt minion and provides the principal example of how to write grains: 289 290:blob:`salt/grains/core.py` 291 292 293Syncing Grains 294============== 295 296Syncing grains can be done a number of ways. They are automatically synced when 297:mod:`state.highstate <salt.modules.state.highstate>` is called, or (as noted 298above) the grains can be manually synced and reloaded by calling the 299:mod:`saltutil.sync_grains <salt.modules.saltutil.sync_grains>` or 300:mod:`saltutil.sync_all <salt.modules.saltutil.sync_all>` functions. 301 302.. note:: 303 304 When the :conf_minion:`grains_cache` is set to False, the grains dictionary is built 305 and stored in memory on the minion. Every time the minion restarts or 306 ``saltutil.refresh_grains`` is run, the grain dictionary is rebuilt from scratch. 307