In our previous article we discussed what is ansible inventory and configuration file which lays the foundation for learning ansible. In this article, we are going to discuss ansible ad hoc commands with some examples.
Introduction
Ansible Ad hoc commands are great if you want to perform quick tasks and tasks that are not often repeated. Usually, these ad hoc commands are one-liner commands that you can run directly from the terminal or from the shell script.
Before you learn how to work with ad hoc commands, you need to know what idempotent is. Ansible is idempotent in nature, meaning no matter how many times you run the same task if an object state has already changed, ansible won’t try to make the same changes to that object again.
Ad hoc commands are sent via /usr/bin/ansible
program. You can run the following command to get the list of supported options for the ansible command.
$ ansible --help
If you don’t have an ansible lab to practice with, you can check out our guide on how to manually set up ansible and use Vagrant and Virtualbox.
Get to know the target
Before you get started with ad hoc assignments or script writing, you should have a clear understanding of the business requirements and the target environment you will be working with.
The target environment can be anything such as servers, network devices, containers, cloud solutions, etc. that ansible supports. Here I am using two managed nodes with Ubuntu 20.04.
You can run the following command to check the list of hosts used when you run an ad hoc command or playbook.
#SYNTAX $ ansible --list-hosts
Group name can be standard-IallI ungrouped) or user-defined groupsI
If you want to know more about groups, check out the following link.
Download the list of hosts for all groups.
$ ansible all --list-hosts hosts (2): managed1.anslab.com managed2.anslab.com
Get a list of hosts for the user-defined group. Here is my group name ubuntuI
$ ansible ubuntu --list-hosts hosts (2): managed1.anslab.com managed2.anslab.com
Inventory File
The inventory file contains the list of managed nodes. The location of the inventory file is configured in the ansible.cfg
File. You can override the location of the inventory file with the -i
or --inventory
flag when running ad hoc commands.
I have two inventory files and the default file is called hosts. To use the host2 file, I have the . usage -i
flag and pass the file as an argument.
$ ansible all -i host2 --list-hosts hosts (1): managed2.anslab.com
NB: If the inventory file is in a different location, you must specify the absolute path. You can refer to the following link to know the priority order for the inventory file.
Ansible modules
Ansible is a tool that comes with a battery, which means that numerous modules come with it. Modules are programs written in Python which is used by ansible to run on the managed nodes to perform a task. Ansible follows the plug-and-play approach, which means you can write your own module and run it through ansible.
Ansible supports many packages created by the open source community and various product vendors. Run the following command to get the list of all modules installed on your computer.
$ ansible-doc -l # LIST ALL MODULES AVAILABLE $ ansible-doc -l | grep -i -w ^apt # GREP PARTICULAR MODULE(APT) MODULE
To view the documentation for a module, you can run the following command. Here I am reviewing the documentation for the apt module, the package management module for Debian/Ubuntu based distributions.
$ ansible-doc apt
The image below shows the documentation for the ansible apt module.
Ad Hoc Command Syntax
There are a few inputs you need to enter when running the ad hoc command.
- You must specify the targets (managed nodes). You can use the default “all/ungrouped” groups or user-defined groups.
- You must pass the module name as an argument to the
-m
flag. - Each module accepts a range of options. Those options must be passed as arguments to -a flag. If there are multiple options, they must be enclosed in quotes.
$ ansible [group] -m [module] -a [module arguments]
You can combine other arguments we saw in the previous sections into ad hoc commands.
Check connectivity with the Ping module
The first module you run after setting up ansible is the “ping” module. The ping module is used to verify that connectivity is good with the controller and managed nodes. If the connection is successful, you will get a response like: “ping: pong”I
$ ansible all -m ping

You can also condense the output using the -o
flag.
$ ansible all -m ping -o

Execute commands via Shell module
The shell module is used to run any command you can run through the terminal. It’s just like running the commands through a Linux terminal.
You should use the -a
mark and pass commands as arguments to the shell module.
$ ansible all -m shell -a "arguments"
Below are some of the commands I ran through the ansible shell module.
$ ansible all -m shell -a "echo $USER"
$ ansible all -m shell -a "uptime"
$ ansible all -m shell -a "cat /etc/os-release | grep -i PRETTY_NAME"
$ ansible all -m shell -a "touch /tmp/abc.txt"
$ ansible all -m shell -a "ls -l /tmp/abc.txt"

As an alternative to the shell module, you can also use the command module, which is the default module in ansible. You can directly use the -a
mark and pass commands as the argument, since the command module is the default module.
$ ansible all -m command -a "uptime" # EXCLUSIVELY PASSING COMMAND MODULE $ ansible all -a "uptime" # NOT USING -m TO PASS MODULE

The difference between shell and command module is that with command module you can access some special variables and cannot use pipes, redirects and logical AND operators.
Run the following command and you will get an error message.
$ ansible all -m command -a "test -f /etc/hosts && echo 'hosts file present'"
You can run the same command through the shell module and it will work just fine.
$ ansible all -m shell -a "test -f /etc/hosts && echo 'hosts file present'"

Run scripts through the script module
If you want to run a script (python, shell, etc.), you can use the script module which copies the script from your controller machine to all managed nodes and then runs the script.
I have the following python code in my /tmp
folder.
import sys,os print("CURRENT PYTHON VERSION = ", sys.version_info) print("HOSTNAME = ", os.uname()[1]) print("CURRENT DIRECTORY = ", os.getcwd())
Run the following command to use the script module to run the script. The script module supports additional arguments depending on how you run your script. In my case I’m running a python script so I’m trying to pass the extra argument “executable = python3” along with the script path.
$ ansible all -m script -a "/tmp/get_host_details.py executable=python3"

Package management modules
There are modules to work with OS package managers, such as: dnf
I apt
I pacman
etc. Here I use apt
since I’m using Ubuntu. But the syntax will be the same for all package managers with parameter differences. Please refer to the respective documentation to know more about it.
To install packages, you can run the following command and set the status to: “Gift”† You have to choose -b
or -become
flag to run the module with sudo
privileges in the managed nodes. If you have set the password for the sudo user, you must pass -K
together with the -b
flag that will ask for the become password.
$ ansible all -m apt -a "name=cowsay,vim,cmatrix state=present" -b -K

Check out our article at the link below to learn how privilege escalation works.
To remove the packages, you can run the following command and set the status to: “absent”I
$ ansible all -m apt -a "name=cowsay,vim,cmatrix state=absent" -b -K

So far I have shown how different modules can be used for different tasks. This may have given you a good understanding of how things work when you run ad hoc commands.
There are countless other modules and this article will not be enough to cover them all. So I recommend that you choose the module according to your usage scenario and start practicing with the ad hoc commands.
output colors
When you run ad hoc commands, you should have seen the output in three different colors. Every color has a meaning.
RED - Failure YELLOW - Success With Changes happened GREEN - Success but no changes happened
RED – Failed
If your job failed, it will print in red color.

YELLOW – Good luck with changes
When the status is set to change, the output is yellow in color.

GREEN – Good luck but no changes
If the object status is not changed, the output is green.

Conclusion
In this article, we discussed what ad hoc commands are and how to use ad hoc commands in Ansible. As a beginner, ad hoc commands will give you an understanding of how ansible uses modules to perform a task. At the next level, you start writing playbooks in YAML format, which are covered in detail in a separate article.
sources: