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!

  • Alexander Kutsyk@lemmy.world
    link
    fedilink
    English
    arrow-up
    1
    ·
    edit-2
    1 day 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.