this post was submitted on 24 Feb 2025
1 points (100.0% liked)

Ansible

320 readers
1 users here now

# TODO

founded 2 years ago
 

Hello everyone, I need some help with using variables in jinja templates.

Disclaimer: I am pretty new to ansible, so feel free to tell me that I understood something wrong.

What I'm trying to do

I try to use a variable inside a variable, that gets called from a jinja template

I have my network ranges defined in the global vars

networks:
  lclsrv:
    ipv4: 10.10.10.0/24
  ext:
    ipv4: 1234.123.123.12/x

Then I createt a role called "iptables", with which I would like to manage all iptables on all hosts. In its defaults, there are (obviously) the default_iptable_rules defined.

Besides them, there are host specific iptables, which are also defined in the defaults, like this e.g:

host1_rules:
  - "-A INPUT -p tcp --dport 80 -j ACCEPT"
  - "-A INPUT -p tcp --dport 443 -j ACCEPT"

In some of the host specific rules I have to define a network range from the global vars, like:

host2_rules: 
 - "-A INPUT -p tcp -s {{ networks['ext']['ipv4'] }} --dport 6000 -j ACCEPT"

In the template I try to insert these host specific rules like this:

{% for rule in vars[inventory_hostname + '_rules'] %}
{{rule}}
{% endfor %}

I think I understood, that this "structure" is not the recommended ansible way. Until now we got all host specific iptables organized in there host files, which is probably the clean way of doing this (?) But with lots of hosts this got very messy, so I want to manage them in one single file, to have them all together.

What I get

The for loop itself works as expected, but the variables won't get processed. The resulting /etc/iptables/rules.v4 for host2 will look exactly like this: -A INPUT -p tcp -s {{ networks['ext']['ipv4'] }} --dport 6000 -j ACCEPT

So the template get the element from the host specific variable as a string but won't interpret the variable inside of this string.

I looked at suggestions to use the lookup function, but this also did not work. When I replaced the variable inside of the rule-string with the lookup, the lookup-functiongot printed out, just like the variable in "{{}}".

I am struggling with this sinc last monday and I would appreciate any help! Tanks!

top 3 comments
sorted by: hot top controversial new old
[–] kutsyk_alexander@lemmy.world 0 points 9 months ago (1 children)

Which module do you use for inserting the template?

[–] dengtav@lemmy.ml 0 points 9 months ago (1 children)

The ansible.builtin.template

Just with the arguments src and dest

I saw that there is a possible argument template_variables which requires a dictionary, but I couldn't find out, how to use it, or whether to use it at all?

[–] kutsyk_alexander@lemmy.world 1 points 9 months ago* (last edited 9 months ago)

I try some tests based on your description, and I think I got a solution. Try to use host_vars

This is a playbook:

***
- name: Test for lemmy
  hosts: your_hosts
  vars:
    networks:
      ext:
        ipv4: "127.0.0.1"
  tasks:
    - name: Use template
      ansible.builtin.template:
        src: test.j2
        dest: "/etc/iptables/rules.v4"
        owner: root
        group: root
        mode: "0644"

This is a template file test.j2:

{% for rule in rules %}
{{ rule }}
{% endfor %}

This is a host2.yml file in a host_vars directory:

***
rules:
  - "-A INPUT -p tcp -s {{ networks['ext']['ipv4'] }} --dport 6000 -j ACCEPT"

For another hosts you can create separate host files with variable rules.