playbook部署nginx需用yum/apt安装(state: present保生产稳定)、copy/template配置文件(注意路径与nginx -t校验)、service启动并设开机自启(显式use=systemd+端口检测),同时规避权限、selinux、幂等性等常见坑。

直接能用的 Playbook 就是:用 yum 或 apt 安装、copy 配置文件、service 启动并设为开机自启——但实际跑不通,往往卡在权限、路径、模块参数或服务状态判断上。
用 yum/apt 模块安装 Nginx 时 state 参数选哪个
state: present 和 state: latest 都能装上,但行为不同:
-
state: present只确保包已安装,不升级;适合生产环境,避免意外更新导致配置不兼容 -
state: latest会检查仓库最新版并升级(含小版本),适合测试环境快速同步 - CentOS/RHEL 环境必须先配好 EPEL 或 Nginx 官方 repo,否则
yum找不到包;Debian/Ubuntu 则注意apt模块需加update_cache: yes,否则可能因缓存过期报no package matching
copy 配置文件后 nginx -t 报错怎么办
Ansible 的 copy 模块不会自动校验语法,直接 service: name=nginx state=restarted 很可能失败并静默退出(默认不报错):
- 务必在
copy后加一个command任务执行nginx -t,用ignore_errors: yes避免中断,再用failed_when显式判断输出是否含successful - 注意
dest路径:RHEL 系列默认配置在/etc/nginx/nginx.conf,但用户自定义站点通常放/etc/nginx/conf.d/*.conf;路径写错会导致nginx -t通过但服务起不来 - 如果用了
template模块生成配置,变量渲染错误(如{{ port }}未定义)也会让nginx -t失败,建议先本地ansible-playbook --check测试渲染结果
service 模块启动失败却显示 “ok” 的原因
Ansible 默认只检查 systemd 或 init 脚本返回码,不验证进程是否真在监听端口:
- 加
enabled: yes是设置开机自启,但不等于服务当前就 running;必须同时指定state: started - 常见坑:
service模块在 RHEL 8+ 上对nginx有时识别不准,建议显式指定use: systemd(即service: name=nginx state=started use=systemd) - 更稳妥的做法:在
service后追加一个wait_for任务,检查port: 80是否可连,避免“启动成功但没监听”的假象
幂等性被破坏的典型场景
Playbook 声称“重复执行无害”,但以下操作会打破它:
- 用
shell模块执行echo "xxx" >> /etc/nginx/conf.d/site.conf—— 每次都追加,配置重复 -
copy时没加backup: yes,覆盖原配置后无法回退 - 用
file创建目录时state: directory是幂等的,但state: touch每次都会更新 mtime,触发后续任务不必要的变更 - 没关
gather_facts却在vars里硬编码 IP,换主机执行就失效;应改用{{ ansible_default_ipv4.address }}这类事实变量
真正麻烦的不是写错一行 YAML,而是服务看似启动了,curl 却超时——这时候得盯住 nginx -t 输出、systemctl status nginx 日志、以及 SELinux 是否拦截了 80 端口,这些细节 Playbook 本身不会替你查。











