Я пытаюсь поддерживать шаблоны для фрагментов файла конфигурации nginx. Эти фрагменты я хочу применить к различным типам веб-серверов, где каждому серверу нужна только часть этих фрагментов.
Мой подход (возможно, есть и лучший) заключался в создании подкаталогов для каждой группы хостов (например, proxy-node) и связывании необходимых файлов, поэтому мне нужно хранить шаблоны только в одном месте.
Моя папка с шаблонами выглядит так:
nginx.conf
proxy-nodes
├── conf.d
└── snippets
├── cors.conf -> ../../snippets/cors.conf
├── proxy_backend.conf -> ../../snippets/proxy_backend.conf
├── proxy_conditions.conf -> ../../snippets/proxy_conditions.conf
├── proxy_location_assets.conf -> ../../snippets/proxy_location_assets.conf
├── proxy_static_params.conf -> ../../snippets/proxy_static_params.conf
└── ssl.conf -> ../../snippets/ssl.conf
snippets
├── backend.conf
├── ban.conf
├── cors.conf
├── proxy_backend.conf
├── proxy_conditions.conf
├── proxy_location_assets.conf
├── proxy_static_params.conf
└── ssl.conf
Затем я пытаюсь извлечь список файлов, которые мне нужны для шаблона, на хост:
- name: create dict of group dirs with snippets files
shell: ls roles/nginx/templates/{{ item|quote }}/snippets/* | cut -d'/' -f4-
register: nginx_group_dirs
delegate_to: localhost
with_lines: for i in $(ls -d roles/nginx/templates/*/); do echo $i | cut -f4 -d'/'; done
when: item in group_names
Это дает мне несколько элементов с файлами в nginx_group_dirs.results.item.stdout_lines:
"nginx_group_dirs": {
"changed": true,
"msg": "All items completed",
"results": [
...
},
"item": "proxy-nodes",
"rc": 0,
"start": "2018-09-12 10:45:14.652846",
"stderr": "",
"stderr_lines": [],
"stdout": "proxy-nodes/snippets/backend.conf\nproxy-nodes/snippets/ban.conf\nproxy-nodes/snippets/cors.conf\nproxy-nodes/snippets/proxy_backend.conf\nproxy-nodes/snippets/proxy_conditions.conf\nproxy-nodes/snippets/proxy_location_assets.conf\nproxy-nodes/snippets/proxy_static_params.conf\nproxy-nodes/snippets/ssl.conf",
"stdout_lines": [
"proxy-nodes/snippets/cors.conf",
"proxy-nodes/snippets/proxy_backend.conf",
"proxy-nodes/snippets/proxy_conditions.conf",
"proxy-nodes/snippets/proxy_location_assets.conf",
"proxy-nodes/snippets/proxy_static_params.conf",
"proxy-nodes/snippets/ssl.conf"
]
},
{
"_ansible_ignore_errors": null,
"_ansible_item_label": "snippets",
"_ansible_item_result": true,
"_ansible_no_log": false,
"changed": false,
"item": "snippets",
"skip_reason": "Conditional result was False",
"skipped": true
},
Позже я понял, что перечисление структуры каталогов только для совпадающих групповых имен приводит к тому, что некоторые элементы не имеют stdout_lines.
Теперь моя проблема состоит в том, чтобы найти правильный цикл и / или синтаксис фильтра для шаблонирования всех соответствующих файлов stdout_lines из нескольких элементов.
- name: template snippets for all applicable groups
template:
src: "{{ item }}"
dest: "/etc/nginx/snippets/{{ item | basename }}"
backup: yes
with_items: "{{ nginx_group_dirs.results | map(attribute='stdout_lines') | list }}"
when: item.stdout_lines is defined
Я добавил предложение when:, которое дает мне этот вывод (здесь больше элементов, потому что я не хочу расширять пост:
TASK [nginx : template snippets for all applicable groups] ********************************************
skipping: [eu-proxy1] => (item=[Undefined, Undefined, Undefined, [u'eu-proxy-nodes/sites-available/default'], [u'proxy-nodes/snippets/cors.conf', u'proxy-nodes/snippets/proxy_backend.conf', u'proxy-nodes/snippets/proxy_conditions.conf', u'proxy-nodes/snippets/proxy_location_assets.conf', u'proxy-nodes/snippets/proxy_static_params.conf', u'proxy-nodes/snippets/ssl.conf'], Undefined, Undefined])
Если я использую предложение techrafs без условия когда
with_items: "{{ nginx_group_dirs.results | map(attribute='stdout_lines') | flattened }}"
Я получаю (потому что у некоторых предметов нет 'stdout_lines'?):
fatal: [eu-proxy1]: FAILED! => {"msg": "'dict object' has no attribute 'stdout_lines'"}
Так что я думаю, что мне нужно как-то избавиться от неопределенных предметов. Есть идеи ?