The Problem

Ansible inventories are great. You have the ability to use external databases as a source, but more on that later. Especially when starting to work with Ansible, it is often not the primary goal to integrate with the central CMDB or similar systems.

However, within a group of servers, there are often certain naming conventions that can be used to generate additional attributes.

The Solution

In my case, I would like to use Ansible to zone the existing ESX servers in the Fibre-Channel network. The servers will be zoned based on their location, which means they will be zoned according to the data center (RZ in German).

The Ansible inventory looks like this:

[esxserver]
esx01.example.org
esx02.example.org
esx03.example.org

Fortunately, we have a simple naming convention to directly determine where an ESX server is installed. If the number is odd, it belongs to RZ1; if it’s even, it belongs to RZ2 (similar to house numbers).

To set a variable based on the hostname, we need to use some Jinja2 magic within Ansible:

- name: Set RZ location based on hostname
  set_fact:
    rz: "{{ 'rz2' if inventory_hostname_short[-2:] | int is divisibleby 2 else 'rz1' }}"

In this example, we are using the special variable inventory_hostname_short, not the Fully-Qualified Host Name (FQDN). Thus, esx01.example.org becomes esx01. In the next step, we extract the ESX server number from the hostname using substring operations. Finally, using Jinja2 conditionals and filters, we check if the number can be evenly divided by two. Depending on the result, whether it is true or false, the variable is set to RZ1 or RZ2, respectively.

This principle can be used for various conditions. For example, depending on the hostname, an application variable could be set or the server could be identified as belonging to a specific environment (production, testing, development).

This translation was generated with the assistance of an AI language model developed by OpenAI.

Header Credit: CC-BY-SA Erik Wilde