Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can the templates module handle multiple templates / directories?

I believe the Ansible copy module can take a whole bunch of "files" and copy them in one hit. This I believe can be achieved by copying a directory recursively.

Can the Ansible template module take a whole bunch of "templates" and deploy them in one hit? Is there such a thing as deploying a folder of templates and applying them recursively?

like image 675
danday74 Avatar asked Jan 16 '17 00:01

danday74


People also ask

What is the use of template module in Ansible?

The template module also copies a file to a remote server, but it allows you to use Jinja2 to render a template to a file dynamically. This enables you to use variables, such as Ansible facts, to customize a particular file for a specific server.

What is difference between copy and template modules in Ansible?

While very similar, template serves an extra function. copy takes a file from host, "as-is", and copies it to the remote destination.

Where are Ansible templates stored?

Templates usually are stored under “templates” directories with “. j2” file extension. The “dest” parameter specifies the path where to render the template on the remote machine. The “validate” parameters allow you to specify the validation command to run before copying it into place.

What extension do the template files in Ansible have?

Usually, the template files will have the . j2 extension, which denotes the Jinja2 templating engine used.


4 Answers

The template module itself runs the action on a single file, but you can use with_filetree to loop recursively over a specified path:

- name: Ensure directory structure exists
  ansible.builtin.file:
    path: '{{ templates_destination }}/{{ item.path }}'
    state: directory
  with_community.general.filetree: '{{ templates_source }}'
  when: item.state == 'directory'

- name: Ensure files are populated from templates
  ansible.builtin.template:
    src: '{{ item.src }}'
    dest: '{{ templates_destination }}/{{ item.path }}'
  with_community.general.filetree: '{{ templates_source }}'
  when: item.state == 'file'

And for templates in a single directory you can use with_fileglob.

like image 95
techraf Avatar answered Oct 12 '22 23:10

techraf


I could not manage to do it with the other answers. This is what worked for me:

- name: Template all the templates and place them in the corresponding path
  template:
    src: "{{ item.src }}"
    dest: "{{ destination_path }}/{{ item.path | regex_replace('\\.j2$', '') }}"
    force: yes
  with_filetree: '{{ role_path }}/templates'
  when: item.state == 'file'
like image 43
Samuryte Avatar answered Oct 12 '22 22:10

Samuryte


This answer provides a working example of the approach laid down by @techraf

with_fileglob expects only files to live within the templates folder - see https://serverfault.com/questions/578544/deploying-a-folder-of-template-files-using-ansible

with_fileglob will only parse files in the templates folder

with_filetree maintains the directory structure when moving the template files to dest. It auto creates those directories for you at dest.

with_filetree will parse all files in the templates folder and nested directories

- name: Approve certs server directories
  file:
    state: directory
    dest: '~/{{ item.path }}'
  with_filetree: '../templates'
  when: item.state == 'directory'

- name: Approve certs server files
  template:
    src: '{{ item.src }}'
    dest: '~/{{ item.path }}'
  with_filetree: '../templates'
  when: item.state == 'file'

Essentially, think of this approach as copying and pasting a directory and all its contents from A to B and whilst doing so, parsing all templates.

like image 13
danday74 Avatar answered Oct 12 '22 23:10

danday74


In my case folder contain both files and jinja2 templates.

- name: copy all directories recursively
  file: dest={{templates_dest_path}}/{{ item|replace(templates_src_path+'/', '') }}  state=directory       
  with_items: "{{ lookup('pipe', 'find '+ templates_src_path +'/ -type d').split('\n') }}"

- name: copy all files recursively
  copy: src={{ item }} dest={{templates_dest_path}}/{{ item|replace(templates_src_path+'/', '') }} 
  with_items: "{{ lookup('pipe', 'find '+ templates_src_path +'/  -type f -not -name *.j2 ').split('\n') }}"
  
- name: copy templates files recursively
  template: src={{ item }} dest={{templates_dest_path}}/{{ item|replace(templates_src_path+'/', '')|replace('.j2', '') }}  
  with_items: "{{ lookup('pipe', 'find '+ templates_src_path +'/*.j2 -type f').split('\n') }}"
like image 3
Sunil Shakya Avatar answered Oct 12 '22 21:10

Sunil Shakya