我有一个运行多个站点的单个 Ansible 配置服务器。
我的 Ansible 任务大致如下:
- name: site nginx config
template: src="nginx-site.conf.j2" dest=/etc/nginx/conf.d/{{item.name}}.conf
owner=root group=root mode=0444
with_items: sites
notify: restart nginx
- name: nginx conf
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
owner=root group=root mode=0444
notify: restart nginx
我想使用validate
Ansible 模板模块的参数来调用nginx -t
并确保我的新配置在语法上有效。它适用于主 nginx.conf:
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
owner=root group=root mode=0444
validate="/usr/sbin/nginx -c %s -t"
但它似乎无法获取对站点特定配置文件的更改。放置validate
站点特定模板不起作用,因为它们需要包装在http
指令中才有效。
我该怎么做才能检查这些特定于站点的文件的有效性?
答案1
您可以在那里做一些技巧并验证放置的文件,例如(想法借自https://gist.github.com/psd/5042334):
validate: bash -c 'nginx -t -c /dev/stdin <<< "events {worker_connections 1;} http { include %s; }"'
更新 2022-12-14
在新版本的 bash 中,这种构造将不起作用!请参阅 nginx错误报告 2381(2425)由于实施发生变化 -用于此处文档而不是临时文件的管道。
因此,您可以使用可读性稍差的构造,例如:
validate: bash -c 'echo "events { worker_connections 2; } http { include %s; }" > /tmp/nginx.conf; sudo nginx -T -c /tmp/nginx.conf && rm -f /tmp/nginx.conf'
更新 2024-04-15
以前的解决方案是在出现错误时不删除 /tmp/nginx.conf。如果您想要调试结果,这可能会很有用。但如果您想确保它被清除,您可以这样做(感谢@谢尔盖对于编辑建议):
validate: bash -c 'echo "events { worker_connections 2; } http { include %s; }" > /tmp/nginx.conf; sudo nginx -T -c /tmp/nginx.conf; ec=$?; rm -f /tmp/nginx.conf; exit $ec'
答案2
直接调用validate
nginx 主配置文件中包含的文件是没有意义的,因为特定配置文件中的指令的有效性可能取决于其余配置文件(例如,您有两个声明相同服务器块的配置文件等)。
nginx -t
每当您想要验证任何 nginx 的配置更改时,您必须始终调用主配置文件而不是其子部分之一。
答案3
我采用了与接受的答案类似的方法,并考虑到了其他答案的顾虑。
我创建这个要点为了这个目的。
这个想法是将整个/etc/nginx
目录复制到一个临时目录,从参数中更改一个文件%s
并测试主 nginx 配置是否存在问题。如果您假设最初 nginx 配置是有效的,并且修改 nginx 配置的所有任务都使用该配置进行验证,那么我猜不会有问题。
作为一行代码,它看起来像这样:
validate: bash -c 'NGINX_CONF_DIR=`mktemp -d`; cp -rTp /etc/nginx/ "$NGINX_CONF_DIR" && cp -Tp %s "$NGINX_CONF_DIR"/sites-enabled/new-site.conf && nginx -t -c "$NGINX_CONF_DIR"/nginx.conf'
答案4
使用 /dev/stdin 的验证似乎不适用于较新的 bash 版本,他们建议使用适当的临时配置文件:https://trac.nginx.org/nginx/ticket/2381#comment:1
我们可以做的是创建临时文件,例如:
- name: Create a temporary file
tempfile:
state: file
suffix: temp
register: tempfile_1
- name: Ensure Nginx configuration file
template:
src: server.j2
dest: /path/to/whatever.conf
validate: bash -c 'echo "events {worker_connections 3;} http { include %s; }" > {{ tempfile_1.path }} &&
nginx -prefix=/etc/nginx -t -c {{ tempfile_1.path }}'
notify: reload nginx
- name: Remove the temporary file
file:
path: "{{ tempfile_1.path }}"
state: absent
when: tempfile_1.path is defined