Skip to content

Instantly share code, notes, and snippets.

@dmccuk
Last active June 16, 2023 19:09
Show Gist options
  • Save dmccuk/66b7095f6711134c74fc593db00516b3 to your computer and use it in GitHub Desktop.
Save dmccuk/66b7095f6711134c74fc593db00516b3 to your computer and use it in GitHub Desktop.
Ansible – Ad-hoc commands
The ability to use ad-hoc commands in Ansible without the need for playbooks is a very powerful tool. In the old days of
Linux and Unix administration (and even today!), the Admins would use a golden host or jump server with SSH keys and be
able to hop around their environments running remote command and colleting data. Ad-hoc commands in Ansible gives us this
same ability, but with a much more powerful tool at our fingertips.
---
Website: https://www.londoniac.co.uk/
Meetup: https://www.meetup.com/londoniac
LinkedIn: https://www.linkedin.com/company/londoniac
YT Channel: https://www.youtube.com/c/LondonIAC
---
In this demo:
• Run basic ad-hoc commands on localhost and remote servers
o Modules: ping, shell, file, copy, yum, setup, reboot
• Using the inventory to manage different operating systems, users and credentials
• Run ad-hoc commands on multiple hosts
My setup: I’m using a .pem key for authentication between my control node and the remote servers.
Links:
https://docs.ansible.com/ansible/2.8/user_guide/intro_adhoc.html
Commands:
ansible localhost -m ping
ansible localhost -m shell -a 'uptime'
ansible localhost -m shell -a 'df -h'
ansible localhost -m copy -a "content='Hello, this is my new file\n' dest=/tmp/new_file"
ansible localhost -m yum -a "name=aide state=latest" --become
Lets try it on a remote server:
ansible 18.169.104.89 -m ping
That’s because you need to authenticate. So you have to provide a user and a key file (I’m my example)
ansible -i 3.9.169.49, all -m ping -u ec2-user --private-key=~/.ssh/working.pem
ansible -i 18.169.104.89, all -m ping -u ubuntu --private-key=~/.ssh/working.pem
---
Now we want to run ansible on multiple servers. To do this We need an inventory file.
The inventory file lets us group together our hosts, and supply variables to each group.
First, with no groups (different OS’s)
18.169.104.89
3.9.169.49
ansible -i hosts.ini all -m ping
ansible -i hosts.ini all -m ping -u ubuntu
ansible -i hosts.ini all -m ping -u ubuntu --private-key=~/.ssh/working.pem
ansible -i hosts.ini all -m ping -u ec2-user --private-key=~/.ssh/working.pem
This is no good.
In our inventory file, lets create 2 groups called centos and ubuntu:
[ubuntu]
18.169.104.89
[centos]
3.9.169.49
ansible -i hosts.ini ubuntu -m ping -u ec2-user --private-key=~/.ssh/working.pem
ansible -i hosts.ini ubuntu -m ping -u ec2-user --private-key=~/.ssh/working.pem
We need inventory variables so let’s create variables n the inventory file:
[ubuntu]
18.169.104.89
[centos]
3.9.169.49
[ubuntu:vars]
ansible_user=ubuntu
[centos:vars]
centos_user=ec2-user
ansible -i hosts.ini all -m ping --private-key=~/.ssh/working.pem
Now lets get ring of the private key into the inventory so we don’t have to type it every time:
The simplest solution is to add an all:vars section.
[ubuntu]
18.169.104.89
[centos]
3.9.169.49
[ubuntu:vars]
ansible_user=ubuntu
[centos:vars]
centos_user=ec2-user
[all:vars]
Cat
BUT, if you have different keys for different servers or groups of servers, you can move the private key variable around and update it for your specific use case.
The variables work on an order and will override variables if they are more specific to a server. So if a variable affects one server, it will beat a variable setting for the group, and that group setting will beat a variable set for all servers.
So now we have the inventory sorted out, and we understand how to setup the template, lets finish by running a few ad-hoc commands on our remote servers.
Copy over a file and use the local hostame variable:
ansible -i hosts.ini all -m copy -a "content='Hello, this is my new file on server: $HOSTNAME\n' dest=/tmp/new_file"
Install a package on all the remote servers (use the package module) – yum or apt wouldn’t work across OS version.
Notice we need root permissions I’ve added –become. I also have sudo privilege to do it.
ansible -i hosts.ini all -m package -a "name=telnet state=latest" –become
and remove it:
ansible -i hosts.ini all -m package -a "name=telnet state=absent" –become
Remote command:
ansible -i hosts.ini all -m shell -a "uptime"
Reboot servers:
ansible -i hosts.ini all -m shell -a "reboot" –become
Setup module, pull out specific information about your servers:
ansible -i hosts.ini all -m setup
ansible -i hosts.ini centos -m setup | sed '1c {'|jq '.ansible_facts|keys'
ansible -i hosts.ini centos -m setup | sed '1c {'|jq '.ansible_facts.ansible_os_family'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment