Ansible ad hoc commands, unlike playbooks, are used to quickly check or change the configuration of managed host(s). The basic feature of ad hoc commands is their stateless nature, in other words, ad hoc commands are not stored anywhere. Once they are executed, record does not remain, but changes are made. The commands are executed in one or more lines, for example if you want to check if a particular text exists in a file, restart the service and many more. One useful example is if you want to check the status of a managed node after the playbook made changes. If you don’t need a write a playbook but quick fix or change, ad hoc commands are the right choice.

Ad hoc commands syntax

ansible host (s) –m module [-a ‘module arguments’] [-i inventory]

host (s) – a list of managed nodes on which we want to execute an ansible ad hoc command(s)

-m module – the module we want to use. Modules are predefined programs written in Python that are used to perform specific tasks (listinffile, ping, copy…)

-a – command arguments (for example -> command has argument ‘cat /etc/motd’)

– i inventory (inventory file which contains a list of managed nodes)

Ansible ad hoc ping

With ansible-doc –l command, we can see a list of all available modules available. At the time of writing, the number of modules was 2834:

[automation @ ansiblewks plays] $ ansible-doc -l | wc -l

One of the most basic modules used in ansible ad hoc commands is the ping module. Module ping is not used as classic ping which sends ICMP request to see if nodes are responsive over network, but to check that managed nodes are ready to execute ansible commands:

[automation@ansiblewks plays]$ ansible all -m ping | SUCCESS => {
“ansible_facts”: {
“discovered_interpreter_python”: “/usr/bin/python”
“changed”: false,
“ping”: “pong”

In this example, we tested whether managed node is Ansible compatible. Remember, only requirement for Ansible compatibility is Python and enabled SSH session. Detailed information about the ping module cab be checked with following command:

# ansible-doc ping

Windows machines use win_ping and net_ping modules is used by network devices.

Ansible ad hoc command examples

Most common modules used for file and directory management are:

  • Lineinfile (module that checks if a particular line is in a file, modifies or adds a new line )
  • File (this module sets rights to files and directories)
  • Copy (copies files from local machine to specific managed nodes)

EXAMPLE: Ansible Copy Module

Lets check simple example of copying an ntpf configuration file from localhost to a managed node. For simplicity, the ntp configuration file contains only one line: server

Current ntp configuration on test1lab1 is::
[root@testlab1 ~]# less /etc/ntp.con

# For more information about this file, see the man pages
# ntp.conf(5), ntp_acc(5), ntp_auth(5), ntp_clock(5), ntp_misc(5), ntp_mon(5).

driftfile /var/lib/ntp/drift

# Permit time synchronization with our time source, but do not
# permit the source to query or modify the service on this system.
restrict default nomodify notrap nopeer noquery

Run the Ansible ad hoc command that uses the copy module:

[automation@ansiblewks plays]$ ansible -m copy -a ‘src=/tmp/ntp.conf dest=/etc/ntp.conf owner=root group=root mode=0644’ | CHANGED => {
“ansible_facts”: {
“discovered_interpreter_python”: “/usr/bin/python”
“changed”: true,
“checksum”: “73784288c77fcc4cb44329f52d3c2a00403f14e9”,
“dest”: “/etc/ntp.conf”,
“gid”: 0,
“group”: “root”,
“md5sum”: “3334c41489188e0ef348af49a05bc24d”,
“mode”: “0644”,
“owner”: “root”,
“size”: 15,
“src”: “/home/automation/.ansible/tmp/ansible-tmp-1569134027.79-205517632043990/source”,
“state”: “file”,
“uid”: 0
Lets check the command details:

ansible -m copy -a ‘src=/tmp/ntp.conf dest=/etc/ntp.conf owner=root group=root mode=0644’

The script starts with the keyword ansible and the name of the server to which we want to copy the file. Power of ansible lies pushing configuration to more than one server, but we are using only one just for simplicity. We need switch – m to specify the name of the module used, which in our case is copy module. Module parameters are set via the switch –a:

src – source (where the file is copied from, our example – local computer where we run ansible)
dest – destination (destination managed node, our example
owner, group (owner of destination file, our example root for user and group)
mode – (file permissions, our example – 0644)

After ansible does its job result is:

[root@testlab1 ~]# less /etc/ntp.conf

Modules used for package management are:

Yum (yum command line package manager)
Apt (apt command line package manager)
Pip (package manager for managing python packages)
Package (Generic OS package manager, manages packages using the corresponding Guest OS package manager)

Example: Ansible yum module

Simple example of zip package installation:

[automation@ansiblewks plays]$ ansible -m yum -a ‘name=zip state=present’ | CHANGED => {
“ansible_facts”: {
“discovered_interpreter_python”: “/usr/bin/python”
“changed”: true,
“changes”: {
“installed”: [
“msg”: “”,
“rc”: 0,
“results”: [
“Loaded plugins: enabled_repos_upload, package_upload, product-id, search-\n : disabled-repos, subscription-manager\nResolving Dependencies\n–> Running transaction check\n—> Package zip.x86_64 0:3.0-11.el7 will be installed\n–> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n zip x86_64 3.0-11.el7 rhel-7-server-rpms 260 k\n\nTransaction Summary\n================================================================================\nInstall 1 Package\n\nTotal download size: 260 k\nInstalled size: 796 k\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : zip-3.0-11.el7.x86_64 1/1 \nUploading Package Profile\n Verifying : zip-3.0-11.el7.x86_64 1/1 \n\nInstalled:\n zip.x86_64 0:3.0-11.el7 \n\nComplete!\nUploading Enabled Repositories Report\nLoaded plugins: product-id, subscription-manager\n”

Ansible ad hoc command in details:

ansible -m yum -a ‘name=zip state=present’

The script starts with the keyword ansible and the name of the server to which we want to install the zip package. Switch – we need to specify the name of the module used, which in this case is yum. Module parameters are set via the switch –a:
name – package name, our example – zip
state – desired state (present,absent,latest), our example – present

Common modules for system management are:

User (modifying, adding and deleting a user)
Service (modifying, adding and deleting services)
Firewalld (firewall configuration of ports and services)

Example: Ansible user module

User module that creates a user john that belongs to the wheel group.[automation@ansiblewks plays]$ ansible -m user -a ‘name=john group=wheel’ | CHANGED => {
“ansible_facts”: {
“discovered_interpreter_python”: “/usr/bin/python”
“changed”: true,
“comment”: “”,
“create_home”: true,
“group”: 10,
“home”: “/home/john”,
“name”: “john”,
“shell”: “/bin/bash”,
“state”: “present”,
“system”: false,
“uid”: 2028

Ansible ad hoc command in details:

ansible -m yum -a ‘name = zip state = present’

The script starts with the keyword ansible and the name of the server to which we want to create the user. Switch – m we need to specify the name of the module used, which in this case is user. Module parameters are set via the switch –a:

name – user, in our case john
group – user group, our example – interface

Result of the Ansible ad hoc command:

[root@testlab1 ~]# id john
uid=2028(john) gid=10(wheel) groups=10(wheel)