Getting Started Quickly With Ansible Ad Hoc Commands

6 min read

Introduction

Configuration management at scale has always been a challenging task for software engineers. Managing configuration on each server manually through SSH can be a tedious task. We have several automation tools for solving this problem. In this post, we’ll focus on Ansible.

Ansible has three primary use cases: provisioning, configuration management, and application deployment. Today, we’ll discuss configuration management. Ansible can be easily set up because it doesn’t require installation of any agent on the target nodes like other configuration management tools. That isn’t the only reason for choosing Ansible; it also has a big user base and is driven by an active community. 

Ansible follows a push-based mechanism. In a push-based mechanism, the server pushes configurations to the nodes. In this post, we’ll learn how to run Ansible ad hoc commands at scale.

What Are Ansible Ad Hoc Commands?

Ansible ad hoc commands are CLI commands used for simple and one-time tasks. One-time tasks include checking whether the nodes are reachable over SSH, shutting down all nodes, and so on. They can easily be run at scale and even concurrently on several hosts at the same time with a single command. 

Ansible ad hoc commands are idempotent—i.e., the state of the node is checked before executing the command, and if no state change can occur, the command isn’t executed.

Prerequisites

You need to have Ansible installed on the machine with which you want to control the target nodes. For the purposes of this post, we’ll refer to this machine as the controller. The Ansible controller is any machine that can connect to the servers using SSH and can control them.

Setup

  • I am running two VMs on AWS. You can use any cloud environment of your choice. These VMs are the hosts which we will control through Ansible.

  • The Ansible controller should be able to connect to the VMs using SSH. (Here, the "controller" is the machine on which Ansible is installed.)

  • The hosts file with two target groups, dev and prod. You can also use a complicated inventory file with several groups, like dev, test, and prod. With these groups, you can also use patterns to tell which hosts the ad hoc command should target.

[dev]

54.145.52.49   ansible_user=ubuntu

[prod]

3.95.196.233  ansible_user=ubuntu

  • The ansible.cfg setup. This file controls all the settings for the Ansible ad hoc commands.

[defaults]
inventory = ./inventory/hosts
retry_files_enabled = False
private_key_file = ubuntu-key.pem
host_key_checking = False

[ssh_connection]
pipelining = True
scp_if_ssh = True

  • The folder structure for local setup.

(Note: You can also change the SSH port in the inventory file if the SSH port on the host is different than 22 by mentioning it inside the hosts file.)

Before telling you about popular ad hoc commands, I would like to tell you that all Ansible commands follow a general structure: 

ansible <host-pattern> -m <module-name> -a “<module-command>” 

Keeping this structure in mind will make it easier to write ad hoc commands.

Does the Ansible Setup Work?

You can easily check if the setup works using Ansible’s ping module. We can use all in the host pattern to check the connectivity with all the hosts.

ansible all -m ping

The output should be a SUCCESS if those hosts are reachable with SSH.

3.95.196.233 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
54.145.52.49 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}

The "changed": false, tells us that no configuration change occurred when the above command was executed. Whenever an Ansible command does not change any configuration, the changed flag will be false.

Executing Commands on Ansible Hosts

You can use the shell module to execute shell commands. To shut down all the servers in the dev target group, you can use: 

ansible dev -m shell -a "shutdown -h now" --become

We used the --become flag here because this shell command requires a privilege escalation to be able to execute shutdown.

You can execute simple commands using the command module. If you live and breathe in uptime like most SREs, you can use: 

ansible prod -m command -a uptime

Difference Between Shell and Command Module in Ansible

Shell module executes all the instructions like you’re executing them using /bin/sh, whereas the command module does not; thus, shell operators like <.>, |, &&, or || won’t work with it.

Are Ansible Target Nodes All Right?

If you’re storing files on your target nodes, you may want to know the free disk space. Unexpected issues may occur if the disk space is low. This can be done easily using the default module. I’ll execute it on the prod group.

ansible prod -a "df -h"

3.95.196.233 | CHANGED | rc=0 >>
Filesystem      Size  Used Avail Use% Mounted on
/dev/root       7.7G  1.4G  6.3G  18% /
devtmpfs        482M     0  482M   0% /dev
tmpfs           487M     0  487M   0% /dev/shm
tmpfs            98M  808K   97M   1% /run
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           487M     0  487M   0% /sys/fs/cgroup
/dev/loop3       33M   33M     0 100% /snap/snapd/13640
/dev/loop0       25M   25M     0 100% /snap/amazon-ssm-agent/4046
/dev/loop1       56M   56M     0 100% /snap/core18/2128
/dev/loop2       62M   62M     0 100% /snap/core20/1169
/dev/loop4       68M   68M     0 100% /snap/lxd/21545
tmpfs            98M     0   98M   0% /run/user/1000

You can install packages using ad hoc commands using the package manager for your OS. I’m using Ubuntu, so I’ll be using the apt module.

ansible prod -m apt -a "name=wget state=present" --become

54.221.31.202 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "cache_update_time": 1634858834,
    "cache_updated": false,
    "changed": false
}

You can change the state from present to absent if you want to remove a package.

What About Using Ansible on More Than Five Servers?

You can run Ansible ad hoc commands at scale because Ansible offers parallel execution of commands on the servers. By default, Ansible can execute an ad hoc command on five nodes at a time. The number of parallel executions can be changed using the fork flag.

If you have a large number of servers, you can use the fork module to deploy packages. The below command will execute on 10 target nodes in parallel:

ansible prod -m apt -a "name=wget state=present" --become -f 10

Just Too Many Modules to Remember?

There are more than 1,000 Ansible modules. We can’t remember all of them and their functionalities. The more complicated the software, the more help it should provide to users. For the purposes of helping, you can use the ansible-doc command.

You can use the ansible-doc -l command to list all the modules. To search modules related to ping, you can use:

ansible-doc -l | grep -i ping

fortios_firewall_shaping_policy                               Configure sha...
fortios_firewall_shaping_profile                              Configure sha...
fortios_switch_controller_igmp_snooping                       Configure For...
icx_ping                                                      Tests reachab...
ios_ping                                                      Tests reachab...
junos_ping                                                    Tests reachab...
net_ping                                                      Tests reachab...
netapp_e_lun_mapping                                          NetApp E-Seri...
nxos_igmp_snooping                                            Manages IGMP ...
nxos_ping                                                     Tests reachab...
ping                                                          Try to connec...
pingdom                                                       Pause/unpause...
pn_igmp_snooping                                              CLI command t...
postgresql_ping                                               Check remote ...
vyos_ping                                                     Tests reachab...
win_ping                                                      A windows ver...

You can get detailed information about a particular module using:

ansible-doc <module-name>

Ansible is community-driven, so we can make our own modules and publish them on Ansible Galaxy. We may also find useful public modules to solve our problems on Ansible Galaxy. 

Conclusion

In this post, we learned how Ansible ad hoc commands solve the automation of configuration management problems for system administrators, DevOps engineers, and SREs, making configuration management both easy and efficient.

Ansible can help you deploy new features at scale on target groups, but it doesn’t provide any rollback features for configuration.

To manage the rollback process, you may consider using CloudBees Feature Management. CloudBees Feature Management allows you to roll back features and perform advanced user testing in a rich UI interface—and it offers a lot more functionality as well. See the documentation for details. 

One potential continuous delivery (CD) solution for easier pipelines with Ansible would be CloudBees CD, which lets you execute Ansible ad hoc commands as well as Ansible playbooks. CloudBees CD can help make Ansible ad hoc commands easier for beginners with its interface experience.

This post was written by Shivam Sharma. Shivam is a site reliability engineer with three years of experience in various DevOps technologies and back-end engineering.

Stay up to date

We'll never share your email address and you can opt out at any time, we promise.