The second method to include variable data from files is the include_vars module. This module will load variables as a task action and will be done for each host. Unlike most modules, this module is executed locally on the Ansible host; therefore, all paths are still relative to the play file itself. Because the variable loading is done as a task, evaluation of variables in the filename happens when the task is executed. Variable data in the file name can be host-specific and defined in a preceding task. Additionally, the file itself does not have to exist at execution time; it can be generated by a preceding task as well. This is a very powerful and flexible concept that can lead to very dynamic playbooks if used properly.
Before getting ahead of ourselves, let's demonstrate a simple usage of include_vars by modifying our existing play to load the variable file as a task:
--- - name: vars hosts: localhost gather_facts: false tasks: - name: load variables include_vars: "{{ varfile }}" - name: a task debug: msg: "I am a {{ varname }}"
Execution of the playbook remains the same and our output differs only slightly from previous iterations:
![](assets/e34a2d1b-5049-446e-a9b3-c9e235749af9.png)
Just like with other tasks, looping can be done to load more than one file in a single task. This is particularly effective when using the special with_first_found loop to iterate through a list of increasingly more generic filenames until a file is found to be loaded.
Let's demonstrate this by changing our play to use gathered host facts to try and load a variable file specific to the distribution, specific to the distribution family, or, finally, a default file:
---
- name: vars
hosts: localhost
gather_facts: true
tasks:
- name: load variables
include_vars: "{{ item }}"
with_first_found:
- "{{ ansible_distribution }}.yaml"
- "{{ ansible_os_family }}.yaml"
- variables.yaml
- name: a task
debug:
msg: "I am a {{ varname }}"
Execution should look very similar to previous runs, only this time we'll see a fact-gathering task, and we will not pass along extra variable data in the execution:
![](assets/17382990-74ea-4ae7-8652-ab0d3f12c3db.png)
We can also see from the output which file was found to load. In this case, variables.yaml was loaded, as the other two files did not exist. This practice is commonly used to load variables that are operating system-specific to the host in question. Variables for a variety of operating systems can be written out to appropriately named files. By utilizing the ansible_distribution variable, which is populated by fact gathering, variable files that use ansible_distribution values as part of their name can be loaded by way of a with_first_found argument. A default set of variables can be provided in a file that does not use any variable data as a failsafe.