更新 2022-12-14

更新 2022-12-14

我有一个运行多个站点的单个 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

我想使用validateAnsible 模板模块的参数来调用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错误报告 23812425)由于实施发生变化 -用于此处文档而不是临时文件的管道

因此,您可以使用可读性稍差的构造,例如:

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

直接调用validatenginx 主配置文件中包含的文件是没有意义的,因为特定配置文件中的指令的有效性可能取决于其余配置文件(例如,您有两个声明相同服务器块的配置文件等)。

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

相关内容