ansible template error while templating string: no filter named 'product'

Viewed 13317

I have the below playbook works fine in ansible 2.9.6 version. But it throws the error while running on ansible 2.4.2.0 version. my requirement is to use the {{ applog }} variable in my configuration yaml file with proper indentation and line break.

templates\appconfig.yml.j2

paths: {{ applog | indent (width=4, indentfirst=True) }} 

The output of appconfig.yml

    paths: 
       - /home/ketg/apps/ketg_DEV/logs/*.log
       - /home/ketg/apps/ketg_UAT/logs/*.log
       - /home/teng/apps/ketg_PT/logs/*.log

playbook to work on both versions. can someone help

sample-playbook

- hosts: localhost
  vars:
    app_log_paths: "/home/ketg/apps/ketg_DEV/logs/*.log,/home/ketg/apps/ketg_UAT/logs/*.log,/home/teng/apps/ketg_PT/logs/*.log"
 
  tasks:
    - set_fact:
        logs: "{{ app_log_paths.split(',') }}"
    - set_fact:
        applogs: "{{ ['- '] | product(logs) | map ('join') | list }}"
    - set_fact:
        applog: "{{ applogs | join('\n') }}"
    - debug:
        msg: "{{ applog }}"

Output ansible 2.9.6

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

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************
ok: [localhost]

TASK [set_fact] ***************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [set_fact] ***************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [set_fact] ***************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [debug] ******************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "- /home/ketg/apps/ketg_DEV/logs/*.log\n- /home/ketg/apps/ketg_UAT/logs/*.log\n- /home/teng/apps/ketg_PT/logs/*.log"
}

PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost                  : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Output ansible 2.4.2.0

TASK [set_fact] ********************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "template error while templating string: no filter named 'product'. String: {{ ['- '] | product(logs) | map ('join') | list }}"}
1 Answers

In templates\appconfig.yml.j2 loop over the result of splitting app_log_paths on commas and template in the array items as shown below. This should provide the result you're looking for.

You also shouldn't need all of that set_fact logic any longer.

Tested locally on my machine and this behaves as expected. Let me know if it works for you.

paths:
{% for path in app_log_paths.split(',') %}
    - {{ path }}
{% endfor %}
Related