Aldamova
Aldamova

Reputation: 3

How to use a list of jinja templates store in a YML file with a Playbook?

I need help because i'm stuck since 2 days with a playbook.

First of all, i have a YAML file which contains jinja templates :

---
template lab:
 - first_template.j2
 - second_template.j2
 - third_template.j2

It exists a YAML file which have value for each router, stores in "./yml/{{ inventory_hostname }}.yml"

I have a playbook Ansible which needs to use jinja templates for generate a .conf file.

---
- name: Generate .conf file
  hosts: my_routers
  gather_facts: no
  vars: 
  - jinja_templates: "{{ (lookup('template', './template_list.yml') | from_yaml).template_lab }}"
  vars_files: 
  - "./yml/{{ inventory_hostname }}.yml"
  
  tasks:
    - name: test
      debug:
        msg: "{{ jinja_templates }}"
    - name: Generate configuration files
      template:
        src: "./templates/{{ jinja_templates }}"
        dest: "./tmp/general/{{ inventory_hostname }}.conf"
        mode: "0644"

OUTPUT of the playbook when i play it :

Could not find or access './templates/['first_template.j2', 'second_template.j2', 'third_template'.j2']'

1 : The first issue is that { jinja_templates }} output contains "[" "]" and "'" "'", so it is impossible for Ansible to use the Jinja Templates.

2 : How can i do an interation for use all jinja templates and generate configuration in a single file ?

I know that i don't use the correct structure of Ansible' Playbook ! It is for the moment experimental test :)

Thank you

Upvotes: 0

Views: 440

Answers (2)

Vladimir Botka
Vladimir Botka

Reputation: 68024

Q: "Use all jinja templates and generate configuration in a single file."

A: Iterate the list of templates and create content. For example, given the tree

shell> tree .
.
├── ansible.cfg
├── hosts
├── pb.yml
├── template_list.yml
└── templates
    ├── first_template.j2
    ├── second_template.j2
    └── third_template.j2
shell> cat hosts
[my_routers]
test_11
test_12
test_13
shell> cat template_list.yml
template_list:
  - first_template.j2
  - second_template.j2
  - third_template.j2
shell> cat templates/first_template.j2 
Content of the 1 template.

shell> cat templates/second_template.j2 
Content of the 2 template.

shell> cat templates/third_template.j2 
Content of the 3 template.

The playbook

shell> cat pb.yml 
- hosts: my_routers
  vars_files:
    template_list.yml
  tasks:
    - copy:
        dest: "/tmp/{{ inventory_hostname }}.conf"
        content: |
          {% for file in template_list %}
          {{ lookup('template', file) }}
          {%- endfor %}

will create the files

shell> ssh admin@test_11 cat /tmp/test_11.conf
Content of the 1 template.
Content of the 2 template.
Content of the 3 template.

shell> ssh admin@test_12 cat /tmp/test_12.conf
Content of the 1 template.
Content of the 2 template.
Content of the 3 template.

shell> ssh admin@test_13 cat /tmp/test_13.conf
Content of the 1 template.
Content of the 2 template.
Content of the 3 template.

Upvotes: 2

Khaled
Khaled

Reputation: 838

You're passing the template files names as one line:

- debug:
   msg: "{{ jinja_templates }}"

The output is being an array:

TASK [test] *******************************************************************************
ok: [localhost] => {
    "msg": [
        "first_template.j2",
        "second_template.j2",
        "third_template.j2"
    ]
}

You should loop over it to get them as single values:

- debug:
   msg: "{{ item }}"
  loop: "{{ jinja_templates }}"
TASK [test] *******************************************************************************
ok: [localhost] => (item=first_template.j2) => {
    "msg": "first_template.j2"
}
ok: [localhost] => (item=second_template.j2) => {
    "msg": "second_template.j2"
}
ok: [localhost] => (item=third_template.j2) => {
    "msg": "third_template.j2"
}

Besides that you defined the same destination file in your template task dest: "./tmp/general/{{ inventory_hostname }}.conf".
That would lead to only writing the last template file.

Upvotes: 0

Related Questions