Learn Ansible
上QQ阅读APP看书,第一时间看更新

Ansible

Now, you would have thought that ansible is going to be the most common command we will be using throughout this book, but it isn't.

The ansible command is really only ever used for running ad hoc commands again in a single or collection of hosts. In the last chapter, we created a host inventory file that targeted a single local virtual machine. For this chapter, let's take a look at targeting four different hosts running in DigitalOcean; my hosts file looks as follows:

ansible01 ansible_host=46.101.92.240
ansible02 ansible_host=159.65.63.218
ansible03 ansible_host=159.65.63.217
ansible04 ansible_host=138.68.145.116

[london]
ansible01
ansible02

[nyc]
ansible03
ansible04

[digitalocean:children]
london
nyc

[digitalocean:vars]
ansible_connection=ssh
ansible_user=root
ansible_private_key_file=~/.ssh/id_rsa
host_key_checking=False

As you can see, I have four hosts, ansible01 > ansible04. My first two hosts are in a group called london and my second two are in a group called nyc. I have then taken these two groups and created one containing them called digitalocean, and I have then used this group to apply some basic configuration based on the hosts I have launched.

Using the ping module, I can check connectivity to the hosts by running the following commands:

$ ansible -i hosts london -m ping
$ ansible -i hosts nyc -m ping

As you can see from these results, all four hosts return pong:

I can also target all four hosts at once by using the following:

$ ansible -i hosts all -m ping

Now that we have our host accessible through Ansible, we can target them with some ad hoc commands; let's start with something basic:

$ ansible -i hosts london -a "ping -c 3 google.com"

This command will connect to the london hosts and run the ping -c 3 google.com command; this will ping google.com from the hosts and return the results:

We can also run a single module using the ansible command; we did this in the previous chapter using the setup module. However, a better example would be updating all of the installed packages:

$ ansible -i hosts nyc -m yum -a "name=* state=latest"

In the previous example, we are using the yum module to update all of the installed packages in the nyc group:

As you can see from the screenshot, the output when running Ansible is quite verbose, and it has feedback to tell us exactly what it has done during the ad hoc execution. Let's run the command again against all of our hosts, but this time just for a single package, say kpartx:

$ ansible -i hosts all -m yum -a "name=kpartx state=latest"

The Terminal output gives you a better idea of the information being returned by each host as the command is executed on it:

As you can see, the two hosts in the nyc group, while returning a SUCCESS status, are showing no changes; the two hosts in the london group again show a SUCCESS status but show changes.

So why would you want to do this and what is the difference between the two commands we ran?

First of all, let's take a look at two of the commands:

$ ansible -i hosts london -a "ping -c 3 google.com"
$ ansible -i hosts london -m yum -a "name=* state=latest"

While it appears that the first command isn't running a module, it is. The default module for the ansible command is called raw and it just runs raw commands on each of the targeted hosts. The -a part of the command is passing arguments to the module. The raw module just happens to accept raw commands, which is exactly what we are doing with the second command.

You may have noticed that the syntax is slightly different to when we pass commands to the ansible command, and when using it as part of a YAML playbook. All we are doing here is passing the key-value pairs directly to the module.

So why would you want to use Ansible like this? Well, it's great for running commands directly against non-Ansible managed hosts in an extremely controlled way. Ansible just SSHs in, runs the command, and lets you know the results. Just be careful, as it is very easy to get overconfident and run something like the following:

$ ansible -i hosts all -a "reboot now"

If Ansible has permissions to execute the command, then it will do. Running the previous command will reboot all the servers in the host inventory file:

Note that all of the hosts have a status of UNREACHABLE because the reboot command kicked our SSH session before the SUCCESS status could be returned. You can, however, see that each of the hosts has been rebooted by running the uptime command:

$ ansible -i hosts all -a "uptime"

The following screenshot shows the output for the preceding command:

As mentioned, be extremely careful when using Ansible to manage hosts using ad hoc commands.