ansible

Ansible: How to get a value of a variable from the inventory or group_vars file?


How do I get the value of a variable from the inventory if the variable could be either in the inventory file or group_vars directory?

For example, region=place-a could be in the inventory file or in a file in the group_vars somewhere. I would like a command to be able to retrieve that value using ansible or something retrieve that value. like:

$ ansible -i /somewhere/production/web --get-value region
place-a

That would help me with deployments and knowing which region is being deployed to.

.

A longer explanation to clarify, my inventory structure looks like this:

/somewhere/production/web
/somewhere/production/group_vars/web

The contents with the variables of the inventory file, /somewhere/production/web looks like this:

[web:children]
web1 ansible_ssh_host=10.0.0.1
web2 ansible_ssh_host=10.0.0.2

[web:vars]
region=place-a

I could get the value from the inventory file by simply parsing the file. like so:

$ awk -F "=" '/^region/ {print $2}' /somewhere/production/web
place-a

But that variable could be in the group_vars file, too. For example:

$ cat /somewhere/production/group_vars/web
region: place-a

Or it could look like an array:

$ cat /somewhere/production/group_vars/web
region:
    - place-a

I don't want to look for and parse all the possible files.

Does Ansible have a way to get the values? Kind of like how it does with --list-hosts?

$ ansible web -i /somewhere/production/web --list-hosts
    web1
    web2

Solution

  • Short Answer

    NO there is no CLI option to get value of variables.

    Long Answer

    First of all, you must look into how variable precedence works in Ansible.

    The exact order is defined in the documentation. Here is an summary excerpt:

    Basically, anything that goes into “role defaults” (the defaults folder inside the role) is the most malleable and easily overridden. Anything in the vars directory of the role overrides previous versions of that variable in namespace. The idea here to follow is that the more explicit you get in scope, the more precedence it takes with command line -e extra vars always winning. Host and/or inventory variables can win over role defaults, but not explicit includes like the vars directory or an include_vars task.

    With that cleared out, the only way to see what value is a variable taking is to use the debug task as follows:

    - name: debug a variable
      debug:
        var: region
    

    This will print out the value of the variable region.

    My suggestion would be to maintain a single value type, either a string or a list to prevent confusion across tasks in different playbooks.

    You could use something like this:

    - name: deploy to regions
      <task_type>:
        <task_options>: <task_option_value>
        // use the region variable as you wish
        region: {{ item }}
        ...
      with_items: "{{ regions.split(',') }}"
    

    In this case you could have a variable regions=us-west,us-east comma-separated. The with_items statement would split it over the , and repeat the task for all the regions.