In this article with a handful of examples I will demonstrate the power of Ansible's ad hoc commands which can be used to do a lot of stuff with just a single command on remote servers.
Prerequisites
One Ansible Control Node The Ansible control or mater node will be the machine we will use to connect to and control the Ansible hosts over SSH.
One or more Linux client nodes
The Ansible control node will be performing configuration management tasks on Linux client nodes.
SSH connection SSH connection should be enabled between Ansible control node and the remote client servers. Assuming either the Ansible control node’s SSH public key added to the
authorized_keys
of a system user or use the root or sudo user's password to connect.
My Environment
Hostname | IP address | Operating System |
lco-ansible-master.example.com | 172.52.52.200 | CentOS Linux 7 (Core) |
lco-worker1.example.com | 172.52.52.201 | CentOS Linux 7 (Core) |
lco-worker2.example.com | 172.52.52.202 | CentOS Linux 7 (Core) |
Need of Ansible Ad hoc commands
Ad hoc commands are used to automate a single task on one or more client nodes. They are used to perform quick functions but are not repeatable.
For example if you want to power off a set of machines or if you want to make a service down on some hosts within your cluster you can use Ansible ad hoc commands and do that pretty quickly.
Test the connection
Before I start demonstrating the ad hoc commands example let us fist test our connection with Ansible client nodes.
My inventory file:
[ansible_user@lco-ansible-master ansible]$ cat myinventory
master ansible_host=lco-ansible-master.example.com ansible_user=ansible_user ansible_ssh_port=22
worker1 ansible_host=lco-worker1.example.com ansible_user=ansible_user ansible_ssh_port=22
worker2 ansible_host=lco-worker2.example.com ansible_user=ansible_user ansible_ssh_port=22
[master]
master
[workers]
worker1
worker2
Here we are using ansible_user
which has sudo
privileges to perform the administrative tasks on client nodes.
We can use
ansible_ssh_private_key_file
variable within inventory file if we wish to chose the custom private key file.For example: master ansible_host=lco-ansible-master.example.com ansible_user=ansible_user ansible_ssh_port=22 ansible_ssh_private_key_file=/home/ansible_user/.ssh/custom_id_file
Test the connection:
[ansible_user@lco-ansible-master ansible]$ ansible -m ping all -i myinventory
[WARNING]: Found both group and host with same name: master
master | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
worker1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
worker2 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
Great! we are all set to perform some brilliant and quick stuff on our client nodes.
Ansible Ad hoc command examples
In this section we will take different examples of Ansible ad hoc commands to perform various things on remote servers.
Reboot client nodes
Many tasks on a Linux server including rebooting the servers requires higher privileges. For that we need to use --become
keyword and enter the sudo user password in order to become root. If you add --ask-become-pass
or -K
, Ansible prompts you for the password to use for privilege escalation.
The default module for Ansible command line is
command
module. we can specify module names by using-m
parameter.
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -a "/sbin/reboot" --become -K
The above command will prompt for the sudo user password, once entered correctly will reboot the worker1 node.
You can verify the reboot operation by going to the remote host and run the following command:
[ansible_user@lco-worker1 ~]$ last | grep -i reboot | head -2
reboot system boot 3.10.0-1160.6.1. Sun Jan 3 14:06 - 14:07 (00:01)
reboot system boot 3.10.0-1160.6.1. Sun Jan 3 14:02 - 14:06 (00:03)
Package Management
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory workers -m yum -a "name=vsftpd state=present" --become -K
The above command will install the vsftpd
package on both the worker nodes. We are using the yum
module to install the required package.
I order to remove a package use state=absent
as argument.
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory workers -m yum -a "name=vsftpd state=absent" --become -K
On Debian based distributions for example on Ubuntu etc. we will use
apt
module for package management.
File Operations
In this section we will do perform some file operations on remote hosts.
Change File Permissions
We will use file
module to perform file related operations on client nodes.
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory workers -m file -a "dest=/tmp/test.txt mode=600 owner=ansible_user group=ansible_user" --become -K
Here we have adjusted file permissions on a file named test.txt
which is present at /tmp
on worker nodes.
We have set 600
permissions (giving read
and write
permissions to the owner) on the file using mode
argument. mode
defines the permissions the resulting file or directory should have. We have also set the ownership
and group membership
of the file to ansible_user
using owner
and group
arguments.
Copy files across the remote nodes
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory workers -m copy -a "src=./test_copy dest=/tmp/test_copy"
Verify the file presence on worker nodes:
[root@lco-worker1 tmp]# ls -l test_copy
-rw-rw-r--. 1 ansible_user ansible_user 0 Jan 3 14:34 test_copy
Here we have copied a local file named test_copy
from Ansible control node over to worker nodes using copy
module.
To copy remote server files over control node run following command:
We use the fetch
module in case we want to move files from the remote host to the local host (i.e. fetch a file from the remote host).
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m fetch -a "src=/tmp/test_copy_from_worker1 remote_src=yes dest=/tmp"
Verify the file presence on Ansible control node:
[ansible_user@lco-ansible-master ansible]$ ls -l /tmp/worker1/tmp/test_copy_from_worker1
-rw-rw-r--. 1 ansible_user ansible_user 0 Jan 3 14:54 /tmp/worker1/tmp/test_copy_from_worker1
It creates a directory structure for fetched files.
Create files and directories
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m file -a "path=/tmp/test_file
Above command will create a file named test_file
under /tmp
directory.
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m file -a "path=/tmp/test_dir state=directory"
Above command will create a directory named test_dir
under /tmp
directory.
You can get all the details about any file or directory by running following command:
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m file -a "path=/tmp/test_file"
worker1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"gid": 1001,
"group": "ansible_user",
"mode": "0664",
"owner": "ansible_user",
"path": "/tmp/test_file",
"secontext": "unconfined_u:object_r:user_tmp_t:s0",
"size": 0,
"state": "file",
"uid": 1001
}
Service Management
We use Ansible's service
module to perform service related tasks.
Start a service
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory workers -m service -a "name=vsftpd state=started" --become -K
Restart a service
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory workers -m service -a "name=vsftpd state=restarted" --become -K
Stop a service
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory workers -m service -a "name=vsftpd state=stopped" --become -K
System Information (facts ) gathering
Ansible facts are data related to your remote systems, including operating systems, IP addresses, attached filesystems, and more. By using Ansible's setup
module we can gather remote systems facts variables.
Gather all the facts about a system
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m setup
Filter gathering facts
We get a lot of data as an output of setup
command we ran above but we can always filter the facts output as we require.
For example if we want to know the Python version running on remote host run the following command:
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m setup -a 'filter=ansible_python_version'
worker1 | SUCCESS => {
"ansible_facts": {
"ansible_python_version": "2.7.5",
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
Find the OS family:
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m setup -a 'filter=ansible_os_family'
worker1 | SUCCESS => {
"ansible_facts": {
"ansible_os_family": "RedHat",
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
Find all the details about an network interface:
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m setup -a 'filter=ansible_eth1'
Find memory details on a host:
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m setup -a 'filter=ansible_memory_mb'
worker1 | SUCCESS => {
"ansible_facts": {
"ansible_memory_mb": {
"nocache": {
"free": 1633,
"used": 204
},
"real": {
"free": 1278,
"total": 1837,
"used": 559
},
"swap": {
"cached": 0,
"free": 2047,
"total": 2047,
"used": 0
}
},
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}
User Management
We use Ansible's user
module to perform user management tasks.
Create a user
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory workers -m user -a "name=test" --become -K
Add user to a group
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory workers -m user -a "name=test append=yes group=wheel" --become -K
Here we are adding user test
to wheel
group. If you notice we've used append
flag and set it to yes
because if not set to yes
it will wipe out the details of previous groups for that user.
Remove a user
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory workers -m user -a "name=test state=absent" --become -K
To remove a user, we use state
flag and set it to absent
as above.
Find Disk Usage on remote host
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -a "df -hT"
worker1 | CHANGED | rc=0 >>
Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 908M 0 908M 0% /dev
tmpfs tmpfs 919M 0 919M 0% /dev/shm
/dev/mapper/centos-root xfs 41G 1.6G 40G 4% /
/dev/sda1 xfs 1014M 253M 762M 25% /boot
/dev/mapper/centos-home xfs 20G 33M 20G 1% /home
Find high CPU consuming processes
The following command will list down the processes with higher cpu
consumption.
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m shell -a "ps -eo pid,ppid,%mem,%cpu,cmd --sort=-%cpu | head"
Here we have used Ansible's shell
module.
To know about the highest cpu consuming processes you can use top
command as well.
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m shell -a "top -c -b | head -15"
Ansible
command
module does not support the pipe character and does not support redirection
Find high Memory consuming processes
The following command will list down the processes with higher memory
consumption.
[ansible_user@lco-ansible-master ansible]$ ansible -i myinventory worker1 -m shell -a "ps -eo pid,ppid,%mem,%cpu,cmd --sort=-%mem | head"
That's all for this article but surely we can achieve a lot more things with Ansible Ad Hoc commands.
Hope you like the article. Stay Tuned for more.
Thank you. Happy learning!
Did you find this article valuable?
Support Learn Code Online by becoming a sponsor. Any amount is appreciated!