Ansible - create a group by exclusion

May 30, 2015   #ansible 

Nine times out of ten, you probably create a group by listing the hosts to include. In some occassions however, you might want to create a group based on hosts that shouldn’t be in it.

This isn’t possible in a static inventory, however you can do it dynamically.

Given the following hosts file, lets create a group that excludes ubuntu1204

[centos]
centos66 ansible_ssh_host=192.168.35.21 
centos70 ansible_ssh_host=192.168.35.22 

[ubuntu]
ubuntu1204 ansible_ssh_host=192.168.35.31 
ubuntu1410 ansible_ssh_host=192.168.35.32 

It requires a 2 step process

  1. the difference filter to get all items in list1 that don’t exist in list2
  2. the add_host module to generate the actual group from the list

e.g.

---
- hosts: centos66
  remote_user: vagrant
  tasks:
    - set_fact: 
        others: "{{ groups['all'] | difference(['ubuntu1204']) }}"
 
    - add_host: 
        name: "{{ item }}"
        groups: all_but_ubuntu1204 
      with_items: others
 
    - debug: var=groups

- hosts: all_but_ubuntu1204
  tasks:
    # - ...

which gives the following output

TASK: [debug var=groups] ****************************************************** 
ok: [centos66] => {
    "var": {
        "groups": {
            "all": [
                "ubuntu1204", 
                "centos66", 
                "centos70", 
                "ubuntu1410"
            ], 
            "all_but_ubuntu1204": [
                "centos66", 
                "centos70", 
                "ubuntu1410"
            ], 
            "centos": [
                "centos66", 
                "centos70"
            ], 
            "ubuntu": [
                "ubuntu1204", 
                "ubuntu1410"
            ], 
            "ungrouped": []
        }
    }
}