How to ignore first iteration in loop Jinja2

1/31/2022

I am trying to templatize a file. But I need to leave the name unchanged in the first iteration, this is necessary for backward compatibility in the production environment.
How to ignore first iteration in loop Jinja2

Is it possible to do this. Or is there some clever trick in Jinja2?

Example:

# VARS
db_hosts: HOST1,HOST2
db_port: 6666,6667
# TEMPLATE
{% if db_enabled == true %}
{% set list_host = vars['db_hosts'].split(',') %}
{% set list_port = (vars['db_port'] | string).split(',') %}
{% for item_host in list_host %}
{% set item_port = list_port[loop.index-1] %}
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: db-se-tcp{{ loop.index }}(DO NOT INSERT INDEX HERE FOR FIRST ITERATION) 
spec:
  exportTo:
    - .
  hosts:
    - {{ item_host }}
  location: MESH_EXTERNAL
  resolution: DNS
  ports:
    - name: db-postgeSQL-{{ loop.index }}
      number: {{ item_port }}
      protocol: TCP
---
{% endfor %}
{% endif %}
# AFTER TEMPLATING
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: db-se-tcp(DO NOT INSERT INDEX HERE)
spec:
  exportTo:
    - .
  hosts:
    - HOST1
  location: MESH_EXTERNAL
  resolution: DNS
  ports:
    - name: db-postgeSQL-1
      number: 6666
      protocol: TCP
---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: db-se-tcp1 (in subsequent iterations insert the index)
spec:
  exportTo:
    - .
  hosts:
    - HOST2
  location: MESH_EXTERNAL
  resolution: DNS
  ports:
    - name: db-postgeSQL-2
      number: 6667
      protocol: TCP
---
-- Ivan Kostin
ansible
istio
jinja2
kubernetes

1 Answer

1/31/2022

You can use the special variable loop.first inside a for-loop and assert on it.

Given:

{% set list = ['one', 'two', 'three', 'four', 'five'] %}
{% for item in list %}
  name: db-se-tcp{% if not loop.first %}{{ loop.index }}{% endif %}            
{% endfor %}

This gives:

name: db-se-tcp
name: db-se-tcp2
name: db-se-tcp3
name: db-se-tcp4
name: db-se-tcp5

Or, even shorter, you can use an inline if expression:

{% set list = ['one', 'two', 'three', 'four', 'five'] %}
{% for item in list %}
  name: db-se-tcp{{ loop.index if not loop.first }}
{% endfor %}
-- β.εηοιτ.βε
Source: StackOverflow