Adding an existing host to a group in an Ansible Tower Inventory

With each new release of Ansible comes the addition of more Ansible modules provided as part of Ansible Core. However, sometimes the modules do not provide enough functionality. That is where other modules such as the uri module can be used to plug in any gaps.

An example of this gap is when adding an existing host to a group in an Ansible Tower inventory. The tower_host Ansible module can be used to add a host to an inventory on Ansible Tower, but cannot be used to add said host to a particular group (despite this functionality being available in the Ansible Tower Web UI). This can be frustrating if Ansible Tower is used as an inventory source (if there is a lack of an appropriate dynamic inventory to use).

There appears to be an open issue (https://github.com/ansible/awx/issues/5177) raised on Github to track this issue, but what if you can’t wait for an official fix?

There are a few solutions to this issue:

  • Use the command or shell module to run tower-cli to associate the host to the appropriate group in the Ansible Tower inventory.
  • The Ansible Tower REST API provides this functionality. However, it requires looking up the inventory ID and group ID.
  • Create a Smart Inventory and define a host filter.

The solution I’m going through though is using the uri module. Referring to the API documentation (https://docs.ansible.com/ansible-tower/latest/html/towerapi/api_ref.html#/Groups/Groups_groups_hosts_create), here is an example where I use the uri module to assign the host to the group in the following task:

- name: Add the host to a Tower Inventory group via API
  uri:
    url: "https://{{ ansible_tower_host }}/api/v2/groups/{{ group_id }}/hosts/"
    body:
      name: "{{ host }}"
      inventory: "{{ inventory_name }}"
    body_format: json
    headers:
      Content-Type: application/json
      Authorization: "Bearer {{ token }}"
    method: POST
    status_code: 204

With the above example, I have assumed you’ve authenticated previously in a different task and pass the token in the request header. The reason why I have chosen using the Ansible Tower API is that it does not require tower-cli to be installed either on the Ansible control node or where the task is running.

This is just a basic example, but hopefully can be used as a basis for something more substantial if required.

Leave a comment