One place for hosting & domains

      How To Manage Multiple Servers with Ansible Ad Hoc Commands


      Ansible is a modern configuration management tool that facilitates the task of setting up and maintaining remote servers. With a minimalist design intended to get users up and running quickly, it allows you to control one to hundreds of systems from a central location with either playbooks or ad hoc commands.

      Unlike playbooks — which consist of collections of tasks that can be reused — ad hoc commands are tasks that you don’t perform frequently, such as restarting a service or retrieving information about the remote systems that Ansible manages.

      In this cheat sheet guide, you’ll learn how to use Ansible ad hoc commands to perform common tasks such as installing packages, copying files, and restarting services on one or more remote servers, from an Ansible control node.


      In order to follow this guide, you’ll need:

      • One Ansible control node. This guide assumes your control node is an Ubuntu 20.04 machine with Ansible installed and configured to connect to your Ansible hosts using SSH keys. Make sure the control node has a regular user with sudo permissions and a firewall enabled, as explained in our Initial Server Setup guide. To set up Ansible, please follow our guide on How to Install and Configure Ansible on Ubuntu 20.04.
      • Two or more Ansible hosts. An Ansible host is any machine that your Ansible control node is configured to automate. This guide assumes your Ansible hosts are remote Ubuntu 20.04 servers. Make sure each Ansible host has:
        • The Ansible control node’s SSH public key added to the authorized_keys of a system user. This user can be either root or a regular user with sudo privileges. To set this up, you can follow Step 2 of How to Set Up SSH Keys on Ubuntu 20.04.
      • An inventory file set up on the Ansible control node. Make sure you have a working inventory file containing all your Ansible hosts. To set this up, please refer to the guide on How To Set Up Ansible Inventories. Then, make sure you’re able to connect to your nodes by running the connection test outlined in the section Testing Connection to Ansible Hosts.

      Testing Connection to Ansible Hosts

      The following command will test connectivity between your Ansible control node and all your Ansible hosts. This command uses the current system user and its corresponding SSH key as the remote login, and includes the -m option, which tells Ansible to run the ping module. It also features the -i flag, which tells Ansible to ping the hosts listed in the specified inventory file

      • ansible all -i inventory -m ping

      If this is the first time you’re connecting to these servers via SSH, you’ll be asked to confirm the authenticity of the hosts you’re connecting to via Ansible. When prompted, type yes and then hit ENTER to confirm.

      You should get output similar to this:


      server1 | SUCCESS => { "changed": false, "ping": "pong" } server2 | SUCCESS => { "changed": false, "ping": "pong" }

      Once you get a "pong" reply back from a host, it means the connection is live and you’re ready to run Ansible commands on that server.

      Adjusting Connection Options

      By default, Ansible tries to connect to the nodes as a remote user with the same name as your current system user, using its corresponding SSH keypair.

      To connect as a different remote user, append the command with the -u flag and the name of the intended user:

      • ansible all -i inventory -m ping -u sammy

      If you’re using a custom SSH key to connect to the remote servers, you can provide it at execution time with the --private-key option:

      • ansible all -i inventory -m ping --private-key=~/.ssh/custom_id

      Note: For more information on how to connect to nodes, please refer to our How to Use Ansible guide, which demonstrates more connection options.

      Once you’re able to connect using the appropriate options, you can adjust your inventory file to automatically set your remote user and private key, in case they are different from the default values assigned by Ansible. Then, you won’t need to provide those parameters in the command line.

      The following example inventory file sets up the ansible_user variable only for the server1 server:


      server1 ansible_host= ansible_user=sammy
      server2 ansible_host=

      Ansible will now use sammy as the default remote user when connecting to the server1 server.

      To set up a custom SSH key, include the ansible_ssh_private_key_file variable as follows:


      server1 ansible_host= ansible_ssh_private_key_file=/home/sammy/.ssh/custom_id
      server2 ansible_host=

      In both cases, we have set up custom values only for server1. If you want to use the same settings for multiple servers, you can use a child group for that:



      This example configuration will assign a custom user and SSH key only for connecting to the servers listed in group_a.

      Defining Targets for Command Execution

      When running ad hoc commands with Ansible, you can target individual hosts, as well as any combination of groups, hosts and subgroups. For instance, this is how you would check connectivity for every host in a group named servers:

      • ansible servers -i inventory -m ping

      You can also specify multiple hosts and groups by separating them with colons:

      • ansible server1:server2:dbservers -i inventory -m ping

      To include an exception in a pattern, use an exclamation mark, prefixed by the escape character , as follows. This command will run on all servers from group1, except server2:

      • ansible group1:!server2 -i inventory -m ping

      In case you’d like to run a command only on servers that are part of both group1 and group2, for instance, you should use & instead. Don’t forget to prefix it with a escape character:

      • ansible group1:&group2 -i inventory -m ping

      For more information on how to use patterns when defining targets for command execution, please refer to Step 5 of our guide on How to Set Up Ansible Inventories.

      Running Ansible Modules

      Ansible modules are pieces of code that can be invoked from playbooks and also from the command-line to facilitate executing procedures on remote nodes. Examples include the apt module, used to manage system packages on Ubuntu, and the user module, used to manage system users. The ping command used throughout this guide is also a module, typically used to test connection from the control node to the hosts.

      Ansible ships with an extensive collection of built-in modules, some of which require the installation of additional software in order to provide full functionality. You can also create your own custom modules using your language of choice.

      To execute a module with arguments, include the -a flag followed by the appropriate options in double quotes, like this:

      ansible target -i inventory -m module -a "module options"

      As an example, this will use the apt module to install the package tree on server1:

      • ansible server1 -i inventory -m apt -a "name=tree"

      Running Bash Commands

      When a module is not provided via the -m option, the command module is used by default to execute the specified command on the remote server(s).

      This allows you to execute virtually any command that you could normally execute via an SSH terminal, as long as the connecting user has sufficient permissions and there aren’t any interactive prompts.

      This example executes the uptime command on all servers from the specified inventory:

      • ansible all -i inventory -a "uptime"


      server1 | CHANGED | rc=0 >> 14:12:18 up 55 days, 2:15, 1 user, load average: 0.03, 0.01, 0.00 server2 | CHANGED | rc=0 >> 14:12:19 up 10 days, 6:38, 1 user, load average: 0.01, 0.02, 0.00

      Using Privilege Escalation to Run Commands with sudo

      If the command or module you want to execute on remote hosts requires extended system privileges or a different system user, you’ll need to use Ansible’s privilege escalation module, become. This module is an abstraction for sudo as well as other privilege escalation software supported by Ansible on different operating systems.

      For instance, if you wanted to run a tail command to output the latest log messages from Nginx’s error log on a server named server1 from inventory, you would need to include the --become option as follows:

      • ansible server1 -i inventory -a "tail /var/log/nginx/error.log" --become

      This would be the equivalent of running a sudo tail /var/log/nginx/error.log command on the remote host, using the current local system user or the remote user set up within your inventory file.

      Privilege escalation systems such as sudo often require that you confirm your credentials by prompting you to provide your user’s password. That would cause Ansible to fail a command or playbook execution. You can then use the --ask-become-pass or -K option to make Ansible prompt you for that sudo password:

      • ansible server1 -i inventory -a "tail /var/log/nginx/error.log" --become -K

      Installing and Removing Packages

      The following example uses the apt module to install the nginx package on all nodes from the provided inventory file:

      • ansible all -i inventory -m apt -a "name=nginx" --become -K

      To remove a package, include the state argument and set it to absent:.

      • ansible all -i inventory -m apt -a "name=nginx state=absent" --become -K

      Copying Files

      With the file module, you can copy files between the control node and the managed nodes, in either direction. The following command copies a local text file to all remote hosts in the specified inventory file:

      • ansible all -i inventory -m copy -a "src=./file.txt dest=~/myfile.txt"

      To copy a file from the remote server to your control node, include the remote_src option:

      • ansible all -i inventory -m copy -a "src=~/myfile.txt remote_src=yes dest=./file.txt"

      Changing File Permissions

      To modify permissions on files and directories on your remote nodes, you can use the file module.

      The following command will adjust permissions on a file named file.txt located at /var/www on the remote host. It will set the file’s umask to 600, which will enable read and write permissions only for the current file owner. Additionally, it will set the ownership of that file to a user and a group called sammy:

      • ansible all -i inventory -m file -a "dest=/var/www/file.txt mode=600 owner=sammy group=sammy" --become -K

      Because the file is located in a directory typically owned by root, we might need sudo permissions to modify its properties. That’s why we include the --become and -K options. These will use Ansible’s privilege escalation system to run the command with extended privileges, and it will prompt you to provide the sudo password for the remote user.

      Restarting Services

      You can use the service module to manage services running on the remote nodes managed by Ansible. This will require extended system privileges, so make sure your remote user has sudo permissions and you include the --become option to use Ansible’s privilege escalation system. Using -K will prompt you to provide the sudo password for the connecting user.

      To restart the nginx service on all hosts in group called webservers, for instance, you would run:

      • ansible webservers -i inventory -m service -a "name=nginx state=restarted" --become -K

      Restarting Servers

      Although Ansible doesn’t have a dedicated module to restart servers, you can issue a bash command that calls the /sbin/reboot command on the remote host.

      Restarting the server will require extended system privileges, so make sure your remote user has sudo permissions and you include the --become option to use Ansible’s privilege escalation system. Using -K will prompt you to provide the sudo password for the connecting user.

      Warning: The following command will fully restart the server(s) targeted by Ansible. That might cause temporary disruption to any applications that rely on those servers.

      To restart all servers in a webservers group, for instance, you would run:

      • ansible webservers -i inventory -a "/sbin/reboot" --become -K

      Gathering Information About Remote Nodes

      The setup module returns detailed information about the remote systems managed by Ansible, also known as system facts.

      To obtain the system facts for server1, run:

      • ansible server1 -i inventory -m setup

      This will print a large amount of JSON data containing details about the remote server environment. To print only the most relevant information, include the "gather_subset=min" argument as follows:

      • ansible server1 -i inventory -m setup -a "gather_subset=min"

      To print only specific items of the JSON, you can use the filter argument. This will accept a wildcard pattern used to match strings, similar to fnmatch. For example, to obtain information about both the ipv4 and ipv6 network interfaces, you can use *ipv* as filter:

      • ansible server1 -i inventory -m setup -a "filter=*ipv*"


      server1 | SUCCESS => { "ansible_facts": { "ansible_all_ipv4_addresses": [ "", "" ], "ansible_all_ipv6_addresses": [ "fe80::a4f5:16ff:fe75:e758" ], "ansible_default_ipv4": { "address": "", "alias": "eth0", "broadcast": "", "gateway": "", "interface": "eth0", "macaddress": "a6:f5:16:75:e7:58", "mtu": 1500, "netmask": "", "network": "", "type": "ether" }, "ansible_default_ipv6": {} }, "changed": false }

      If you’d like to check disk usage, you can run a Bash command calling the df utility, as follows:

      • ansible all -i inventory -a "df -h"


      server1 | CHANGED | rc=0 >> Filesystem Size Used Avail Use% Mounted on udev 3.9G 0 3.9G 0% /dev tmpfs 798M 624K 798M 1% /run /dev/vda1 155G 2.3G 153G 2% / tmpfs 3.9G 0 3.9G 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup /dev/vda15 105M 3.6M 101M 4% /boot/efi tmpfs 798M 0 798M 0% /run/user/0 server2 | CHANGED | rc=0 >> Filesystem Size Used Avail Use% Mounted on udev 2.0G 0 2.0G 0% /dev tmpfs 395M 608K 394M 1% /run /dev/vda1 78G 2.2G 76G 3% / tmpfs 2.0G 0 2.0G 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup /dev/vda15 105M 3.6M 101M 4% /boot/efi tmpfs 395M 0 395M 0% /run/user/0


      In this guide, we demonstrated how to use Ansible ad hoc commands to manage remote servers, including how to execute common tasks such as restarting a service or copying a file from the control node to the remote servers managed by Ansible. We’ve also seen how to gather information from the remote nodes using limiting and filtering parameters.

      As an additional resource, you can check Ansible’s official documentation on ad hoc commands.

      Source link