Ad-hoc commands
Your sandbox is set up as an Ansible control node. Six "managed
hosts" are running as sibling containers, reachable over SSH:
| Group | Hosts |
|--------|-----------------------------|
| centos | centos1, centos2, centos3 |
| ubuntu | ubuntu1, ubuntu2, ubuntu3 |
Wait for the green โ lab ready banner at the top of the terminal,
then prove the connection by running an ad-hoc ping against every
host. The ping module isn't ICMP โ it logs into the host over SSH
and checks that Python is available.
ansible all -m ping
You should see one SUCCESS block per host. The control's
/root/ansible/hosts file lists them all under the all group via
the [linux:children] parent.
To narrow down to one group:
ansible centos -m ping
When every host returns pong, click Verify step.
Hint
Use `ansible -m ping all` once the lab is ready.
Inventory groups
Inventory files describe which hosts Ansible can talk to, and groups
let you target subsets of them. Open hosts in the Editor tab to see
the starter inventory:
[centos]
centos1
centos2
centos3
[ubuntu]
ubuntu1
ubuntu2
ubuntu3
[linux:children]
centos
ubuntu
The :children syntax turns linux into a parent group whose members
are the union of centos and ubuntu.
Run an ad-hoc command against just one group, then the parent group:
ansible centos -m command -a 'cat /etc/os-release'
ansible linux -m command -a 'hostname'
Now add a third group called lab that contains only centos1
and ubuntu1. Edit hosts and append:
[lab]
centos1
ubuntu1
Then verify it works:
ansible lab --list-hosts
Click Verify step when ansible lab --list-hosts shows both hosts.
Hint
Group hosts under `[centos]` and `[ubuntu]` headers in `hosts`.
Group variables
Connection details and ansible behaviour can be set per-host or
per-group. The common pattern is group_vars/<name>.yml โ Ansible
auto-loads variables for any group with that filename.
Create a group_vars directory and an all.yml file that pins the
SSH user globally:
mkdir -p group_vars
cat > group_vars/all.yml <<'EOF'
---
ansible_user: root
ansible_ssh_private_key_file: /root/.ssh/id_ed25519
EOF
Then narrow ubuntu-only behaviour. Some Ansible modules require
become: true to escalate on Debian-family hosts. Persist that for
the whole group:
cat > group_vars/ubuntu.yml <<'EOF'
---
ansible_become: true
EOF
Re-run the ping:
ansible all -m ping
The output should still be SUCCESS for all six hosts, but you've
moved the credential boilerplate out of hosts into reusable group
files. Click Verify step.
Hint
Create `group_vars/all.yml` with `ansible_user: root`.
Host patterns
The "hosts" argument to ansible and ansible-playbook accepts
patterns โ set operations across groups. The common ones:
| Pattern | Meaning |
|---------------------|----------------------------------------------------|
| all | every host in the inventory |
| centos:ubuntu | union โ every host in either group |
| centos:&ubuntu | intersection โ hosts in both (probably empty) |
| centos:!centos1 | centos group minus centos1 |
| centos[0] | first host in the centos group |
| ~ubuntu\d+ | regex (the ~ prefix toggles regex mode) |
Try each form:
ansible 'centos:!centos1' --list-hosts
ansible '~ubuntu[12]' --list-hosts
ansible 'centos[0]' -m command -a 'hostname'
Now run a ping on every linux host except centos1 and ubuntu3 in
a single invocation:
ansible 'linux:!centos1:!ubuntu3' -m ping
You should see four pong responses (centos2, centos3, ubuntu1,
ubuntu2). The linux parent group excludes the control's
localhost entry that's otherwise reachable through all.
Click Verify step.
Hint
Try `ansible centos:&ubuntu -m ping` โ bitwise patterns are documented under `ansible-doc -t inventory`.
Modules with arguments
ansible -m <module> -a '<args>' <pattern> is the canonical shape
for ad-hoc commands. The module name picks what to do, the args
pick how.
A few high-leverage modules:
# Run an arbitrary shell pipeline.
ansible centos -m shell -a 'uptime | awk "{print \$1, \$NF}"'
# Copy a file from the control to every host.
echo "managed-by-ansible" > /tmp/badge.txt
ansible all -m copy -a 'src=/tmp/badge.txt dest=/etc/cac-badge.txt mode=0644'
# Then read it back to confirm.
ansible all -m command -a 'cat /etc/cac-badge.txt'
# Install a package using the OS-neutral `package` module โ Ansible
# picks `dnf` on centos and `apt` on ubuntu automatically.
ansible all -m package -a 'name=tree state=present'
Take a look at ansible-doc package (q to quit) for the full list of
arguments the package module accepts.
Click Verify step once tree is installed on every host.
Hint
Pass module args with `-a`, e.g. `ansible centos -m command -a 'uptime'`.