Tasks

main.yml

Synopsis: Main task.

Import tasks if enabled.

[tasks/main.yml]

 1---
 2# tasks for config_light
 3
 4- name: Import setup.yml
 5  ansible.builtin.import_tasks: setup.yml
 6  when: cl_setup|bool
 7  delegate_to: localhost
 8  run_once: true
 9  tags: [cl_setup, always]
10
11- name: Import vars.yml
12  ansible.builtin.import_tasks: vars.yml
13  tags: [cl_vars, always]
14
15- name: Import sanity.yml
16  ansible.builtin.import_tasks: sanity.yml
17  when: cl_sanity|bool
18  delegate_to: localhost
19  run_once: true
20  tags: [cl_sanity, always]
21
22- name: Import debug.yml
23  ansible.builtin.import_tasks: debug.yml
24  when: cl_debug|bool
25  tags: cl_debug
26
27- name: Import packages.yml
28  ansible.builtin.import_tasks: packages.yml
29  when: cl_install|bool
30  tags: cl_packages
31
32- name: Import states.yml
33  ansible.builtin.import_tasks: states.yml
34  tags: cl_states
35
36- name: Import files.yml
37  ansible.builtin.import_tasks: files.yml
38  tags: cl_files
39
40- name: Import services.yml
41  ansible.builtin.import_tasks: services.yml
42  tags: cl_services
43
44# EOF
45...

setup.yml

Synopsis: Configure setup.

Description of the task.

[tasks/setup.yml]

  1---
  2
  3- name: "setup: Debug"
  4  vars:
  5    msg: |-
  6      cl_dird: {{ cl_dird }}
  7      cl_dird_owner: {{ cl_dird_owner|default('UNDEFINED') }}
  8      cl_dird_group: {{ cl_dird_group|default('UNDEFINED') }}
  9      cl_dird_dmode: {{ cl_dird_dmode }}
 10
 11      cl_handlersd_dir: {{ cl_handlersd_dir }}
 12      cl_packagesd_dir: {{ cl_packagesd_dir }}
 13      cl_servicesd_dir: {{ cl_servicesd_dir }}
 14      cl_filesd_dir: {{ cl_filesd_dir }}
 15      cl_statesd_dir: {{ cl_statesd_dir }}
 16
 17      cl_dira: {{ cl_dira }}
 18      cl_dira_owner: {{ cl_dira_owner|default('UNDEFINED') }}
 19      cl_dira_group: {{ cl_dira_group|default('UNDEFINED') }}
 20      cl_dira_dmode: {{ cl_dira_dmode }}
 21      cl_dira_fmode: {{ cl_dira_fmode }}
 22      cl_assemble_regexp: {{ cl_assemble_regexp }}
 23
 24      cl_handlersd: {{ cl_handlersd }}
 25      cl_packagesd: {{ cl_packagesd }}
 26      cl_servicesd: {{ cl_servicesd }}
 27      cl_filesd: {{ cl_filesd }}
 28      cl_statesd: {{ cl_statesd }}
 29
 30      cl_handlers_delete_all: {{ cl_handlers_delete_all }}
 31      cl_handlers_delete: {{ cl_handlers_delete }}
 32      cl_handlers_create: {{ cl_handlers_create }}
 33      cl_handlers_dir_become: {{ cl_handlers_dir_become }}
 34      cl_handlers_dir_owner: {{ cl_handlers_dir_owner|default('UNDEFINED') }}
 35      cl_handlers_dir_group: {{ cl_handlers_dir_group|default('UNDEFINED') }}
 36      cl_handlers_dir_dmode: {{ cl_handlers_dir_dmode|default('UNDEFINED') }}
 37      cl_handlers_main_mode: {{ cl_handlers_main_mode|default('UNDEFINED') }}
 38
 39      cl_all_delete: {{ cl_all_delete }}
 40      cl_packagesd_delete: {{ cl_packagesd_delete }}
 41      cl_servicesd_delete: {{ cl_servicesd_delete }}
 42      cl_filesd_delete: {{ cl_filesd_delete }}
 43      cl_statesd_delete: {{ cl_statesd_delete }}
 44
 45  ansible.builtin.debug:
 46    msg: "{{ '{}'.format(msg) }}"
 47  when: cl_debug|bool
 48
 49# directories
 50- name: "setup: Create directories in {{ cl_dird }}"
 51  ansible.builtin.file:
 52    state: directory
 53    path: "{{ item }}"
 54    owner: "{{ cl_dird_owner|default(omit) }}"
 55    group: "{{ cl_dird_group|default(omit) }}"
 56    mode: "{{ cl_dird_dmode }}"
 57  loop:
 58    - "{{ cl_dird }}"
 59    - "{{ cl_handlersd_dir }}"
 60    - "{{ cl_packagesd_dir }}"
 61    - "{{ cl_servicesd_dir }}"
 62    - "{{ cl_filesd_dir }}"
 63    - "{{ cl_statesd_dir }}"
 64
 65- name: "setup: Create directory {{ cl_dira }}"
 66  ansible.builtin.file:
 67    state: directory
 68    path: "{{ cl_dira }}"
 69    owner: "{{ cl_dira_owner|default(omit) }}"
 70    group: "{{ cl_dira_group|default(omit) }}"
 71    mode: "{{ cl_dira_dmode }}"
 72
 73# handlers
 74- name: "setup: Create dir {{ role_path }}/handlers"
 75  become: "{{ cl_handlers_dir_become }}"
 76  ansible.builtin.file:
 77    state: directory
 78    path: "{{ role_path }}/handlers"
 79    owner: "{{ cl_handlers_dir_owner|default(omit) }}"
 80    group: "{{ cl_handlers_dir_group|default(omit) }}"
 81    mode: "{{ cl_handlers_dir_dmode|default(omit) }}"
 82
 83- name: "setup: Create handlers/main.yml"
 84  ansible.builtin.lineinfile:
 85    path: "{{ role_path }}/handlers/main.yml"
 86    insertbefore: BOF
 87    line: "---"
 88    validate: "{{ cl_handlers_validate|default(omit) }}"
 89    backup: "{{ cl_backup }}"
 90    create: true
 91    mode: "{{ cl_handlers_main_mode|default(omit) }}"
 92
 93- name: "setup: Assemble handlers"
 94  ansible.builtin.import_tasks: vars-handlers.yml
 95
 96- name: "setup: Delete all handlers"
 97  block:
 98
 99    - name: "setup: Find all handlers"
100      ansible.builtin.find:
101        path: "{{ role_path }}/handlers"
102        patterns: handlers-auto-*.yml
103      register: result
104
105    - name: "setup: Debug result"
106      ansible.builtin.debug:
107        var: result
108      when: cl_debug|bool
109
110    - name: "setup: Delete all handlers"
111      ansible.builtin.file:
112        state: absent
113        path: "{{ item.path }}"
114      loop: "{{ result.files }}"
115      loop_control:
116        label: "{{ item.path|basename }}"
117
118    - name: "setup: Exclude all found handlers from handlers/main.yml"
119      ansible.builtin.lineinfile:
120        state: absent
121        path: "{{ role_path }}/handlers/main.yml"
122        line: "- import_tasks: {{ item.path|basename }}"
123        backup: "{{ cl_backup }}"
124      loop: "{{ result.files }}"
125      loop_control:
126        label: "{{ item.path|basename }}"
127
128  when: cl_handlers_delete_all|bool
129
130- name: "setup: Delete handlers listed in cl_handlers"
131  block:
132
133    - name: "setup: Delete handlers listed in cl_handlers"
134      ansible.builtin.file:
135        state: absent
136        path: "{{ role_path }}/handlers/handlers-auto-{{ item.key }}.yml"
137      loop: "{{ cl_handlers|dict2items }}"
138      loop_control:
139        label: "{{ role_path }}/handlers/handlers-auto-{{ item.key }}.yml"
140
141    - name: "setup: Exclude handlers from handlers/main.yml"
142      ansible.builtin.lineinfile:
143        state: absent
144        path: "{{ role_path }}/handlers/main.yml"
145        line: "- import_tasks: handlers-auto-{{ item.key }}.yml"
146        backup: "{{ cl_backup }}"
147      loop: "{{ cl_handlers|dict2items }}"
148      loop_control:
149        label: "{{ role_path }}/handlers/handlers-auto-{{ item.key }}.yml"
150
151  when: cl_handlers_delete|bool
152
153- name: "setup: Create handlers listed in cl_handlers"
154  block:
155
156    - name: "setup: Create handlers listed in cl_handlers"
157      ansible.builtin.template:
158        dest: "{{ role_path }}/handlers/handlers-auto-{{ item.key }}.yml"
159        src: "{{ item.value.template }}"
160        mode: "{{ item.value.mode|default(omit) }}"
161        validate: "{{ cl_handlers_validate|default(omit) }}"
162        backup: "{{ cl_backup }}"
163      loop: "{{ cl_handlers|dict2items }}"
164      loop_control:
165        label: "{{ role_path }}/handlers/handlers-auto-{{ item.key }}.yml"
166
167    - name: "setup: Include handlers in handlers/main.yml"
168      ansible.builtin.lineinfile:
169        path: "{{ role_path }}/handlers/main.yml"
170        line: "- import_tasks: handlers-auto-{{ item.key }}.yml"
171        validate: "{{ cl_handlers_validate|default(omit) }}"
172        backup: "{{ cl_backup }}"
173      loop: "{{ cl_handlers|dict2items }}"
174      loop_control:
175        label: "{{ role_path }}/handlers/handlers-auto-{{ item.key }}.yml"
176
177  when: cl_handlers_create|bool
178
179# EOF
180...

vars-handlers.yml

Synopsis: Configure vars-handlers.

Description of the task.

[tasks/vars-handlers.yml]

 1---
 2
 3- name: Assemble handlers
 4  block:
 5
 6    - name: "vars-handlers: Assemble handlers to {{ cl_handlersd }}"
 7      ansible.builtin.assemble:
 8        regexp: "{{ cl_assemble_regexp }}"
 9        src: "{{ cl_handlersd_dir }}"
10        dest: "{{ cl_handlersd }}"
11        owner: "{{ cl_dira_owner|default(omit) }}"
12        group: "{{ cl_dira_group|default(omit) }}"
13        mode: "{{ cl_dira_fmode }}"
14        validate: "{{ cl_assemble_validate|default(omit, true) }}"
15
16  rescue:
17
18    - name: "vars-handlers: Assemble handlers to {{ cl_handlersd }} failed"
19      ansible.builtin.debug:
20        msg: |-
21          [ERR] Can not assemble handlers. End of play.
22          {{ ansible_failed_result }}
23
24    - name: "vars-handlers: End of play"
25      meta: end_play
26
27- name: "vars-handlers: Include files from {{ cl_handlersd }} to cl_handlersd_items"
28  ansible.builtin.include_vars:
29    file: "{{ cl_handlersd }}"
30    name: cl_handlersd_items
31
32- name: "vars-handlers: Combine cl_handlers with cl_handlersd_items"
33  ansible.builtin.set_fact:
34    cl_handlers: "{{ cl_handlers|combine(cl_handlersd_items|default({})) }}"
35
36- name: "vars-handlers: Debug"
37  ansible.builtin.debug:
38    var: cl_handlers
39  when: cl_debug|bool
40
41# EOF
42...

vars.yml

Synopsis: Configure vars.

Description of the task.

[tasks/vars.yml]

 1---
 2
 3- name: "vars: Debug"
 4  vars:
 5    msg: |-
 6      cl_packagesd_dir: {{ cl_packagesd_dir }}
 7      cl_statesd_dir: {{ cl_statesd_dir }}
 8      cl_servicesd_dir: {{ cl_servicesd_dir }}
 9      cl_filesd_dir: {{ cl_filesd_dir }}
10
11      cl_dira: {{ cl_dira }}
12      cl_packagesd: {{ cl_packagesd }}
13      cl_statesd: {{ cl_statesd }}
14      cl_servicesd: {{ cl_servicesd }}
15      cl_filesd: {{ cl_filesd }}
16
17      cl_all_delete: {{ cl_all_delete }}
18      cl_packagesd_delete: {{ cl_packagesd_delete }}
19      cl_servicesd_delete: {{ cl_servicesd_delete }}
20      cl_filesd_delete: {{ cl_filesd_delete }}
21      cl_statesd_delete: {{ cl_statesd_delete }}
22
23      cl_assemble_validate: {{ cl_assemble_validate|d(omit, true) }}
24  ansible.builtin.debug:
25    msg: "{{ '{}'.format(msg) }}"
26  when: cl_debug|bool
27
28- name: "vars: Packages"
29  ansible.builtin.import_tasks: vars-packages.yml
30
31- name: "vars: States"
32  ansible.builtin.import_tasks: vars-states.yml
33
34- name: "vars: Services"
35  ansible.builtin.import_tasks: vars-services.yml
36
37- name: "vars: Files"
38  ansible.builtin.import_tasks: vars-files.yml
39
40# EOF
41...

vars-packages.yml

Synopsis: Configure vars-packages.

Description of the task.

[tasks/vars-packages.yml]

 1---
 2
 3- name: Assemble packages
 4  block:
 5
 6    - name: "vars-packages: Delete {{ cl_packagesd }}"
 7      ansible.builtin.file:
 8        state: absent
 9        path: "{{ cl_packagesd }}"
10      when: cl_all_delete|bool or cl_packagesd_delete|bool
11
12    - name: "vars-packages: Assemble packages to {{ cl_packagesd }}"
13      ansible.builtin.assemble:
14        regexp: "{{ cl_assemble_regexp }}"
15        src: "{{ cl_packagesd_dir }}"
16        dest: "{{ cl_packagesd }}"
17        owner: "{{ cl_dira_owner|default(omit) }}"
18        group: "{{ cl_dira_group|default(omit) }}"
19        mode: "{{ cl_dira_fmode }}"
20        validate: "{{ cl_assemble_validate|default(omit, true) }}"
21
22  rescue:
23
24    - name: "vars-packages: Assemble packages to {{ cl_packagesd }} failed"
25      ansible.builtin.debug:
26        msg: |-
27          [ERR] Can not assemble packages. End of play.
28          {{ ansible_failed_result }}
29
30    - name: "vars-packages: End of play"
31      meta: end_play
32
33  delegate_to: localhost
34
35- name: "vars-packages: Include files from {{ cl_packagesd }} to cl_packagesd_items"
36  ansible.builtin.include_vars:
37    file: "{{ cl_packagesd }}"
38    name: cl_packagesd_items
39
40- name: "vars-packages: Combine cl_packages with cl_packagesd_items"
41  ansible.builtin.set_fact:
42    cl_packages: "{{ cl_packages|combine(cl_packagesd_items|default({})) }}"
43
44- name: "vars-packages: Debug"
45  ansible.builtin.debug:
46    var: cl_packages
47  when: cl_debug|bool
48
49# TODO: sort|unique list of packages/ports
50
51# EOF
52...

vars-states.yml

Synopsis: Configure vars-states.

Description of the task.

[tasks/vars-states.yml]

 1---
 2
 3- name: Assemble states
 4  block:
 5
 6    - name: "vars-states: Delete {{ cl_statesd }}"
 7      ansible.builtin.file:
 8        state: absent
 9        path: "{{ cl_statesd }}"
10      when: cl_all_delete|bool or cl_statesd_delete|bool
11
12    - name: "vars-states: Assemble states to {{ cl_statesd }}"
13      ansible.builtin.assemble:
14        regexp: "{{ cl_assemble_regexp }}"
15        src: "{{ cl_statesd_dir }}"
16        dest: "{{ cl_statesd }}"
17        owner: "{{ cl_dira_owner|default(omit) }}"
18        group: "{{ cl_dira_group|default(omit) }}"
19        mode: "{{ cl_dira_fmode }}"
20        validate: "{{ cl_assemble_validate|default(omit, true) }}"
21
22  rescue:
23
24    - name: "vars-states: Assemble states to {{ cl_states }} failed"
25      ansible.builtin.debug:
26        msg: |-
27          [ERR] Can not assemble states. End of play.
28          {{ ansible_failed_result }}
29
30    - name: "vars-states: End of play"
31      meta: end_play
32
33  delegate_to: localhost
34
35- name: "vars-states: Include files from {{ cl_statesd }} to cl_statessd_items"
36  ansible.builtin.include_vars:
37    file: "{{ cl_statesd }}"
38    name: cl_statesd_items
39
40- name: "vars-states: Combine cl_statess with cl_statesd_items"
41  ansible.builtin.set_fact:
42    cl_states: "{{ cl_states|combine(cl_statesd_items|default({})) }}"
43
44- name: "vars-states: Debug"
45  ansible.builtin.debug:
46    var: cl_states
47  when: cl_debug|bool
48
49# EOF
50...

vars-services.yml

Synopsis: Configure vars-services.

Description of the task.

[tasks/vars-services.yml]

 1---
 2
 3- name: Assemble services
 4  block:
 5
 6    - name: "vars-services: Delete {{ cl_servicesd }}"
 7      ansible.builtin.file:
 8        state: absent
 9        path: "{{ cl_servicesd }}"
10      when: cl_all_delete|bool or cl_servicesd_delete|bool
11
12    - name: "vars-services: Assemble services to {{ cl_servicesd }}"
13      ansible.builtin.assemble:
14        regexp: "{{ cl_assemble_regexp }}"
15        src: "{{ cl_servicesd_dir }}"
16        dest: "{{ cl_servicesd }}"
17        owner: "{{ cl_dira_owner|default(omit) }}"
18        group: "{{ cl_dira_group|default(omit) }}"
19        mode: "{{ cl_dira_fmode }}"
20        validate: "{{ cl_assemble_validate|default(omit, true) }}"
21
22  rescue:
23
24    - name: "vars-services: Assemble services to {{ cl_servicesd }} failed"
25      ansible.builtin.debug:
26        msg: |-
27          [ERR] Can not assemble services. End of play.
28          {{ ansible_failed_result }}
29
30    - name: "vars-services: End of play"
31      meta: end_play
32
33  delegate_to: localhost
34
35- name: "vars-services: Include files from {{ cl_servicesd }} to cl_cervicesd_items"
36  ansible.builtin.include_vars:
37    file: "{{ cl_servicesd }}"
38    name: cl_servicesd_items
39
40- name: "vars-services: Combine cl_services with cl_servicesd_items"
41  ansible.builtin.set_fact:
42    cl_services: "{{ cl_services|combine(cl_servicesd_items|default({})) }}"
43
44- name: "vars-services: Debug"
45  ansible.builtin.debug:
46    var: cl_services
47  when: cl_debug|bool
48
49# EOF
50...

vars-files.yml

Synopsis: Configure vars-files.

Description of the task.

[tasks/vars-files.yml]

 1---
 2
 3- name: Assemble files
 4  block:
 5
 6    - name: "vars-files: Delete {{ cl_filesd }}"
 7      ansible.builtin.file:
 8        state: absent
 9        path: "{{ cl_filesd }}"
10      when: cl_all_delete|bool or cl_filesd_delete|bool
11
12    - name: "vars-files: Assemble files to {{ cl_filesd }}"
13      ansible.builtin.assemble:
14        regexp: "{{ cl_assemble_regexp }}"
15        src: "{{ cl_filesd_dir }}"
16        dest: "{{ cl_filesd }}"
17        owner: "{{ cl_dira_owner|default(omit) }}"
18        group: "{{ cl_dira_group|default(omit) }}"
19        mode: "{{ cl_dira_fmode }}"
20        validate: "{{ cl_assemble_validate|default(omit, true) }}"
21
22  rescue:
23
24    - name: "vars-files: Assemble files to {{ cl_filesd }} failed"
25      ansible.builtin.debug:
26        msg: |-
27          [ERR] Can not assemble files. End of play.
28          {{ ansible_failed_result }}
29
30    - name: "vars-files: End of play"
31      meta: end_play
32
33  delegate_to: localhost
34
35- name: "vars-files: Include files from {{ cl_filesd }} to cl_filesd_items"
36  ansible.builtin.include_vars:
37    file: "{{ cl_filesd }}"
38    name: cl_filesd_items
39
40- name: "vars-files: Combine cl_files with cl_filesd_items"
41  ansible.builtin.set_fact:
42    cl_files: "{{ cl_files|combine(cl_filesd_items|default({})) }}"
43
44- name: "vars-files: Debug"
45  ansible.builtin.debug:
46    var: cl_files
47  when: cl_debug|bool
48
49# EOF
50...

sanity.yml

Synopsis: Configure sanity.

Description of the task.

[tasks/sanity.yml]

 1---
 2
 3- name: Collections installed
 4  block:
 5
 6    - name: "sanity: Collections must be installed"
 7      ansible.builtin.debug:
 8        msg: |-
 9          [ERR] Collections are not installed. End of play.
10          Hint: Check the required collections are installed.
11          {{ cl_collections }}
12
13    - name: "sanity: End of play"
14      meta: end_play
15
16  when: cl_sanity_collections|bool
17  # TODO: Find installed collections and compare the list with cl_collections
18
19- name: "sanity: Data directories must exist"
20  ansible.builtin.assert:
21    quiet: "{{ cl_sanity_quiet }}"
22    that:
23      - cl_handlersd_dir is exists
24      - cl_packagesd_dir is exists
25      - cl_statesd_dir is exists
26      - cl_servicesd_dir is exists
27      - cl_filesd_dir is exists
28    fail_msg: |-
29      [ERR] Data directories do not exist.
30      Hint: Check the existence of directories
31      {{ cl_handlersd_dir }}
32      {{ cl_packagesd_dir }}
33      {{ cl_statesd_dir }}
34      {{ cl_servicesd_dir }}
35      {{ cl_filesd_dir }}
36
37- name: "sanity: Assembled data must exist in ansible_check_mode"
38  ansible.builtin.assert:
39    quiet: "{{ cl_sanity_quiet }}"
40    that:
41      - cl_packagesd is exists
42      - cl_statesd is exists
43      - cl_servicesd is exists
44      - cl_filesd is exists
45    fail_msg: |-
46      [ERR] Assembled data do not exist in ansible_check_mode.
47      Hint: Assemble variables first.
48      Run: ansible-playbook playbook.yml -t cl_vars
49  when: ansible_check_mode
50
51- name: "sanity: Supported modules for packages"
52  ansible.builtin.assert:
53    quiet: "{{ cl_sanity_quiet }}"
54    that: unsupported|length == 0
55    fail_msg: |-
56      [ERR] Unsupported module(s) {{ unsupported }} in assembled packages.
57  vars:
58    unsupported: "{{ cl_packages.values()|list|
59                     json_query('[].module')|unique|
60                     difference(cl_supported_modules_pkg) }}"
61  when: cl_sanity_modules_pkg|bool
62
63- name: "sanity: yamllint must be installed"
64  ansible.builtin.assert:
65    quiet: "{{ cl_sanity_quiet }}"
66    that: out is match(regex)
67    fail_msg: |-
68      [ERR] yamllint not installed on controller.
69    success_msg: |-
70      [OK]  yamllint found on controller.
71  vars:
72    regex: '^yamllint \d+\.\d+\.\d+$'
73    out: "{{ lookup('pipe', cl_yamllint ~ ' --version') }}"
74  when: cl_sanity_yamllint|bool
75
76# EOF
77...

debug.yml

Synopsis: Configure debug.

Description of the task.

[tasks/debug.yml]

 1---
 2
 3- name: "debug: Config Light"
 4  vars:
 5    msg: |-
 6      ansible_os_family: {{ ansible_os_family }}
 7      ansible_distribution: {{ ansible_distribution }}
 8      ansible_distribution_major_version: {{ ansible_distribution_major_version }}
 9      ansible_distribution_version: {{ ansible_distribution_version }}
10      ansible_distribution_release: {{ ansible_distribution_release }}
11      ansible_python_version: {{ ansible_python_version }}
12
13      cl_supported_linux_family: {{ cl_supported_linux_family }}
14      cl_supported_modules_pkg: {{ cl_supported_modules_pkg }}
15      cl_collections:
16        {{ cl_collections|to_nice_yaml(indent=2)|indent(2) }}
17
18      cl_sanity: {{ cl_sanity }}
19      cl_sanity_quiet: {{ cl_sanity_quiet }}
20      cl_sanity_collections: {{ cl_sanity_collections }}
21      cl_sanity_modules_pkg: {{ cl_sanity_modules_pkg }}
22      cl_sanity_yamllint: {{ cl_sanity_yamllint }}
23
24      cl_setup: {{ cl_setup }}
25      cl_install: {{ cl_install }}
26      cl_backup: {{ cl_backup }}
27      cl_copyfile_delete: {{ cl_copyfile_delete }}
28      cl_template_delete: {{ cl_template_delete }}
29
30      cl_handlers:
31        {{ cl_handlers|to_nice_yaml(indent=2)|indent(2) }}
32      cl_packages:
33        {{ cl_packages|to_nice_yaml(indent=2)|indent(2) }}
34      cl_services:
35        {{ cl_services|to_nice_yaml(indent=2)|indent(2) }}
36      cl_files:
37        {{ cl_files|to_nice_yaml(indent=2)|indent(2) }}
38      cl_states:
39        {{ cl_states|to_nice_yaml(indent=2)|indent(2) }}
40
41      cl_dird: {{ cl_dird }}
42      cl_dird_owner: {{ cl_dira_owner|default('UNDEFINED') }}
43      cl_dird_group: {{ cl_dira_group|default('UNDEFINED') }}
44      cl_dird_dmode: {{ cl_dira_dmode }}
45
46      cl_handlersd_dir: {{ cl_handlersd_dir }}
47      cl_packagesd_dir: {{ cl_packagesd_dir }}
48      cl_servicesd_dir: {{ cl_servicesd_dir }}
49      cl_filesd_dir: {{ cl_filesd_dir }}
50      cl_statesd_dir: {{ cl_statesd_dir }}
51
52      cl_dira: {{ cl_dira }}
53      cl_dira_owner: {{ cl_dira_owner|default('UNDEFINED') }}
54      cl_dira_group: {{ cl_dira_group|default('UNDEFINED') }}
55      cl_dira_dmode: {{ cl_dira_dmode }}
56      cl_dira_fmode: {{ cl_dira_fmode }}
57      cl_assemble_regexp: {{ cl_assemble_regexp }}
58
59      cl_handlersd: {{ cl_handlersd }}
60      cl_handlers_delete_all: {{ cl_handlers_delete_all }}
61      cl_handlers_delete: {{ cl_handlers_delete }}
62      cl_handlers_create: {{ cl_handlers_create }}
63
64      cl_packagesd: {{ cl_packagesd }}
65      cl_servicesd: {{ cl_servicesd }}
66      cl_filesd: {{ cl_filesd }}
67      cl_statesd: {{ cl_statesd }}
68      cl_all_delete: {{ cl_all_delete }}
69      cl_packagesd_delete: {{ cl_packagesd_delete }}
70      cl_servicesd_delete: {{ cl_servicesd_delete }}
71      cl_filesd_delete: {{ cl_filesd_delete }}
72      cl_statesd_delete: {{ cl_statesd_delete }}
73
74      cl_yamllint: {{ cl_yamllint }}
75      cl_assemble_validate: {{ cl_assemble_validate|default('UNDEFINED') }}
76      cl_handlers_validate: {{ cl_handlers_validate|default('UNDEFINED') }}
77
78      cl_files_order:
79        {{ cl_files_order|to_nice_yaml(indent=2)|indent(2) }}
80
81      install_retries: {{ install_retries }}
82      install_delay: {{ install_delay }}
83
84      freebsd_install_method: {{ freebsd_install_method }}
85      freebsd_use_packages: {{ freebsd_use_packages }}
86      cl_services_freebsd_rcconf_auto: {{ cl_services_freebsd_rcconf_auto }}
87
88  ansible.builtin.debug:
89    msg: "{{ '{}'.format(msg) }}"
90
91# EOF
92...

packages.yml

Synopsis: Configure packages.

Description of the task.

[tasks/packages.yml]

  1---
  2
  3- name: "packages: Select lists"
  4  ansible.builtin.set_fact:
  5    my_packages_apt: "{{ cl_packages.values()|list|json_query('[?module == `apt`]') }}"
  6    my_packages_snap: "{{ cl_packages.values()|list|json_query('[?module == `snap`]') }}"
  7    my_packages_yum: "{{ cl_packages.values()|list|json_query('[?module == `yum`]') }}"
  8    my_packages_pkgng: "{{ cl_packages.values()|list|json_query('[?module == `pkgng`]') }}"
  9    my_packages_package: "{{ cl_packages.values()|list|json_query('[?module == `package`]') }}"
 10    my_packages_undef: "{{ cl_packages.values()|list|selectattr('module', 'undefined') }}"
 11
 12- name: "packages: Create list defaulted to module package"
 13  ansible.builtin.set_fact:
 14    my_packages_default: "{{ my_packages_package + my_packages_undef }}"
 15
 16- name: "packages: Debug"
 17  ansible.builtin.debug:
 18    msg: |
 19      cl_packages:
 20        {{ cl_packages|to_nice_yaml(indent=2)|indent(2) }}
 21      my_packages_apt:
 22        {{ my_packages_apt|to_yaml(indent=2)|indent(2) }}
 23      my_packages_snap:
 24        {{ my_packages_snap|to_yaml(indent=2)|indent(2) }}
 25      my_packages_yum:
 26        {{ my_packages_yum|to_yaml(indent=2)|indent(2) }}
 27      my_packages_pkgng:
 28        {{ my_packages_pkgng|to_yaml(indent=2)|indent(2) }}
 29      my_packages_package:
 30        {{ my_packages_package|to_yaml(indent=2)|indent(2) }}
 31      my_packages_undef:
 32        {{ my_packages_undef|to_yaml(indent=2)|indent(2) }}
 33      my_packages_default:
 34        {{ my_packages_default|to_yaml(indent=2)|indent(2) }}
 35  when: cl_debug|bool
 36
 37- name: FreeBSD packages
 38  block:
 39
 40    - name: "packages: Manage FreeBSD packages"
 41      community.general.pkgng:
 42        name: "{{ item.name }}"  # list / elements=string / required
 43        state: "{{ item.state|default(omit) }}"
 44        annotation: "{{ item.annotation|default(omit) }}"
 45        autoremove: "{{ freebsd_pkgng_autoremove|default(omit) }}"
 46        cached: "{{ freebsd_pkgng_cached|default(omit) }}"
 47        chroot: "{{ freebsd_pkgng_chroot|default(omit) }}"
 48        ignore_osver: "{{ freebsd_pkgng_ignore_osver|default(omit) }}"
 49        jail: "{{ freebsd_pkgng_jail|default(omit) }}"
 50        pkgsite: "{{ freebsd_pkgng_pkgsite|default(omit) }}"
 51        rootdir: "{{ freebsd_pkgng_rootdir|default(omit) }}"
 52      loop: "{{ my_packages_pkgng }}"
 53      loop_control:
 54        label: "{{ item.name }}"
 55      register: result
 56      until: result is succeeded
 57      retries: "{{ install_retries }}"
 58      delay: "{{ install_delay }}"
 59
 60    - name: "packages: Debug FreeBSD packages"
 61      ansible.builtin.debug:
 62        var: result
 63      when: cl_debug|bool
 64
 65  when:
 66    - my_packages_pkgng|length > 0
 67    - ansible_os_family == 'FreeBSD'
 68    - freebsd_install_method|lower == 'packages'
 69
 70- name: FreeBSD ports
 71  block:
 72
 73    - name: "packages: Manage FreeBSD ports"
 74      community.general.portinstall:
 75        name: "{{ item.1 }}"  # string / required
 76        state: "{{ item.0.state|default(omit) }}"
 77        use_packages: "{{ item.0.use_packages|default(freebsd_use_packages) }}"
 78      loop: "{{ my_packages_pkgng|d([])|subelements('name') }}"
 79      loop_control:
 80        label: "{{ item.1 }}"
 81      register: result
 82      until: result is succeeded
 83      retries: "{{ install_retries }}"
 84      delay: "{{ install_delay }}"
 85
 86    - name: "packages: Debug FreeBSD ports"
 87      ansible.builtin.debug:
 88        var: result
 89      when: cl_debug|bool
 90
 91  when:
 92    - my_packages_pkgng|length > 0
 93    - ansible_os_family == 'FreeBSD'
 94    - freebsd_install_method|lower == 'ports'
 95
 96- name: Linux snap
 97  block:
 98
 99    - name: "packages: Find snap"
100      ansible.builtin.find:
101        paths: "{{ cl_snap_paths }}"
102        patterns: "{{ cl_snap_patterns }}"
103      register: cl_find_snap
104
105    - name: "packages: Debug find snap"
106      ansible.builtin.debug:
107        var: cl_find_snap
108      when: cl_debug|bool
109
110    - name: "packages: Fail if snap is missing"
111      ansible.builtin.fail:
112        msg: "[ERR] snap is missing."
113      when: cl_find_snap.matched == 0
114
115    - name: "packages: Manage Linux packages by snap module"
116      community.general.snap:
117        name: "{{ item.name }}"  #  list / elements=string
118        state: "{{ item.state|default(omit) }}"
119      loop: "{{ my_packages_snap }}"
120      loop_control:
121        label: "{{ item.name }}"
122      register: result
123      until: result is succeeded
124      retries: "{{ install_retries }}"
125      delay: "{{ install_delay }}"
126
127    - name: "packages: Debug Linux snap"
128      ansible.builtin.debug:
129        var: result
130      when: cl_debug|bool
131
132  when:
133    - my_packages_snap|length > 0
134    - ansible_os_family in cl_supported_linux_family
135
136- name: Linux package
137  block:
138
139    - name: "packages: Manage Linux packages by package module"
140      ansible.builtin.package:
141        name: "{{ item.1 }}"  # string / required
142        state: "{{ item.0.state|default('present') }}"
143        use: "{{ item.0.use|default('auto') }}"
144      loop: "{{ my_packages_default|d([])|subelements('name') }}"
145      loop_control:
146        label: "{{ item.1 }}"
147      register: result
148      until: result is succeeded
149      retries: "{{ install_retries }}"
150      delay: "{{ install_delay }}"
151
152    - name: "packages: Debug Linux package"
153      ansible.builtin.debug:
154        var: result
155      when: cl_debug|bool
156
157  when:
158    - my_packages_default|length > 0
159    - ansible_os_family in cl_supported_linux_family
160
161- name: Linux yum
162  block:
163
164    - name: "packages: Manage Linux packages by yum module"
165      ansible.builtin.yum:
166        name: "{{ item.name }}"  #  list / elements=string
167        state: "{{ item.state|default(omit) }}"
168        use_backend: "{{ item.use|default(omit) }}"
169      loop: "{{ my_packages_yum }}"
170      loop_control:
171        label: "{{ item.name }}"
172      register: result
173      until: result is succeeded
174      retries: "{{ install_retries }}"
175      delay: "{{ install_delay }}"
176
177    - name: "packages: Debug Linux yum"
178      ansible.builtin.debug:
179        var: result
180      when: cl_debug|bool
181
182  when:
183    - my_packages_yum|length > 0
184    - ansible_os_family == 'RedHat'
185
186- name: Linux apt
187  block:
188    - name: "packages: Manage Linux packages by apt module"
189      ansible.builtin.apt:
190        name: "{{ item.name }}"  #  list / elements=string
191        state: "{{ item.state|default(omit) }}"
192        purge: "{{ item.purge|default(omit) }}"
193      loop: "{{ my_packages_apt }}"
194      loop_control:
195        label: "{{ item.name }}"
196      register: result
197      until: result is succeeded
198      retries: "{{ install_retries }}"
199      delay: "{{ install_delay }}"
200
201    - name: "packages: Debug Linux apt"
202      ansible.builtin.debug:
203        var: result
204      when: cl_debug|bool
205
206  when:
207    - my_packages_apt|length > 0
208    - ansible_os_family == 'Debian'
209
210# TODO: Complete parameters of modules
211
212# EOF
213...

states.yml

Synopsis: Configure states.

Description of the task.

[tasks/states.yml]

 1---
 2
 3- name: "states: Debug"
 4  ansible.builtin.debug:
 5    msg: "{{ cl_states }}"
 6  when: cl_debug|bool
 7
 8- name: "states: Apply unmount states"
 9  ansible.posix.mount:
10    path: "{{ item.value.path }}"
11    state: "{{ item.value.state|default('absent') }}"
12    backup: "{{ item.value.backup|default(omit) }}"
13    boot: "{{ item.value.boot|default(omit) }}"
14    dump: "{{ item.value.dump|default(omit) }}"
15    fstab: "{{ item.value.fstab|default(omit) }}"
16    opts: "{{ item.value.opts|default(omit) }}"
17    passno: "{{ item.value.passno|default(omit) }}"
18    src: "{{ item.value.src|default(omit) }}"
19  loop: "{{ cl_states|dict2items }}"
20  loop_control:
21    label: "{{ item.value.path }}"
22  when: item.value.state|default('absent') in cl_states_unmount
23
24- name: "states: Apply file states"
25  ansible.builtin.file:
26    path: "{{ item.value.path }}"
27    state: "{{ item.value.state|default(omit) }}"
28    src: "{{ item.value.src|default(omit) }}"
29    owner: "{{ item.value.owner|default(omit) }}"
30    group: "{{ item.value.group|default(omit) }}"
31    mode: "{{ item.value.mode|default(omit) }}"
32    attributes: "{{ item.value.attributes|default(omit) }}"
33    recurse: "{{ item.value.recurse|default(omit) }}"
34    force: "{{ item.value.force|default(omit) }}"
35    follow: "{{ item.value.follow|default(omit) }}"
36    access_time: "{{ item.value.access_time|default(omit) }}"
37    access_time_format: "{{ item.value.access_time_format|default(omit) }}"
38    modification_time: "{{ item.value.modification_time|default(omit) }}"
39    modification_time_format: "{{ item.value.modification_time_format|default(omit) }}"
40    unsafe_writes: "{{ item.value.unsafe_writes|default(omit) }}"
41  loop: "{{ cl_states|dict2items }}"
42  loop_control:
43    label: "{{ item.value.path }}"
44  when: item.value.state|default('file') in cl_states_file
45
46- name: "states: Apply mount states"
47  ansible.posix.mount:
48    path: "{{ item.value.path }}"
49    state: "{{ item.value.state }}"
50    backup: "{{ item.value.backup|default(omit) }}"
51    boot: "{{ item.value.boot|default(omit) }}"
52    dump: "{{ item.value.dump|default(omit) }}"
53    fstab: "{{ item.value.fstab|default(omit) }}"
54    opts: "{{ item.value.opts|default(omit) }}"
55    passno: "{{ item.value.passno|default(omit) }}"
56    src: "{{ item.value.src|default(omit) }}"
57  loop: "{{ cl_states|dict2items }}"
58  loop_control:
59    label: "{{ item.value.path }}"
60  when: item.value.state|default('absent') in cl_states_mount
61
62# EOF
63...

files.yml

Synopsis: Manage files.

Iterate cl_files_order (6) and include tasks with particular modules.

[tasks/files.yml]

 1---
 2
 3- name: "files: Manage files"
 4  ansible.builtin.include_tasks:
 5    file: "files-{{ fitem }}.yml"
 6  loop: "{{ cl_files_order }}"
 7  loop_control:
 8    loop_var: fitem
 9
10# EOF
11...

See also

  • See Files Order of options

Hint

  • Customize the list cl_files_order and fit the order of the options to your needs.

files-blockinfile.yml

Synopsis: Configure files-blockinfile.

Description of the task.

[tasks/files-blockinfile.yml]

 1---
 2
 3- name: "files-blockinfile: Debug blocks in cl_files.values()"
 4  ansible.builtin.debug:
 5    msg: "{{ cl_files.values()|selectattr('blocks', 'defined')|list }}"
 6  when: cl_debug|bool
 7
 8- name: "files-blockinfile: Blockinfile"
 9  ansible.builtin.blockinfile:
10    path: "{{ item.0.path }}"
11    marker: "# {mark} ANSIBLE MANAGED BLOCK {{ item.1.marker }}"
12    block: "{{ item.1.block }}"
13    state: "{{ item.1.state|default(omit) }}"
14    insertafter: "{{ item.1.insertafter|default(omit) }}"
15    insertbefore: "{{ item.1.insertbefore|default(omit) }}"
16    marker_begin: "{{ item.1.marker_begin|default(omit) }}"
17    marker_end: "{{ item.1.marker_end|default(omit) }}"
18    owner: "{{ item.0.owner|default(omit) }}"
19    group: "{{ item.0.group|default(omit) }}"
20    mode: "{{ item.0.mode|default(omit) }}"
21    attributes: "{{ item.0.attributes|default(omit) }}"
22    create: "{{ item.0.create|default(omit) }}"
23    validate: "{{ item.0.validate|default(omit) }}"
24    # backup: "{{ cl_backup }}"
25  loop: "{{ cl_files.values()|list|subelements('blocks', skip_missing=true) }}"
26  loop_control:
27    label: "{{ item.0.path }} {{ item.1.marker }}"
28  notify: "{{ item.0.handlers|default(omit) }}"
29  register: cl_results_blocks
30
31- block:
32    - name: "files-blockinfile: Debug cl_results_blocks"
33      ansible.builtin.debug:
34        var: cl_results_blocks
35    - name: "files-blockinfile: Debug changed blocks paths"
36      ansible.builtin.debug:
37        msg: "{{ cl_results_blocks.results|default([])|
38                 json_query('[?changed].invocation.module_args.path') }}"
39  when: cl_debug|bool
40
41# EOF
42...

files-copy.yml

Synopsis: Configure files-copy.

Description of the task.

[tasks/files-copy.yml]

 1---
 2
 3- name: "files-copy: Debug copyfile in cl_files.values()"
 4  ansible.builtin.debug:
 5    msg: "{{ cl_files.values()|selectattr('copyfile', 'defined')|list }}"
 6  when: cl_debug|bool
 7
 8- name: "files-copy: Delete copyfile in cl_files.values()"
 9  ansible.builtin.file:
10    state: absent
11    path: "{{ item.path }}"
12  loop: "{{ cl_files.values()|selectattr('copyfile', 'defined')|list }}"
13  loop_control:
14    label: "{{ item.path }}"
15  when: cl_copyfile_delete|bool
16
17- name: "files-copy: Copy copyfile in cl_files.values()"
18  ansible.builtin.copy:
19    dest: "{{ item.path }}"
20    src: "{{ item.copyfile.path }}"
21    checksum: "{{ item.copyfile.checksum|default(omit) }}"
22    content: "{{ item.copyfile.content|default(omit) }}"
23    decrypt: "{{ item.copyfile.decrypt|default(omit) }}"
24    directory_mode: "{{ item.copyfile.directory_mode|default(omit) }}"
25    follow: "{{ item.copyfile.follow|default(omit) }}"
26    force: "{{ item.copyfile.force|default(omit) }}"
27    local_follow: "{{ item.copyfile.local_follow|default(omit) }}"
28    remote_src: "{{ item.copyfile.remote_src|default(omit) }}"
29    owner: "{{ item.owner|default(omit) }}"
30    group: "{{ item.group|default(omit) }}"
31    mode: "{{ item.mode|default(omit) }}"
32    attributes: "{{ item.attributes|default(omit) }}"
33    validate: "{{ item.validate|default(omit) }}"
34    # backup: "{{ cl_backup }}"
35  loop: "{{ cl_files.values()|selectattr('copyfile', 'defined')|list }}"
36  loop_control:
37    label: "{{ item.path }}"
38  notify: "{{ item.handlers|default(omit) }}"
39  register: cl_results_copy
40
41- block:
42    - name: "files-copy: Debug cl_results_copy"
43      ansible.builtin.debug:
44        var: cl_results_copy
45    - name: "files-copy: Debug changed copy path"
46      ansible.builtin.debug:
47        msg: "{{ cl_results_copy|default([])|
48                 json_query('[?changed].invocation.module_args.path') }}"
49  when: cl_debug|bool
50
51# EOF
52...

files-create-backup.yml

Synopsis: Configure files-create-backup.

Description of the task.

[tasks/files-create-backup.yml]

 1---
 2
 3- name: "file-create-backup: Create time-stamp"
 4  ansible.builtin.set_fact:
 5    cl_timestamp: "{{ '%Y-%m-%d_%H_%M_%S'|strftime }}"
 6
 7- name: "file-create-backup: Stat cl_files"
 8  ansible.builtin.stat:
 9    path: "{{ item }}"
10  loop: "{{ cl_files.values()|map(attribute='path')|list|unique }}"
11  loop_control:
12    label: "{{ item }}"
13  register: result
14
15- name: "file-create-backup: Debug result"
16  ansible.builtin.debug:
17    var: result
18  when: cl_debug|bool
19
20- name: "file-create-backup: Create backup files"
21  ansible.builtin.copy:
22    remote_src: true
23    src: "{{ item.item }}"
24    dest: "{{ item.item }}_{{ cl_timestamp }}.bak"
25    mode: preserve
26  loop: "{{ result.results }}"
27  loop_control:
28    label: "{{ item.item }}"
29  when: item.stat.exists
30  changed_when: false
31
32# EOF
33...

files-delete-backup.yml

Synopsis: Configure files-delete-backup.

Description of the task.

[tasks/files-delete-backup.yml]

 1---
 2
 3- name: "files-delete-backup: Delete backup files that did not change"
 4  ansible.builtin.file:
 5    state: absent
 6    path: "{{ item }}_{{ cl_timestamp }}.bak"
 7  loop: "{{ cl_files.values()|list|json_query('[].path')|
 8            difference(cl_results_copy.results|default([])|
 9                       json_query('[?changed].invocation.module_args.path'))|unique|
10            difference(cl_results_template.results|default([])|
11                       json_query('[?changed].invocation.module_args.path'))|unique|
12            difference(cl_results_lines.results|default([])|
13                       json_query('[?changed].invocation.module_args.path'))|unique|
14            difference(cl_results_blocks.results|default([])|
15                       json_query('[?changed].invocation.module_args.path'))|unique|
16            difference(cl_results_inifile.results|default([])|
17                       json_query('[?changed].invocation.module_args.path'))|unique|
18            difference(cl_results_ucl.results|default([])|
19                       json_query('[?changed].invocation.module_args.path'))|unique|
20            difference(cl_results_patch.results|default([])|
21                       json_query('[?changed].invocation.module_args.path'))|unique
22            }}"
23  when:
24    - cl_backup|bool
25    - not ansible_check_mode
26  changed_when: false
27
28# EOF
29...

files-inifile.yml

Synopsis: Configure files-inifile.

Description of the task.

[tasks/files-inifile.yml]

 1---
 2
 3- name: "files-inifile: Debug ini in cl_files.values()"
 4  ansible.builtin.debug:
 5    msg: "{{ cl_files.values()|selectattr('ini', 'defined')|list }}"
 6  when: cl_debug|bool
 7
 8- name: "files-inifile: INI files"
 9  community.general.ini_file:
10    path: "{{ item.0.path }}"
11    section: "{{ item.1.section }}"
12    option: "{{ item.1.option|default(omit) }}"
13    value: "{{ item.1.value|default(omit) }}"
14    state: "{{ item.1.state|default(omit) }}"
15    allow_no_value: "{{ item.1.allow_no_value|default(omit) }}"
16    no_extra_spaces: "{{ item.1.no_extra_spaces|default(omit) }}"
17    owner: "{{ item.0.owner|default(omit) }}"
18    group: "{{ item.0.group|default(omit) }}"
19    mode: "{{ item.0.mode|default(omit) }}"
20    attributes: "{{ item.0.attributes|default(omit) }}"
21    create: "{{ item.0.create|default(omit) }}"
22    # backup: "{{ cl_backup }}"
23  loop: "{{ cl_files.values()|list|subelements('ini', {'skip_missing': True}) }}"
24  loop_control:
25    label: "{{ item.0.path }}"
26  notify: "{{ item.0.handlers|default(omit) }}"
27  register: cl_results_ini
28
29- block:
30    - name: "files-inifile: Debug cl_results_ini"
31      ansible.builtin.debug:
32        var: cl_results_ini
33    - name: "files-inifile: Debug changed ini paths"
34      ansible.builtin.debug:
35        msg: "{{ cl_results_ini.results|default([])|
36                 json_query('[?changed].invocation.module_args.path') }}"
37  when: cl_debug|bool
38
39# EOF
40...

files-lineinfile.yml

Synopsis: Configure files-lineinfile.

Description of the task.

[tasks/files-lineinfile.yml]

 1---
 2
 3# lines
 4- name: "files-lineinfile: Debug lines in cl_files.values()"
 5  ansible.builtin.debug:
 6    msg: "{{ cl_files.values()|selectattr('lines', 'defined')|list }}"
 7  when: cl_debug|bool
 8
 9- name: "files-lineinfile: Lineinfile lines"
10  ansible.builtin.lineinfile:
11    path: "{{ item.0.path }}"
12    regexp: "{{ item.1.regexp|default(omit) }}"
13    line: "{{ item.1.line|default(omit) }}"
14    backrefs: "{{ item.1.backrefs|default(omit) }}"
15    state: "{{ item.1.state|default(omit) }}"
16    firstmatch: "{{ item.1.firstmatch|default(omit) }}"
17    insertafter: "{{ item.1.insertafter|default(omit) }}"
18    insertbefore: "{{ item.1.insertbefore|default(omit) }}"
19    owner: "{{ item.0.owner|default(omit) }}"
20    group: "{{ item.0.group|default(omit) }}"
21    mode: "{{ item.0.mode|default(omit) }}"
22    attributes: "{{ item.0.attributes|default(omit) }}"
23    others: "{{ item.0.others|default(omit) }}"
24    create: "{{ item.0.create|default(omit) }}"
25    validate: "{{ item.0.validate|default(omit) }}"
26    # backup: "{{ cl_backup }}"
27  loop: "{{ cl_files.values()|list|subelements('lines', skip_missing=true) }}"
28  loop_control:
29    label: "{{ item.0.path }} {{ item.1.line|default('') }}"
30  notify: "{{ item.0.handlers|default(omit) }}"
31  register: cl_results_lines
32
33- block:
34    - name: "files-lineinfile: Debug cl_results_lines"
35      ansible.builtin.debug:
36        var: cl_results_lines
37    - name: "files-lineinfile: Debug changed lines paths"
38      ansible.builtin.debug:
39        msg: "{{ cl_results_lines.results|default([])|
40                 json_query('[?changed].invocation.module_args.path') }}"
41  when: cl_debug|bool
42
43# dict
44- name: "files-lineinfile: Debug dict in cl_files.values()"
45  ansible.builtin.debug:
46    msg: "{{ cl_files.values()|selectattr('dict', 'defined')|list }}"
47  when: cl_debug|bool
48
49- name: "files-lineinfile: Lineinfile dict"
50  ansible.builtin.lineinfile:
51    path: "{{ item.0.path }}"
52    regexp: '^\s*[#;]*\s*{{ item.1.key }}\s*{{ item.0.assignment|default("=")|trim }}\s*(.*)$'
53    line: "{{ item.1.key }}{{ item.0.assignment|default('=') }}{{ item.1.value }}"
54    backrefs: "{{ item.1.backrefs|default(omit) }}"
55    state: "{{ item.1.state|default(omit) }}"
56    firstmatch: "{{ item.1.firstmatch|default(omit) }}"
57    insertafter: "{{ item.1.insertafter|default(omit) }}"
58    insertbefore: "{{ item.1.insertbefore|default(omit) }}"
59    owner: "{{ item.0.owner|default(omit) }}"
60    group: "{{ item.0.group|default(omit) }}"
61    mode: "{{ item.0.mode|default(omit) }}"
62    attributes: "{{ item.0.attributes|default(omit) }}"
63    others: "{{ item.0.others|default(omit) }}"
64    create: "{{ item.0.create|default(omit) }}"
65    validate: "{{ item.0.validate|default(omit) }}"
66    # backup: "{{ cl_backup }}"
67  loop: "{{ cl_files.values()|list|subelements('dict', skip_missing=true) }}"
68  loop_control:
69    label: "{{ item.0.path }} {{ item.1.key }}"
70  notify: "{{ item.0.handlers|default(omit) }}"
71  register: cl_results_dict
72
73- block:
74    - name: "files-lineinfile: Debug cl_results_dict"
75      ansible.builtin.debug:
76        var: cl_results_dict
77    - name: "files-lineinfile: Debug changed dict paths"
78      ansible.builtin.debug:
79        msg: "{{ cl_results_dict.results|default([])|
80                 json_query('[?changed].invocation.module_args.path') }}"
81  when: cl_debug|bool
82
83# EOF
84...

files-markers.yml

Synopsis: Configure files-markers.

Description of the task.

[tasks/files-markers.yml]

 1---
 2
 3- name: "files-markers: Debug markers in cl_files.values()"
 4  ansible.builtin.debug:
 5    msg: "{{ cl_files.values()|selectattr('markers', 'defined')|list }}"
 6  when: cl_debug|bool
 7
 8- name: "files-markers: Mark block {{ item.1.marker }}"
 9  ansible.builtin.include_tasks: fn/mark-block.yml
10  loop: "{{ cl_files.values()|list|subelements('markers', skip_missing=true) }}"
11  loop_control:
12    label: "{{ item.0.path }}"
13
14# EOF
15...

mark-block.yml

Synopsis: Configure mark-block.

Description of the task.

[tasks/fn/mark-block.yml]

 1---
 2
 3- name: "mark-block: Check begin marker {{ item.1.marker }}"
 4  ansible.builtin.command:
 5    cmd: >
 6      grep -q '# BEGIN ANSIBLE MANAGED BLOCK {{ item.1.marker }}' {{ item.0.path }}
 7  register: checkmarker
 8  ignore_errors: true
 9  changed_when: false
10
11- block:
12    - name: "mark-block: Create begin marker {{ item.1.marker }}"
13      ansible.builtin.replace:
14        path: '{{ item.0.path }}'
15        regexp: '{{ item.1.regex1 }}'
16        replace: |-
17          {{ '#' }} BEGIN ANSIBLE MANAGED BLOCK {{ item.1.marker }}
18          {{ item.1.replace1 }}
19    - name: "mark-block: Create end marker {{ item.1.marker }}"
20      ansible.builtin.replace:
21        path: '{{ item.0.path }}'
22        regexp: '({{ item.1.regex1 }}[\s\S]*?){{ item.1.regex2 }}'
23        replace: |-
24          \g<1>
25          {{ item.1.replace2 }}
26          {{ '#' }} END ANSIBLE MANAGED BLOCK {{ item.1.marker }}
27  when:
28    - not ansible_check_mode
29    - checkmarker.rc != 0
30
31# EOF
32...

files-patch.yml

Synopsis: Configure files-patch.

Description of the task.

[tasks/files-patch.yml]

 1---
 2
 3- name: "files-patch: Debug patch in cl_files.values()"
 4  ansible.builtin.debug:
 5    msg: "{{ cl_files.values()|selectattr('patch', 'defined')|list }}"
 6  when: cl_debug|bool
 7
 8- name: "files-patch: Patch"
 9  ansible.posix.patch:
10    dest: "{{ item.path }}"
11    src: "{{ item.patch.src }}"
12    basedir: "{{ item.patch.basedir|default(omit) }}"
13    binary: "{{ item.patch.binary|default(omit) }}"
14    ignore_whitespace: "{{ item.patch.ignore_whitespace|default(omit) }}"
15    remote_src: "{{ item.patch.remote_src|default(omit) }}"
16    state: "{{ item.patch.state|default(omit) }}"
17    strip: "{{ item.patch.strip|default(omit) }}"
18    # backup: "{{ cl_backup }}"
19  loop: "{{ cl_files.values()|selectattr('patch', 'defined')|list }}"
20  loop_control:
21    label: "{{ item.path }}"
22  notify: "{{ item.handlers|default(omit) }}"
23  register: cl_results_patch
24
25- block:
26    - name: "files-patch: Debug cl_results_patch"
27      ansible.builtin.debug:
28        var: cl_results_patch
29    - name: "files-patch: Debug changed patch patch"
30      ansible.builtin.debug:
31        msg: "{{ cl_results_patch|default([])|
32                 json_query('[?changed].invocation.module_args.path') }}"
33  when: cl_debug|bool
34
35# EOF
36...

files-template.yml

Synopsis: Configure files-template.

Description of the task.

[tasks/files-template.yml]

 1---
 2
 3- name: "files-template: Debug template in cl_files.values()"
 4  ansible.builtin.debug:
 5    msg: "{{ cl_files.values()|selectattr('template', 'defined')|list }}"
 6  when: cl_debug|bool
 7
 8- name: "files-template: Delete template in cl_files.values()"
 9  ansible.builtin.file:
10    state: absent
11    path: "{{ item.path }}"
12  loop: "{{ cl_files.values()|selectattr('template', 'defined')|list }}"
13  loop_control:
14    label: "{{ item.path }}"
15  when: cl_template_delete|bool
16
17- name: "files-template: Template"
18  ansible.builtin.template:
19    dest: "{{ item.path }}"
20    src: "{{ item.template.path }}"
21    follow: "{{ item.template.follow|default(omit) }}"
22    force: "{{ item.template.force|default(omit) }}"
23    block_start_string: "{{ item.template.block_start_string|default(omit) }}"
24    block_end_string: "{{ item.template.block_end_string|default(omit) }}"
25    lstrip_blocks: "{{ item.template.lstrip_blocks|default(omit) }}"
26    newline_sequence: "{{ item.template.newline_sequence|default(omit) }}"
27    output_encoding: "{{ item.template.output_encoding|default(omit) }}"
28    trim_blocks: "{{ item.template.trim_blocks|default(omit) }}"
29    variable_end_string: "{{ item.template.variable_end_string|default(omit) }}"
30    variable_start_string: "{{ item.template.variable_start_string|default(omit) }}"
31    owner: "{{ item.owner|default(omit) }}"
32    group: "{{ item.group|default(omit) }}"
33    mode: "{{ item.mode|default(omit) }}"
34    attributes: "{{ item.attributes|default(omit) }}"
35    validate: "{{ item.validate|default(omit) }}"
36    # backup: "{{ cl_backup }}"
37  loop: "{{ cl_files.values()|selectattr('template', 'defined')|list }}"
38  loop_control:
39    label: "{{ item.path }}"
40  notify: "{{ item.handlers|default(omit) }}"
41  register: cl_results_template
42
43- block:
44    - name: "files-template: Debug cl_results_template"
45      ansible.builtin.debug:
46        var: cl_results_template
47    - name: "files-template: Debug changed template path"
48      ansible.builtin.debug:
49        msg: "{{ cl_results_template|default([])|
50                 json_query('[?changed].invocation.module_args.path') }}"
51  when: cl_debug|bool
52
53# EOF
54...

files-ucl.yml

Synopsis: Configure files-ucl.

Description of the task.

[tasks/files-ucl.yml]

 1---
 2
 3- name: "files-ucl: Debug ucl in cl_files.values()"
 4  ansible.builtin.debug:
 5    msg: "{{ cl_files.values()|selectattr('ucl', 'defined')|list }}"
 6  when: cl_debug|bool
 7
 8- name: "files-ucl: UCL files cl_files.values()"
 9  vbotka.freebsd.ucl:
10    path: "{{ item.0.path }}"
11    chdir: "{{ item.1.chdir|default(omit) }}"
12    upath: "{{ item.1.upath|default(omit) }}"
13    ipath: "{{ item.1.ipath|default(omit) }}"
14    icontent: "{{ item.1.icontent|default(omit) }}"
15    value: "{{ item.1.value|default(omit) }}"
16    vtype: "{{ item.1.vtype|default(omit) }}"
17    merge: "{{ item.1.merge|default(omit) }}"
18    state: "{{ item.1.state|default(omit) }}"
19    delimiter: "{{ item.1.delimiter|default(omit) }}"
20    lang: "{{ item.1.lang|default(omit) }}"
21    owner: "{{ item.0.owner|default(omit) }}"
22    group: "{{ item.0.group|default(omit) }}"
23    mode: "{{ item.0.mode|default(omit) }}"
24    attributes: "{{ item.0.attributes|default(omit) }}"
25    create: "{{ item.0.create|default(omit) }}"
26    validate: "{{ item.0.validate|default(omit) }}"
27    # backup: "{{ cl_backup }}"
28  loop: "{{ cl_files.values()|list|subelements('ucl', skip_missing=true) }}"
29  loop_control:
30    label: "{{ item.0.path }}"
31  notify: "{{ item.0.handlers|default(omit) }}"
32  register: cl_results_ucl
33
34- block:
35    - name: "files-ucl: Debug cl_results_ucl"
36      ansible.builtin.debug:
37        var: cl_results_ucl
38    - name: "files-ucl: Debug changed ucl paths"
39      ansible.builtin.debug:
40        msg: "{{ cl_results_ucl.results|default([])|
41                 json_query('[?changed].invocation.module_args.path') }}"
42  when: cl_debug|bool
43
44# EOF
45...

services.yml

Synopsis: Configure services.

Description of the task.

[tasks/services.yml]

 1---
 2
 3- name: "services: Debug"
 4  vars:
 5    msg: |-
 6      cl_services_freebsd_rcconf_auto [{{ cl_services_freebsd_rcconf_auto }}]
 7      cl_services
 8      {{ cl_services|to_nice_yaml }}
 9  ansible.builtin.debug:
10    msg: "{{ '{}'.format(msg) }}"
11  when: cl_debug|bool
12
13# FreeBSD auto ------------------------------------------------------------
14- block:
15
16    - name: "services: Enable service in rc.conf FreeBSD"
17      ansible.builtin.lineinfile:
18        dest: /etc/rc.conf
19        regexp: '^\s*{{ item.value.name }}_enable\s*=(.*)$'
20        line: '{{ item.value.name }}_enable="YES"'
21        backup: "{{ cl_backup }}"
22      loop: "{{ cl_services|dict2items }}"
23      loop_control:
24        label: "{{ item.key }}"
25      when: item.value.enabled|default(true)|bool
26
27    - name: "services: Disable service in rc.conf FreeBSD"
28      ansible.builtin.lineinfile:
29        dest: /etc/rc.conf
30        regexp: '^\s*{{ item.value.name }}_enable\s*=(.*)$'
31        line: '{{ item.value.name }}_enable="NO"'
32        backup: "{{ cl_backup }}"
33      loop: "{{ cl_services|dict2items }}"
34      loop_control:
35        label: "{{ item.key }}"
36      when: not item.value.enabled|default(true)|bool
37
38  when:
39    - ansible_os_family == 'FreeBSD'
40    - cl_services_freebsd_rcconf_auto|bool
41
42# All ---------------------------------------------------------------------
43- block:
44
45    - name: "services: Manage services"
46      ansible.builtin.service:
47        name: "{{ item.value.name }}"
48        state: "{{ item.value.state|default('started') }}"
49        enabled: "{{ item.value.enabled|default(true) }}"
50      loop: "{{ cl_services|dict2items }}"
51      loop_control:
52        label: "{{ item.key }}"
53
54  when: ansible_os_family == 'RedHat' or
55        ansible_os_family == 'Debian' or
56        ansible_os_family == 'FreeBSD'
57
58# EOF
59...