Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ericwastaken/c98d2ea8b1752f9903ce93df5847905a to your computer and use it in GitHub Desktop.
Save ericwastaken/c98d2ea8b1752f9903ce93df5847905a to your computer and use it in GitHub Desktop.
Running ad-hoc Commands and Scripts on multiple hosts using Ansible

Running ad-hoc Commands and Scripts on multiple hosts using Ansible

Summary

Ansible is very helpful for automated deployments. However, it can also be used for server admin tasks against many servers by using both the Command, Shell and Script Modules.

Note: Although the process described here works with hosts that you can access via password or SSH keys, it is more convenient when working with hosts that you have SSH keys for (you don't have to enter passwords!)

License

This content is shared under a Creative Commons Attribution-ShareAlike 4.0 International.

Dependencies

Before proceeding, make sure you have the following installed:

  • Ansible - Installing Ansible.
  • SSH Access - Ensure you can SSH to the hosts you want to manage, preferably by using SSH keys.

Setup your host Inventory

Create a directory anywhere and save the following in a file called hosts. This file provides Ansible with information about your hosts (the remote machines you want to connect to and control.)

[webservers]
web01 ansible_host=somehost01.yourdomain.com ansible_port=22 ansible_user=your-remote-user
web02 ansible_host=somehost02.yourdomain.com ansible_port=22 ansible_user=your-remote-user

[dbservers]
db01 ansible_host=somedb01.yourdomain.com ansible_port=22 ansible_user=your-remote-user
db02 ansible_host=somedb02.yourdomain.com ansible_port=22 ansible_user=your-remote-user

In the above, replace with your own host information. Also:

  • webservers and dbservers denote the server "groups" that you will be able to act on. You can act on all servers or one specific group. You can use any group names that suit your needs.
  • web01, web02, db01, db02 denote the specific hosts. You may also choose to act on one or more hosts by using the direct host alias in this file. You can use any host aliases to suit your needs.

Note: The above inventory file is very simple. Ansible's Inventory is very powerful and has many advanced features to make it easy for you to manage many hosts. See How to build your inventory for much more advanced setups.

Running simple commands

With an inventory file in place you can run a simple command against a server group with the following:

$ ansible webservers -i hosts -m command -a "echo hello"

(Run the above from the same directory that you created above that contains your hosts file. If you created your own group names, use that instead of webservers.)

This simple command returns this:

web01 | CHANGED | rc=0 >>
hello

web02 | CHANGED | rc=0 >>
hello

Note: The above example uses the Ansible Command Module. Read more about the Command Module. There is another mechanism using the Shell Module which runs commands through a shell on the remote. Finally, there is a Raw Module that runs commands outside of Ansible's module system, and is discouraged in most use cases.

Of course, echo hello is a contrite example, but you can theoretically run any command your user can run on the host's command line!

For instance, this command gets the externally facing IP address of your remote hosts using a CURL against ifconfig.co (a great website that you can use to verify your external IP address!)

$ ansible webservers -i hosts -m command -a "curl -s ifconfig.co"

This simple command returns this, which is the external IP for each of the hosts:

web01 | CHANGED | rc=0 >>
184.55.230.25

web02 | CHANGED | rc=0 >>
184.55.230.26

Running more complex commands using the Script module

Running a single cli is useful, but what if you need to do something more complex? Though it is possible in Linux to have very complex single-line commands, these can be tedious and difficult to create and work with. Therefore, it is easier to write a simple shell script in a file that is sent and executed on the remote.

For this use, the Script Module allows you to send and run an entire script on your remote hosts.

You begin by creating a script that does something interesting. For example, the following script checks with NetCat (nc) that the target host can establish a connection out to both DB hosts on port 9200 (Elasticsearch). It just uses a simple bash loop to run the nc command out to each DB host!

hostlist=( somedb01 somedb02 );
for host in "${hostlist[@]}"
do
    nc -zv ${host}.yourdomain.com 9200
done

Save the above script to check-db-access.sh in the same directory as your hosts file.

Then, you can run it on all webservers with:

$ ansible webservers -i hosts -m script -a "check-db-access.sh"

Note: Learn more about the Script Module.

@tseemann
Copy link

tseemann commented Apr 7, 2023

This tutorial was exactly what I was looking for, and worked first time!

Pointers on how to allow sudo/root for the command being run would also be useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment