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:
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.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:
Outputserver1 | 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.
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=203.0.113.111 ansible_user=sammy
server2 ansible_host=203.0.113.112
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=203.0.113.111 ansible_ssh_private_key_file=/home/sammy/.ssh/custom_id
server2 ansible_host=203.0.113.112
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:
[group_a]
203.0.113.111
203.0.113.112
[group_b]
203.0.113.113
[group_a:vars]
ansible_user=sammy
ansible_ssh_private_key_file=/home/sammy/.ssh/custom_id
This example configuration will assign a custom user and SSH key only for connecting to the servers listed in group_a
.
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.
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"
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"
Outputserver1 | 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
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
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
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"
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.
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
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
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*"
Outputserver1 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"203.0.113.111",
"10.0.0.1"
],
"ansible_all_ipv6_addresses": [
"fe80::a4f5:16ff:fe75:e758"
],
"ansible_default_ipv4": {
"address": "203.0.113.111",
"alias": "eth0",
"broadcast": "203.0.113.111",
"gateway": "203.0.113.1",
"interface": "eth0",
"macaddress": "a6:f5:16:75:e7:58",
"mtu": 1500,
"netmask": "255.255.240.0",
"network": "203.0.113.0",
"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"
Output
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.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
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.
This series goes over how to use Ansible to manage remote servers, and how to execute Ansible playbooks to automate server setup.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!