I have for example this playbook:
- name: System Configuration
hosts: host1, host2
become: yes
tasks:
- name: Set current app version
shell: export APP_VERSION={{ app_version|quote }}
I wish to set this variables for multiple hosts, for example host
and host2
. I read somewhere that I can create a yml
file with the name of each host and store the variables fort each host there but I cane find how to load this file for each host.
I thought it may be loaded automatically if the name matches the host name but I dont think this happens I get an error FAILED! => {"msg": "The task includes an option with an undefined variable
so how can I define a set for variables for each host separately?
CodePudding user response:
There are many options.
- For example, create a dictionary in 'group_vars/all'
shell> cat group_vars/all
app_versions:
host1: '1.1'
host2: '1.2'
default: '1.0'
app_version: "{{ app_versions[inventory_hostname]|
default(app_versions.default) }}"
The playbook
- hosts: host1,host2,host3
tasks:
- debug:
var: app_version
gives
TASK [debug] **********************************************************
ok: [host3] =>
app_version: '1.0'
ok: [host1] =>
app_version: '1.1'
ok: [host2] =>
app_version: '1.2'
- The next option is 'vars_files'. Create a YAML file and use it in the playbook. For example, the file and the playbook give the same result
shell> cat app_versions.yml
app_versions:
host1: '1.1'
host2: '1.2'
default: '1.0'
app_version: "{{ app_versions[inventory_hostname]|
default(app_versions.default) }}"
- hosts: host1,host2,host3
vars_files:
- app_versions.yml
tasks:
- debug:
var: app_version
- The next option is to create files in host_vars. For example, the 'host_vars' and the playbook give also the same result
shell> cat host_vars/host1.yml
app_version: '1.1'
shell> cat host_vars/host2.yml
app_version: '1.2'
shell> cat host_vars/host3.yml
app_version: '1.0'
- hosts: host1,host2,host3
tasks:
- debug:
var: app_version
The options override each other. See Understanding variable precedence. In the above options, the lowest precedence (4,5) are group_vars/all followed by host_vars precedence (9,10). The highest precedence (14) has the play vars_file.
Putting it all together, you might want to put the defaults to the group_vars/all
shell> cat group_vars/all
app_versions:
default: '1.0'
and override the defaults in host_vars
shell> tree host_vars
host_vars
├── host1.yml
└── host2.yml
shell> cat host_vars/host1.yml
app_version: '1.1'
shell> cat host_vars/host2.yml
app_version: '1.2'
Then, the playbook below gives again the same result
- hosts: host1,host2,host3
tasks:
- set_fact:
app_version: "{{ app_version|
default(app_versions[inventory_hostname])|
default(app_versions.default) }}"
- debug:
var: app_version
CodePudding user response:
Ok there are probably many solutions to this but the one I liked an used is to create a vars
sub-directory in my project folder. Ansible look there by default when trying to find variable files for a host with the include_vars
module.
So in my tasks I added this task:
tasks:
- name: Load variables for host
include_vars:
file: "{{ inventory_hostname }}.yml"
and in my project in the vars
directory I added a host_name_as_in_inventory.yml
file with the host-name for each host I want to specify variables for.
Edit: as it is suggested int he other coment if the yml
files with the hostnames are added in a directory calles host_vars
they are loaded automatically so the include_vars
taks is redundant.