Search code examples
ansibleroles

Ansible: Include variables file under role/xyzrole/main.yml


I have some variables that dont change and some that do from time to time. I'd like my main.yml within the role to list all the static variables, for the dynamic variables I'd like to put them in a different file and just include the new file everytime there is a change.

Like this:

main.yml:

---
var1: somevalue
var2: anothervalue
var3:
  var3.1: somevalue that changes
  var3.2: anothervalue that changes

Instead of that, I'd like to do the following:

main.yml:

---
var1: somevalue
var2: anothervalue
invlude_vars: varsfile.yml

varsfile.yml:

---
var3:
  var3.1: somevalue that changes
  var3.2: anothervalue that changes

This way I dont have to touch main.yml but change varsfile.yml everytime there is any change. I tried it, ends in following error:

fatal: [hostnamehidden]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'var3.1' is undefined\n\nThe error appears to be in '.../tasks/main.yml': line 7, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Some tasks is getting executed here^ here\n"}

Any ideas? Is it possible to do this at all within the roles/rolename/vars/main.yml?


Solution

  • There are many options depending on the exact use-case. For example, use the default values. Given the role

    shell> cat roles/role3/defaults/main.yml 
    var1: somevalue
    var2: anothervalue
    var3:
      var3.1: "{{ somevalue_that_changes|default('UNDEFINED') }}"
      var3.2: "{{ anothervalue_that_changes|default('UNDEFINED') }}"
    
    shell> cat roles/role3/tasks/main.yml 
    - debug:
        var: var3
    

    The playbook

    shell> cat playbook.yml
    - hosts: localhost
      roles:
        - role3
    

    gives

    shell> ansible-playbook playbook.yml
    
    TASK [role3 : debug] ****
    ok: [localhost] => 
      var3:
        var3.1: UNDEFINED
        var3.2: UNDEFINED
    

    If you define the variable, for example on the command-line, the playbook gives

    shell> ansible-playbook playbook.yml -e somevalue_that_changes=XYZ
    
    TASK [role3 : debug] ****
    ok: [localhost] => 
      var3:
        var3.1: XYZ
        var3.2: UNDEFINED
    

    Of course, it's possible to put the variables into a file and use the file in the playbook. For example

    shell> cat varsfile.yml 
    somevalue_that_changes: XYZ
    anothervalue_that_changes: 123
    
    shell> cat playbook.yml
    - hosts: localhost
      vars_files:
        - varsfile.yml
      roles:
        - role3
    

    gives

    shell> ansible-playbook playbook.yml
    
    TASK [role3 : debug] ****
    ok: [localhost] => 
      var3:
        var3.1: XYZ
        var3.2: '123'
    

    It's possible to include the data in the role instead of the playbook. For example

    shell> cat roles/role3/tasks/main.yml
    - include_vars: varsfile.yml
    - debug:
        var: var3
    

    gives

    shell> ansible-playbook playbook.yml
    
    TASK [role3 : debug] ****
    ok: [localhost] => 
      var3:
        var3.1: XYZ
        var3.2: '123'
    

    Q: "Separate the changing variables into another file and include them within vars/main.yml"

    A: Use lookup plugin file. For example, put the changing variables into the file

    shell> cat files/varsfile.yml
    var3.1: XYZ
    var3.2: 123
    

    Combine the changing variables from the file with the defaults

    shell> cat roles/role3/defaults/main.yml 
    var1: somevalue
    var2: anothervalue
    var3_default:
      var3.1: "{{ somevalue_that_changes|default('UNDEFINED') }}"
      var3.2: "{{ anothervalue_that_changes|default('UNDEFINED') }}"
    
    shell> cat roles/role3/vars/main.yml
    var3: "{{ var3_default|combine(lookup('file', 'varsfile.yml')|from_yaml) }}"
    

    Then, the debug task

    shell> cat roles/role3/tasks/main.yml
    - debug:
        var: var3
    

    gives

      var3:
        var3.1: XYZ
        var3.2: 123
    

    It's rather flexible. For example, if you omit var3.1

    shell> cat files/varsfile.yml
    var3.2: 123
    

    The result is

      var3:
        var3.1: UNDEFINED
        var3.2: 123
    

    In addition to this, you can still override the default values. For example,

    shell> ansible-playbook playbook.yml -e somevalue_that_changes=ABC
    

    gives

      var3:
        var3.1: ABC
        var3.2: 123
    

    Fit the defaults/vars, paths, and combinations to your needs.