Skip to content

Host Patterns Introduction


Back in the very first inventory chapter, this course made a promise: “patterns… we’re coming back for the deeper mechanics later.” The ad hoc chapter that followed only ever used a bare host name, a group name, or all. This is where the full picture finally arrives.

What You Already Know

A single host name, a single group name, or all — every pattern used in this course so far:

ansible ubuntu -m ansible.builtin.ping
ansible servers -m ansible.builtin.ping
ansible all -m ansible.builtin.ping

Combining Multiple Groups: Union

A colon (or comma) between patterns means “either of these” — the union of both:

ansible webservers:dbservers -m ansible.builtin.ping

Every host in webservers, plus every host in dbservers, targeted together in one command.

Wildcards

* matches any sequence of characters, exactly like a filesystem glob:

ansible 'web*' -m ansible.builtin.ping

Matches any host or group whose name starts with webweb01, web02, webservers, all of it.

Exclusion: !

! removes hosts from a pattern that would otherwise include them:

ansible 'webservers:!staging' -m ansible.builtin.ping

Every host in webservers, except any that are also in staging — useful for targeting production web servers specifically, without needing a dedicated group defined purely for that combination.

Intersection: &

& narrows a pattern down to hosts present in both groups:

ansible 'webservers:&staging' -m ansible.builtin.ping

Only hosts that are in webservers and staging at the same time — the opposite intent from exclusion, and easy to mix up with it if you’re not paying attention to which symbol you’re using.

Combining Multiple Operators In One Pattern

These compose together:

ansible 'webservers:dbservers:&staging:!maintenance' -m ansible.builtin.ping

Every host in webservers or dbservers, restricted to ones also in staging, with anything in maintenance excluded regardless. Patterns like this get hard to read fast — worth keeping in mind as this chapter’s own gotcha, covered in the best practices below.

Writing Inventory Using Host Patterns

You can write inventory file directly using host patterns just discussed:

inventory.yaml
# Web servers: web01 through web50
webservers:
  hosts:
    web[01:50].example.com:

# Database servers: db01, db03, db05, ..., db49
# The final ":2" means increment by 2
dbservers:
  hosts:
    db[01:50:2].example.com:

# Frontend servers: frontend-a through frontend-f
frontend_servers:
  hosts:
    frontend-[a-f].example.com:

One caveat: this is an Ansible inventory pattern, not a generic YAML feature. YAML simply sees these as keys; Ansible expands the patterns when parsing the inventory.

Best Practices

  • Reach for a wildcard when a naming convention already makes hosts self-describing (web*), rather than maintaining a separate group purely to capture that same naming pattern.
  • Prefer & for “must be in both,” ! for “must not be in this one” — say the operator’s meaning out loud if you’re ever unsure which one a situation calls for.
  • If a pattern needs more than two operators chained together to express what you mean, consider defining a proper group in inventory instead — a pattern that’s hard to read once is a pattern that’s genuinely risky to reuse later without re-deriving what it actually does.
Last updated on