Ashar
Ashar

Reputation: 3065

Issue executing ansible play due to undefined variable in include_vars file

Below is my playbook:

  tasks:
   - name: Construct File Path on Destination Server.
     include_vars:
       file: "{{ item }}"
     with_fileglob:
        - "vars/myvars.yaml"

   - name: setting_facts for BackEnd
     set_fact:
       fpath_BackEnd_APP: []
     set_fact:
       fpath_BackEnd_APP: "{{ fpath_BackEnd_APP + [ BASEPATH ~ '/' ~ vars[ (item | splitext)[1].split('.')[1] ] ~ '/' ~ item | basename ] }}"
     with_items:
       - "{{ Source_Filenames.split(',') }}"

Here is my variable file:

cat vars/myvars.yaml

com: /path/to/com/folder
src: /path/to/src/folder

The below playbook run works fine as expected.

ansible-playbook  /app/deploy.yml -e Source_Filenames=/app/testing_purpose.src,/app/testing_purpose.com

However, when I pass filename which do not have a dot(.) i.e no file extension the ansible play is not able to find the the variable in myvars.yaml and errors as below:

ansible-playbook  /app/deploy.yml -e Source_Filenames=/app/testing_purpose.src,/app/testing_purpose,/app/testing_purpose.com,/app/testing_moht

"The task includes an option with an undefined variable. The error was: list object has no element 1\n\nThe error appears to be in '/app/deploy.yml'"

My requirement is to allocate "/path/to/no-ext/folder" for variable "fpath_BackEnd_APP" incase a file without extension is passed. Files with extensions .com & .src work fine as they get the variable value substituted from the myvars.yml file. For any other file extensions like .jpg or .txt the playbook should fall with the variable undefined error. Any solution would be appreciated.

Upvotes: 0

Views: 2380

Answers (1)

Zeitounator
Zeitounator

Reputation: 44730

If you take as an entry /toto/pipo

$ ansible localhost -m debug -a "msg={{ (item | splitext) }}" -e item=/toto/pipo
localhost | SUCCESS => {
    "msg": "('/toto/pipo', '')"
}

$ ansible localhost -m debug -a "msg={{ (item | splitext)[1] }}" -e item=/toto/pipo
localhost | SUCCESS => {
    "msg": ""
}

$ ansible localhost -m debug -a "msg={{ (item | splitext)[1].split('.') }}" -e item=/toto/pipo
localhost | SUCCESS => {
    "msg": [
        ""
    ]
}

$ ansible localhost -m debug -a "msg={{ (item | splitext)[1].split('.')[1] }}" -e item=/toto/pipo
localhost | FAILED! => {
    "msg": "The task includes an option with an undefined variable. The error was: list object has no element 1"
}

Whereas, if you pass an entry containing an extension like /toto/pipo.test:

$ ansible localhost -m debug -a "msg={{ (item | splitext)[1].split('.')[1] }}" -e item=/toto/pipo.test
localhost | SUCCESS => {
    "msg": "test"
}

Meanwhile, you can set a default value when the expression itself does not return a value:

$ ansible localhost -m debug -a "msg={{ (item | splitext)[1].split('.')[1] | default('') }}" -e item=/toto/pipo
localhost | SUCCESS => {
    "msg": ""
}

Upvotes: 1

Related Questions