How to Use Wildcard String Matching in Ansible Conditionals


2 views

In Ansible, conditionals are often used to control whether tasks should run based on certain criteria. A common scenario is checking EC2 instance tags, like ec2_tag_Name. While exact matches work fine:

when: ec2_tag_Name == 'testhost01'

Many users need wildcard matching to handle dynamic hostnames, such as testhost* to match testhost01, testhostABC, etc.

match Test /h2>

The most elegant way is using Ansible's built-in match test with regex:

when: ec2_tag_Name is match('^testhost.*')

This regex pattern means:

  • ^ - Start of string
  • testhost - Literal match
  • .* - Any characters (0 or more)

For those preferring Jinja2 filters:

when: ec2_tag_Name.startswith('testhost')

Or using regex_search:

when: ec2_tag_Name is regex('testhost.*')

Here's a complete task example:

- name: Configure testhost servers
  ansible.builtin.debug:
    msg: "Configuring testhost instance"
  when: ec2_tag_Name is match('^testhost.*')

For large inventories, startswith() is generally faster than regex matching. However, regex provides more flexibility if you need complex patterns later.

Remember that Ansible's match is case-sensitive by default. For case-insensitive matching:

when: ec2_tag_Name is match('^testhost.*', ignorecase=True)

When working with Ansible playbooks that manage EC2 instances, you often need to filter instances based on their tags. A common requirement is to match instance names using wildcard patterns, similar to shell globbing.

The basic conditional syntax for exact matching works perfectly:

when: ec2_tag_Name == 'testhost01'

However, this only matches exactly "testhost01" and nothing else.

Ansible provides several ways to implement wildcard matching:

1. Using the 'match' Test

The most straightforward solution is using Ansible's match test with a regex pattern:

when: ec2_tag_Name is match('^testhost.*')

This will match any string starting with "testhost". The ^ anchors the match to the start of the string.

2. Using the 'search' Test

If you need more flexible pattern matching anywhere in the string:

when: ec2_tag_Name is search('testhost')

3. Using the 'regex' Filter

You can also use the regex filter in a comparison:

when: ec2_tag_Name | regex_match('^testhost')

Here are some real-world examples of how you might use these patterns:

- name: Apply configuration to all testhost instances
  ansible.builtin.command: /usr/bin/configure
  when: ec2_tag_Name is match('^testhost[0-9]+$')

- name: Special setup for development hosts
  ansible.builtin.template:
    src: dev_config.j2
    dest: /etc/app/config
  when: ec2_tag_Name is match('^testhost.*dev.*$')

When working with large inventories:

  • The match test (anchored patterns) is generally faster than search
  • Simple patterns are more efficient than complex regex
  • Consider filtering at the inventory level when possible

For more complex scenarios, you can combine multiple conditions:

when: 
  - ec2_tag_Name is match('^testhost')
  - ec2_tag_Environment == 'production'
  - ec2_tag_Status != 'maintenance'