2

I have an ansible playbook which requires a JSON file to be passed as a --extra-vars (or -e ) from the command line. I would like to know if there is any way that I can add a validation task in my playbook to confirm that such a file is passed.

I have checked hostvars and did not find any parameter that stores such value or name of the file. It directly loaded the variables present inside the file.

I tried echo !! (to fetch the command history) using command and shell modules which didn't work either.

Sample command

ansible-playbook test.yml -e@input_vars.json

I want a task that will fail the execution if the JSON file is not passed in --extra-vars. Is it possible?

U880D
  • 8,601
  • 6
  • 24
  • 40
Pazuzu
  • 70
  • 6
  • Can you just check if expected variables are defined? (task that prints failure can have conditional `when: my_var is undefined`) – Bojan Komazec Jul 11 '22 at 10:35
  • Yes, that I'm already doing. I wanted to know if it's possible to check if some JSON file is being passed from the command line. – Pazuzu Jul 11 '22 at 10:37

2 Answers2

1

There is no method, function, lookup plugin, special variable, etc. to find out where a variable comes from. Without knowing the run-string you also can't tell whether extra variables are used or not.

The simplest method to determine whether extra variables are used might be based on the fact that extra vars are the highest precedence. For example, test if extra vars overrode a variable

shell> cat input_vars.yml
extra_vars: true
var1: foo
var2: bar

Declare the variable extra_vars also in the playbook

shell> cat test.yml
- hosts: localhost
  vars:
    extra_vars: false
  tasks:
    - assert:
        that: extra_vars|bool
        fail_msg: Extra vars missing. End of play.
    - debug:
        msg: |
          var1: {{ var1 }}
          var2: {{ var2 }}

The playbook fails if you run it without extra vars

shell> ansible-playbook test.yml

PLAY [localhost] *****************************************************************************

TASK [assert] ********************************************************************************
fatal: [localhost]: FAILED! => changed=false 
  assertion: extra_vars|bool
  evaluated_to: false
  msg: Extra vars missing. End of play.

The playbook will continue if extra vars are used

shell> ansible-playbook test.yml -e@input_vars.yml

PLAY [localhost] *****************************************************************************

TASK [assert] ********************************************************************************
ok: [localhost] => changed=false 
  msg: All assertions passed

TASK [debug] *********************************************************************************
ok: [localhost] => 
  msg: |-
    var1: foo
    var2: bar
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63
  • I'm already doing validation of the vars inside the file. I was just looking for a way to validate the argument passed which is .json and not the vars inside. Sounds like it's not really possible. – Pazuzu Jul 12 '22 at 05:28
1

Even if it is not possible to find out where and when a variable was defined, it might be possible to check the content of the CLI option(s).

Whereby for the CLI options --tags, --skip-tags and --limit the Special Variables ansible_run_tags, ansible_skip_tags and ansible_limit are available, to access the command line argument --extra-vars used to invoke Ansible one would need to drop a tiny Custom Action Plugin.

After that a sample playbook

---
- hosts: test
  become: false
  gather_facts: true

  tasks:

  - name: Gather Arguments Values
    get_argv:

  - name: Show values
    debug:
      msg: "{{ ansible_facts.argv }}"

called via

ansible-playbook --extra-vars="test=test" extraVars.yml

results into an output of

TASK [Show values] *************
ok: [test.example.com] =>
  msg:
  - /usr/bin/ansible-playbook
  - --extra-vars=test=test
  - extraVars.yml

... if there is any way that I can add a validation task in my playbook to confirm that such a file is passed ... I want a task that will fail the execution if the JSON file is not passed in --extra-vars ...

You would need than just to include a check of the Ansible facts and Conditionals based on ansible_facts.

Further Documentation


The above approach gives also the opportunity to check for multiple extra vars files like in the problem What is the variable order/precedence in case of multiple 'extra_vars' files?

ansible-playbook extraVars.yml --extra-vars="test=test" -e="test=TEST"

resulting into an output of

TASK [Show values] *************
ok: [test.example.com] =>
  msg:
  - /usr/bin/ansible-playbook
  - extraVars.yml
  - --extra-vars=test=test
  - -e=test=TEST

TASK [Show content of var 'test'] *************
ok: [test.example.com] =>
  msg: TEST
U880D
  • 8,601
  • 6
  • 24
  • 40