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!

  • dengtav@lemmy.mlOP
    link
    fedilink
    English
    arrow-up
    1
    ·
    2 days ago

    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?

    • 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.