我尝试维护nginx配置文件摘要的模板。我想将这些代码片段应用于不同类型的Web服务器,其中每个服务器仅需要这些代码片段的一个子集。 我的方法(也许有更好的方法)是为每个host_group创建子目录(例如代理节点)并链接所需的文件,因此我只需要将模板维护在一个位置即可。 我的模板文件夹如下所示:
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
},
后来我意识到,虽然列出仅用于匹配group_names的目录结构会导致某些项目没有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])
如果我使用无when子句的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'"}
所以我想我还需要以某种方式摆脱未定义的项。有任何想法吗 ?
答案 0 :(得分:0)
您的模板:
{{ nginx_group_dirs.results | map(attribute='stdout_lines') | list }}
产生一个列表列表(stdout_lines
)。
当您要遍历所有stdout_lines
的元素时,需要将结果展平:
{{ nginx_group_dirs.results | map(attribute='stdout_lines') | flatten }}
答案 1 :(得分:0)
我找到了一种使模板运行的方法,但对我来说有点奇怪:
- name: create dict of group dirs with subdirs and files
shell: ls -d1 roles/nginx/templates/{{ item|quote }}/*/* | 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
- debug: msg="{{ item.stdout_lines | default([]) }}"
register: file_list
loop: "{{ nginx_group_dirs.results }}"
- name: template snippets for all applicable groups
template:
src: "{{ item }}"
dest: "/etc/nginx/{{ item | regex_replace('^(\\w(-?))+\\/', '') }}"
backup: yes
loop: "{{ file_list.results | map(attribute='msg') | flatten }}"