Welcome back. Today we will cover Host and Group variables, followed by modules. I originally planned to cover plays in this section, but realized it makes more sense to cover when we cover playbooks (part 5).
Sometimes you need to store additional information associated with a host or a group. Ansible supports this through variables (referred to as vars in the Ansible documentation). Let’s take a look at some host variable examples.
In the above example, we’ve assigned a variable named
sql_port to the host sql1.softwarecorp.com with a value of
8888 and a variable of the same name to devsql1.softwarecorp.com with a value of
1433. While this can be useful, it’s more likely that you will be setting variables at a group level instead on individual hosts.
In the above example, we set 3 variables (
http_port, proxy and maxRequestPerChild) on the
prodapp_server group. These variables are applied to each host that is part of the
prodapp_server group. There are a few rules around variables to keep in mind. First we’ll look at variables precedence is handled.
Variables have an order of precedence, with host variables having the highest precedence. Group precedence lowers as you move further from the host, so a variable defined on the host appserver1.softwarecorp.com would override the value set on the
production_servers group, but would not override a variable set on the
appserver group. The next rule is how variables work when hosts are in multiple groups.
Hosts in multiple groups will have their variables merged together, so in the above example appserver1.softwarecorp.com will have proxy and port variables.
Ansible will allow you to define group and host variables in their own file or files in addition to setting them in the inventory file. These files can have no extension or end in ‘.yml’, ‘.yaml’, or ‘.json’. Assuming you have an inventory path (an ansible configuration we will cover in a later part) of
/etc/ansible/hosts you can create host and group variable files in directories as follows.
Ansible will apply all variables defined in the directory (matching the above schema)
/etc/ansible/host_vars/appserver1.softwarecorp.com to the host appserver1.softwarecorp.com and
/wtc/ansible/group_vars/all to all members of the production_server group (and child groups). Note that we’ve used the special all group covered in the previous post to assign variables to all hosts.
Lastly, we still need to know how to define variables within these files. Fortunately for us, this process is pretty straightforward.
As you can see it’s simply a key value pair separated by a colon (:) and a space. The three dashes (—) indicate a comment and are ignored by Ansible.
Modules are the core working component of Ansible. Modules are commands that perform some operation and can return information or data. There’s a extensive library of existing modules. Ansible has modules for managing networks, windows, cloud resources(AWS, Azure, etc), source control and more. You can find a full listing in the Module Index Should you need a module that doesn’t exist, you can create your own using powershell or python. We will cover this in Building modules (Part 11).
Modules can be called as part of a play (covered below) or ad-hoc via the shell. For these examples, we are going to assume we have the inventory file from the last post. Lets take a look at 3 examples of ad-hoc ansible commands.
Well that’s pretty simple, but lets review. The first command is passing the argument all. This tells ansible to run the module against
all hosts in our inventory file (This is the special all group covered in the previous post). In the second example, we are passing
webservers and in the third example we are passing both
devapp_server. Ansible will use the host defined in these groups to run the command against. Next we pass
-m followed by the module name (in this example the module is ping). I bet some of you noticed that in the second and third examples,
-m was omitted. This is because modules that take no parameters do not require
-m. Let move to something more complex.
Now this is a bit more complex. It should be clear by now, but
devwebservers is telling ansible to use the
devwebservers group in our inventory file. You’ll notice that we do not have a
-m or a module. When this is omitted, Ansible will use the command module by default. Next we pass
-a followed by
'/sbin/reboot'. This is passing the argument to the command module. This will run the command
/sbin/reboot on each host in the
devwebservers group. Next up is
-f which specifies that we want to run this command in 10 parallel forks. Now that’s a pretty useful parameter if you need a nightly/weekly system reboot against a large number of machines. Since this is clearly not a windows command, it would fail if we had a windows machine in our inventory list. Lets move on to another example.
Now this is a favorite of mine. Lets break it down. We are targeting
all servers in our inventory file running the module [![win_chocolatey] (http://docs.ansible.com/ansible/latest/win_chocolatey_module.html)]. Next we have
-e. This allows up to specific variables in a key/value or YAML/JSON format for use by the module. In this example, we are telling the
win_chocolatey module we want the state to be the latest (which will attempt to update all chocolatey installs).
You can also get documentation on a specific module by using the ansible-doc command. Let look at what we get if we user the
Now this tells us a lot of information about what parameters can be used and some example of calling the module.
Next time we’ll be installing Ansible and creating a couple machines for testing