Ansible模板需放templates/目录且以.j2结尾,src只写文件名;变量须用default过滤器防未定义;循环前需判空;上线前用validate校验语法并配合backup回滚。

模板文件必须放在正确位置且带.j2后缀
Ansible只认当前 playbook 同级目录下的 templates/ 子目录,且模板名必须以 .j2 结尾。比如 playbook 是 deploy.yml,那模板就得是 templates/nginx_upstream.j2。写成 conf/nginx.j2 或 templates/nginx.conf 都会报错 template file not found。
src 参数只写文件名,不加路径前缀:正确是 src: nginx_upstream.j2,不是 src: templates/nginx_upstream.j2。
变量要防未定义、带默认值
Jinja2 遇到未定义变量会渲染为空,容易导致语法错误。比如 upstream {{ app_name }} { ... } 中 app_name 没传,结果变成 upstream { ... },Nginx 直接拒绝加载。
用 | default 过滤器兜底:
{{ app_name | default('webapp') }}{{ upstream_port | default(8080) }}-
{{ ansible_processor_vcpus | int * 2 | default(4) }}(动态算 worker 数)
循环生成 upstream server 块要判空防崩
常见需求是根据 inventory 动态列出后端节点。别直接写 {% for host in groups['backend'] %},万一 groups['backend'] 为空或未定义,任务就失败。
安全写法是先判断再循环:
{% if groups['backend'] is defined and groups['backend'] %}{% for host in groups['backend'] %}server {{ hostvars[host]['ansible_host'] }}:{{ upstream_port }};{% endfor %}{% endif %}
这样即使没 backend 主机,也能生成合法的空 upstream 块,不会中断部署。
上线前务必用 validate 校验语法
模板渲染完立刻用 Nginx 自检命令验证,避免错误配置上线:
validate: '/usr/sbin/nginx -t -c %s'- 如果校验失败,Ansible 会中止任务并报错,不会把非法配置推到线上
- 配合
backup: yes,出问题能快速回滚
实际效果:改错一个 {% 少了左花括号,validate 立刻报 nginx: [emerg] invalid number of arguments in "upstream" directive,而不是等 reload 时才发现。











