Basic Ad hoc commands on Ansible
When automating or orchestrating tasks, Ansible is mainly used with playbooks to allow subtasks to be scripted and organized in a handy pipeline. However, Ansible also has various ad hoc commands. These allow the execution of a module on a host, or group of hosts, no matter how they are identified.
Once Ansible is installed, the ad hoc command line can be used directly. It can be easily tested, either by using it with the raw module or with some simple modules, such as ping or shell. As a quick example, each Ansible instance can ping itself using the following command:
ansible localhost -m ping
We should see the following output:
Some could question the Ansible ad hoc commands usefulness. They are actually a great way to test your tasks in depth, thereby making it easier to debug step-by-step smaller bits of a bigger task and capture the error location or troubleshoot slow requests. For beginners, running simple commands may help to master the basic operation of the tool by solving simpler tasks and going up a notch until you reach more complex tasks—it's better to learn how to walk before you start running.
The most common use for Ansible ad hoc commands is to run raw commands. A raw command is basically any line of Bash or PowerShell code to be sent to the host or hosts as is:
ansible localhost -a "echo 'Hello automated World'"
Something like the following output will appear after executing the command:
Let's try to run a command on a different host. For this, we need the host's IP address or a fully qualified hostname, and a user where we can copy the SSH key. This can be done by physically copying the key to the user's ~/.ssh folder, or it can be done using the ssh-copyid command mentioned in Chapter 2, Ansible Setup and Configuration. After that, we run the following raw command to get information about the host:
ansible 192.168.10.10 -a "uname -a" -u setup
This ad hoc command will produce an output as follows:
Alternatively, we can try and make the host perform an elevated task that requires superuser privileges:
ansible 192.168.10.10 -a "apt update" -u setup --become
This is what the output should look like when executing the preceding command:
If we use this command without the --become option, it will fail with a permission denied error message:
This same task can be performed using Ansible modules. To do so, we use the -m option, followed by the name of the module and its arguments after the -a option, as shown in the following example:
ansible 192.168.10.10 -m apt -a "update_cache=yes" -u setup --become
Ansible also allows you to run tasks as another user by using the --become option to elevate the current user to a superuser, then selecting which user to use to run the command. It can also be done using the -e option and defining the variables in its input. The two commands are as follows:
ansible 192.168.10.10 -a "whoami" -u setup --become --become-user user1
ansible 192.168.10.10 -a "whoami" -u setup -e "ansible_user=user1 become=true"
This is what the output should look like when executing the preceding playbook:
The ad hoc commands can also be used for a quick file transfer to multiple machines. We can either use a raw command, relying on scp or rsync, or we can also use the Ansible copy module. To be able to perform tasks on multiple hosts, we recommend using a quick static inventory. This can be done by adding a few lines to the /etc/ansible/hosts file or any other location that the Ansible configuration file points to. The file should look as follows:
[servers]
192.168.10.10
192.168.10.11
192.168.10.12
Grouping the three hosts under the servers name allows us to run tasks on all three hosts just by calling their group name. This is shown in the following example:
ansible servers -m copy -a "src=/home/user/file.txt dest=/home/setup/file.txt" -u setup
Some tasks are so simple that writing a playbook to achieve them is a huge waste of time. Also, any Ansible ad hoc command can be made into a playbook—an Ansible user could always try some of the commands and verify their parameters, before adding them to the playbook pipeline or workflow. This is a great way of troubleshooting and applying a quick update or fix on the fly. The following example shows how we can restart a replicate of web servers one at a time by setting the number of forks to one (with the -f option). This applies the restart command host by host:
ansible servers -m service -a "name=httpd state=restarted" -u setup –become -f 1