lucky simon
lucky simon

Reputation: 291

Include vars from a file for multiple import_playbooks

This is an error using Ansible 2.7

I am trying to include a files with vars in it into my playbook that has multiple import_playbooks.

I have 3 files.

  1. one with all the vars
  2. one with a playbook and a task
  3. one with an import_playbook

My playbook:

---
- name: Create CPG
  hosts: localhost

  tasks:
   - name: Create CPG "{{ cpg_name }}"
     hpe3par_cpg:
      storage_system_ip: "{{ storage_system_ip }}"
      storage_system_username: "{{ storage_system_username }}"
      storage_system_password: "{{ storage_system_password }}"
      state: present
      cpg_name: "{{ cpg_name }}"
      #domain: "{{ domain }}"
      growth_increment: "{{ growth_increment }}"
      growth_increment_unit: "{{ growth_increment_unit }}"
      growth_limit: "{{ growth_limit }}"
      growth_limit_unit: "{{ growth_limit_unit }}"
      growth_warning: "{{ growth_warning }}"
      growth_warning_unit: "{{ growth_warning_unit }}"
      raid_type: "{{ raid_type }}"
      set_size: "{{ set_size }}"
      high_availability: "{{ high_availability }}"
      disk_type: "{{ disk_type }}"

The playbook where I will call my tasks and my variables:

---
- name: master
  hosts: localhost

- import_playbook: create_CPG.yml
   include_vars: properties/variables.yml

I get this error when running "ansible-playbook create_master.yml"

ERROR! Syntax Error while loading YAML.
  mapping values are not allowed in this context

The error appears to have been in '/home/simon/Documents/Ansible/create_MasterPlaybook.yml': line 6, column 16, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

- import_playbook: create_CPG.yml
   include_vars: properties/variables.yml
               ^ here

Is there a way to call a file with variables for only this import_playbook.

thank you

Upvotes: 3

Views: 14859

Answers (3)

Vladimir Botka
Vladimir Botka

Reputation: 67984

(Update 14 Jun 2022 for Ansible 2.12)

Q: "Is there a way to call a file with variables for only this import_playbook?"

A: No. It is not. The variables included in a task are visible in the whole playbook to the affected hosts. include_vars is a task. The correct syntax would be

- name: master
  hosts: localhost
  tasks:
    - include_vars: properties/variables.yml

- import_playbook: create_CPG.yml

import_playbook is not a tasks. It is a module that "Includes a file with a list of plays to be executed". You can declare vars in the scope of the imported plays. For example,

- import_playbook: create_CPG.yml
  vars:
    var1: value of var1

But, you can't declare vars_files at the moment. The import below

- import_playbook: create_CPG.yml
  vars_files:
    - properties/variables.yml

will fail with the error:

ERROR! 'vars_files' is not a valid attribute for a PlaybookInclude

See Ansible issue Support vars_files when using import_playbook #36806. This will solve your problem when implemented.


Workaround

Put the name of the file into a variable and use vars. For example, given the inventory

shell> cat hosts
host1 var1=1
host2 var1=2

, the file with the play

shell> cat pb-import.yml
- hosts: host1,host2
  gather_facts: false
  vars_files:
    - "{{ my_vars_file|default('vars_file_default.yml') }}"
  tasks:
    - debug:
        msg: |-
          var1: {{ var1|d('undef') }}
          var2: {{ var2|d('undef') }}

, the playbook

shell> cat pb.yml
- import_playbook: pb-import.yml

- import_playbook: pb-import.yml
  vars:
    my_vars_file: vars_file_play_A.yml

- import_playbook: pb-import.yml
  vars:
    my_vars_file: vars_file_play_B.yml

, and the files with the variables for various playbooks

shell> cat vars_file_default.yml
var2: play default
shell> cat vars_file_play_A.yml
var2: play A
shell> cat vars_file_play_B.yml
var2: play B

gives

shell> ansible-playbook pb.yml

PLAY [host1,host2] ***************************************************************************

TASK [debug] *********************************************************************************
ok: [host1] => 
  msg: |-
    var1: 1
    var2: play default
ok: [host2] => 
  msg: |-
    var1: 2
    var2: play default

PLAY [host1,host2] ***************************************************************************

TASK [debug] *********************************************************************************
ok: [host1] => 
  msg: |-
    var1: 1
    var2: play A
ok: [host2] => 
  msg: |-
    var1: 2
    var2: play A

PLAY [host1,host2] ***************************************************************************

TASK [debug] *********************************************************************************
ok: [host1] => 
  msg: |-
    var1: 1
    var2: play B
ok: [host2] => 
  msg: |-
    var1: 2
    var2: play B

PLAY RECAP ***********************************************************************************
host1: ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host2: ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Scope of the variables

The scope of the variables is more complex. See Scoping variables. There are three main scopes: global, play, and host. For example, given the inventory

shell> cat hosts
host1 var1=1
host2 var1=2
host3 var1=3

, the file

shell> cat my_vars.yml 
var4: included in a task

, and the playbook

shell> cat pb.yml
- hosts: host1,host2
  gather_facts: false
  vars:
    var2: play
  tasks:
    - include_vars: my_vars.yml
    - debug:
        msg: |-
          var1: {{ var1|d('undef') }}
          var2: {{ var2|d('undef') }}
          var3: {{ var3|d('undef') }}
          var4: {{ var4|d('undef') }}

- hosts: host1,host2,host3
  gather_facts: false
  tasks:
    - debug:
        msg: |-
          var1: {{ var1|d('undef') }}
          var2: {{ var2|d('undef') }}
          var3: {{ var3|d('undef') }}
          var4: {{ var4|d('undef') }}

gives the results below:

  • Host scope. The variable var1 declared in the inventory is available to the host in the whole playbook

  • Play scope: The variable var2 declared in the first play is available to all hosts in the first play only. The variable is undefined in the second play.

  • Global scope. The variable var3 declared as an extra variable at the command line is available globally to all hosts in all plays.

  • The variable var4* declared in the - include_vars: my_vars.yml is available to the affected hosts only, i.e. hosts in the first play host1,host2. The variable is undefined to host3.

shell> ansible-playbook pb.yml -e var3=global

PLAY [host1,host2] ***************************************************************************

TASK [include_vars] **************************************************************************
ok: [host1]
ok: [host2]

TASK [debug] *********************************************************************************
ok: [host1] => 
  msg: |-
    var1: 1
    var2: play
    var3: global
    var4: included in a task
ok: [host2] => 
  msg: |-
    var1: 2
    var2: play
    var3: global
    var4: included in a task

PLAY [host1,host2,host3] *********************************************************************

TASK [debug] *********************************************************************************
ok: [host1] => 
  msg: |-
    var1: 1
    var2: undef
    var3: global
    var4: included in a task
ok: [host2] => 
  msg: |-
    var1: 2
    var2: undef
    var3: global
    var4: included in a task
ok: [host3] => 
  msg: |-
    var1: 3
    var2: undef
    var3: global
    var4: undef

PLAY RECAP ***********************************************************************************
host1: ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host2: ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host3: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

The results are the same if the playbooks are imported. For example, given the file

shell> cat pb-import.yml
- hosts: host1,host2,host3
  gather_facts: false
  tasks:
    - debug:
        msg: |-
          var1: {{ var1|d('undef') }}
          var2: {{ var2|d('undef') }}
          var3: {{ var3|d('undef') }}
          var4: {{ var4|d('undef') }}

and the imports added to the previous playbook

- import_playbook: pb-import.yml
  vars:
    var2: play3

- import_playbook: pb-import.yml

give

PLAY [host1,host2,host3] *********************************************************************

TASK [debug] *********************************************************************************
ok: [host1] => 
  msg: |-
    var1: 1
    var2: play3
    var3: global
    var4: included in a task
ok: [host2] => 
  msg: |-
    var1: 2
    var2: play3
    var3: global
    var4: included in a task
ok: [host3] => 
  msg: |-
    var1: 3
    var2: play3
    var3: global
    var4: undef

PLAY [host1,host2,host3] *********************************************************************

TASK [debug] *********************************************************************************
ok: [host1] => 
  msg: |-
    var1: 1
    var2: undef
    var3: global
    var4: included in a task
ok: [host2] => 
  msg: |-
    var1: 2
    var2: undef
    var3: global
    var4: included in a task
ok: [host3] => 
  msg: |-
    var1: 3
    var2: undef
    var3: global
    var4: undef

Upvotes: 11

Anurag Guda
Anurag Guda

Reputation: 11

this will be the ideal solution if you want to run import playbook with when condition. where system_ip can defined in properties/variables.yml

- hosts: all
  gather_facts: yes
  vars_files:
    - properties/variables.yml
  tasks:
    - set_fact: 
        storage_system_ip: "{{ system_ip }}"
  
- import_playbook: create_CPG.yml
  when: "storage_system_ip == '192.168.0.2' and ansible_architecture == 'x86_64'"

Upvotes: 1

error404
error404

Reputation: 2823

The import_playbook module doesn't accept - include_vars as an argument.

- import_playbook: create_CPG.yml
- include_vars: properties/variables.yml

For calling include_vars specific you can use the include_vars module inside that playbook

Upvotes: 1

Related Questions