Cloud AI Campus
  • Career paths
  • Learning paths
  • Hands-on Labs
Log in Sign up

๐Ÿงช Hands-on lab · 45 min

Ansible โ€” Architecture & Inventories

  1. 1. Ad-hoc commands
  2. 2. Inventory groups
  3. 3. Group variables
  4. 4. Host patterns
  5. 5. Modules with arguments

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'`.

© 2026 Cloud AI Campus