Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extra spaces appearing in Ansible templates

I am generating config files and I want them to be indented just so. I started with a Jinja2 template that rendered correctly when called from a simple python program. When I call it from ansible, I will get 2 extra spaces on all but the first line of the loop. Generating things like YAML and python has been a real pain. I have taken to putting a comment line as the first line of a for block to fix this...

Here is a really simple example of a YAML generator:

playbook call:

  - name: generate bgp vars file, put in includes directory
    local_action: template src={{ role_dir }}/templates/bgp_vars.j2 dest={{ incvar_dir }}/bgp_vars.yaml
    run_once: true

section of template:

dc_route_reflectors:
{% for dc in SH_dcs %}
# dc is "{{ dc }}"
  {{ dc }}:
  {% for host in groups[bgpgroupname] if dc == hostvars[host].MYDC %}
    - "{{ hostvars[host].MAIN_MYADDR }}"
  {% endfor %}
{% endfor %}

rendered output:

dc_route_reflectors:

# dc is "pnp"
  pnp:
      - "10.100.16.3"
      - "10.100.32.3"
  # dc is "sgs"
  sgs:
      - "10.8.0.3"
      - "10.8.16.3"
  # dc is "cst"
  cst:
      - "10.4.0.3"
      - "10.4.16.3"
  # dc is "dse"
  dse:
      - "10.200.0.3"
      - "10.200.16.3"

Notice how the dc is "pnp" comment is not indented as it is shown in the template, but sgs,cst and dse comments are indented by 2 spaces. All of the array lines of ip addresses are also indented. I have tried various versions of adding "-" to the "%" things as Jinja2 describes, but none have given consistent correct results.

Others must have seen this before. I'm running 2.2.1.0 on CentOS7.

like image 938
JerryS Avatar asked Mar 20 '17 21:03

JerryS


People also ask

How do you get rid of whitespace in Jinja?

Jinja2 allows us to manually control generation of whitespaces. You do it by using a minus sing - to strip whitespaces from blocks, comments or variable expressions. You need to add it to the start or end of given expression to remove whitespaces before or after the block, respectively.

How do you trim space in Ansible?

FreeKB - Ansible Remove whitespace using the trim filter. trim is a Jinja2 filter, used to remove whitespace from the left and right sides of a string. In this example, " hello world " will be trimmed. Which should return the following.

How are parameters used in template files in Ansible?

A template in Ansible is a file which contains all your configuration parameters, but the dynamic values are given as variables. During the playbook execution, depending on the conditions like which cluster you are using, the variables will be replaced with the relevant values.

What is Jinja2 template in Ansible?

Jinja2 templates are simple template files that store variables that can change from time to time. When Playbooks are executed, these variables get replaced by actual values defined in Ansible Playbooks. This way, templating offers an efficient and flexible solution to create or alter configuration file with ease.


Video Answer


1 Answers

For a start, you can just remove the spaces you explicitly added in front of your statements and keep indentation only for the data:

dc_route_reflectors: {% for dc in SH_dcs %} # dc is "{{ dc }}"   {{ dc }}: {% for host in groups[bgpgroupname] if dc == hostvars[host].MYDC %}     - "{{ hostvars[host].MAIN_MYADDR }}" {% endfor %} {% endfor %} 

If you want to keep indentation of the statements, you can set lstrip_blocks option to True (notice: the declaration must be in the first line of the template):

#jinja2:lstrip_blocks: True dc_route_reflectors: {% for dc in SH_dcs %} # dc is "{{ dc }}"   {{ dc }}:   {% for host in groups[bgpgroupname] if dc == hostvars[host].MYDC %}     - "{{ hostvars[host].MAIN_MYADDR }}"   {% endfor %} {% endfor %} 

Read more about whitespace control in Jinja2.


Ansible runs Jinja2 with trim_blocks enabled and lstrip_blocks disabled.

All the spaces you typed into the template (outside of the statements and expressions) are thus considered a part of the output. No "extra spaces" are added.

Notice how the dc is "pnp" comment is not indented as it is shown in the template, but sgs, cst and dse comments are indented by 2 spaces.

These two spaces are included in your template in the 7th line (before {% endfor %}).

All of the array lines of ip addresses are also indented.

These spaces are defined in your template in the 5th line (in front of the {% for host).

like image 101
techraf Avatar answered Sep 23 '22 17:09

techraf