Home > Mobile >  How to set distinct variables for different hosts in an external variables yaml to be used in Ansibl
How to set distinct variables for different hosts in an external variables yaml to be used in Ansibl

Time:04-05

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.

  1. 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'

  1. 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

  1. 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.

  • Related