1

I have wrote the jinja2 template for ansible playbook. However, i dont want the comma at the end of last line for that reason, i have used the "if" condition with "loop.last". Since there is "for" loop and "if" loop, last line is executing two times - one with comma and another without comma. any help would be appreciated for the last line to be executed once without comma.

  [{% for ip in range  %}
  "127.0.0.1:{{ ip }}",
     {% if loop.last %}
       "127.0.0.1:{{ ip }}"
     {% endif %}
  {% endfor %}]

Below is the output that i am getting,

[  "127.0.0.1:6000",
         "127.0.0.1:6001",
         "127.0.0.1:6002",
         "127.0.0.1:6003",
         "127.0.0.1:6004",
         "127.0.0.1:6005",
         "127.0.0.1:6006",
            "127.0.0.1:6006"
       ]

Expected output:

  ["127.0.0.1:6000", "127.0.0.1:6001", "127.0.0.1:6002", "127.0.0.1:6003", "127.0.0.1:6004", "127.0.0.1:6005", "127.0.0.1:6006" ]

Thanks

learning fun
  • 519
  • 1
  • 5
  • 12

2 Answers2

3

you could add an else clause for the non last iterations. try this template file:

[{% for ip in range  %}
{% if loop.last %}
"127.0.0.1:{{ ip }}"{% else %}
"127.0.0.1:{{ ip }}", {% endif %}
{% endfor %}]

produced file:

[root@greenhat-30 tests]$ cat /tmp/test.out         
["127.0.0.1:6001", "127.0.0.1:6002", "127.0.0.1:6003", "127.0.0.1:6004", "127.0.0.1:6005", "127.0.0.1:6006"]
[root@greenhat-30 tests]$ 

hope it helps

ilias-sp
  • 6,135
  • 4
  • 28
  • 41
0
  1. You should be extra careful with your var name. range is actually a jinja2 function and might cause errors on occasion.
  2. Your current problem basically comes down to transforming an input list by adding a prefix and outputting the result as a json string.

In the below example:

  • The initial range(6001,6007) dynamically replaces your current var with the same number of values (for the example). You can simply replace this function with your renamed variable containing your actual list of values (see point 1 above).
  • I use the regex_replace filter with map to prepend 127.0.0.1: to each value in the list.
  • Finally, I use the to_json filter to output the list to the desired format.

Final template:

{{ range(6001,6007) | map('regex_replace','^', '127.0.0.1:') | list | to_json }}

We can easily test that with an ansible debug task:

---
- name: Demo template
  hosts : localhost
  gather_facts: false

  tasks:

    - name: Add prefix to range list and output json
      debug:
        msg: "{{ range(6001,6007) | map('regex_replace','^', '127.0.0.1:') | list | to_json }}"

Which gives (Note: backslashes are added by debug to escape double quotes in the result string. Actual output in the result template will not contain them.)

PLAY [Demo template] ****************************************************************************************************************************************************************************************************************************************************

TASK [Add prefix to range list and output json] *************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "[\"127.0.0.1:6001\", \"127.0.0.1:6002\", \"127.0.0.1:6003\", \"127.0.0.1:6004\", \"127.0.0.1:6005\", \"127.0.0.1:6006\"]"
}

PLAY RECAP **************************************************************************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
Zeitounator
  • 38,476
  • 7
  • 53
  • 66