Home > Enterprise >  Ansible: Hierarchical templating, first found
Ansible: Hierarchical templating, first found

Time:09-29

repo/
├─ cells/
│  ├─ cell1/
│  │  ├─ enabled-sites/
│  │  │  ├─ example2.conf
│  │  │  ├─ example1.conf
│  │  ├─ site.conf
├─ workgroups/
│  ├─ wg1/
│  │  ├─ enabled-sites/
│  │  │  ├─ example3.conf
│  │  │  ├─ example4.conf
│  │  │  ├─ example5.conf
│  │  ├─ site.conf

I'm trying to write a role which will template the first things it finds

All the above would exist on the ansible host not the remote

So in the above example if repo/cells/cell1/enabled-sites contains files they'll be templated to a remote machine

If they don't exist it would look for repo/cells/cell1/site.conf which would be templated

If that didn't exist it would look for files in repo/workgroups/wg1/enabled-sites

If that didn't exist if would look for ropo/workgroups/wg1/site.conf

Finally if none of those exist it would use the roles template site.conf

- name: Configure | Find first enabled-sites
  find:
    paths: "{{ item }}"
  with_first_found:
    - "{{ cvs_path }}/scripts/def/cells/{{ grouping.name }}/enabled-sites/"
    - "{{ cvs_path }}/scripts/def/cells/{{ grouping.name }}/site.conf"
    - "{{ cvs_path }}/scripts/def/workgroups/{{ grouping.workgroup }}/enabled-sites/"
    - "{{ cvs_path }}/scripts/def/cells/{{ grouping.name }}/site.conf"
    - "../templates/site.conf"
  register: esites
  delegate_to: localhost
  run_once: true

- name: Configure | Template out found cell specific enabled-sites
  template:
     src: "{{ item.path }}"
     dest: "{{ httpd_home }}/conf/enabled-sites/{{ item.path | basename }}"
  with_items: "{{ esites.results | map(attribute='files') | list }}"

This only works for the directories, the find doesn't work on files

CodePudding user response:

There seems to be another option within "with_first_found" loop. Please have a look at bellow example

- name: Include tasks only if one of the files exist, otherwise skip the task
  ansible.builtin.include_tasks:
    file: "{{ item }}"
  with_first_found:
    - files:
      - path/tasks.yaml
      - path/other_tasks.yaml

There is another attribute as "paths" similar to "files" not sure can we combine them together. https://docs.ansible.com/ansible/latest/collections/ansible/builtin/first_found_lookup.html

CodePudding user response:

The best I've come up with is:

- name: Configure | Find first enabled-sites
  find:
    paths: "{{ item }}"
  with_first_found:
    - "{{ cvs_path }}/scripts/def/cells/{{ grouping.name }}/enabled-sites/"
    - "{{ cvs_path }}/scripts/def/workgroups/{{ grouping.workgroup }}/enabled-sites/"
  register: esites
  delegate_to: localhost
  run_once: true
  ignore_errors: true

- name: Configure | Template out found cell specific enabled-sites
  template:
     src: "{{ item.path }}"
     dest: "{{ httpd_home }}/conf/enabled-sites/{{ item.path | basename }}"
  with_items: "{{ esites.results | map(attribute='files') | list }}"
  when: esites.results is defined

- name: Configure | Template out single site.conf
  template:
     src: "{{ item }}"
     dest: "{{ httpd_home }}/conf/enabled-sites/{{ grouping.environment }}{{ grouping.workgroup }}.conf"
  with_first_found:
    - "{{ cvs_path }}/scripts/def/cells/{{ grouping.name }}/site.conf"
    - "{{ cvs_path }}/scripts/def/workgroups/{{ grouping.workgroup }}/site.conf"
    - "site.conf"
  when: esites.results is not defined

It doesn't quite get the ordering correct but gets the job done

  • Related