
Ansible 批量服务器配置最适合解决“机器一多,手工 SSH 登录就容易漏步骤”的问题。本文会教你如何从一次性的 ad-hoc 命令开始,逐步整理出可重复执行的 Playbook(自动化任务剧本),并用一个网站服务器初始化案例说明 inventory(主机清单)、变量、任务拆分和结果验证。读完后,你可以把安装软件、创建用户、同步配置、重启服务这类重复动作收敛成一套可审计的流程,而不是靠聊天记录和个人习惯传递运维经验。
先判断场景:哪些任务值得交给 Ansible
在只有 1 台测试机时,手工执行 5 条命令通常更快;但当同一套操作要覆盖 3 台、10 台甚至更多服务器时,手工方式的问题会迅速放大。常见风险不是“不会执行命令”,而是第 6 台机器少改了一个配置项、第 9 台忘记重启服务,或者离职交接时没人能说清楚当初改过什么。
Ansible 的价值在于把这些步骤写成文本文件,并通过 SSH(安全外壳协议)连接目标主机执行。它不要求被管理端长期运行 agent,只要控制端能连上目标服务器,且目标主机具备 Python 运行环境,就可以完成大多数 Linux 运维任务。对中小团队来说,这种低侵入方式更容易从现有流程接入。
我们建议先选择“重复频率高、失败影响可控、验证条件明确”的任务做第一批自动化。例如创建部署用户、统一时区、安装 Nginx、配置防火墙规则、下发监控 agent。这类任务的共同特点是:命令相对固定,目标状态清晰,执行完可以用 systemctl status、端口探测或文件校验快速确认。
如果你的业务运行在 VPS(虚拟专用服务器) 或多台独立主机上,Ansible 可以帮助你把基础环境保持一致;如果只是单台临时机器,先把命令记录完整,再决定是否整理成 Playbook 会更稳妥。接下来我们用一个“三台网站节点初始化”的例子,把流程拆开说明。
准备 inventory:先把目标服务器分组清楚
inventory 是 Ansible 的主机清单,它回答两个问题:要管理哪些服务器,以及这些服务器属于什么角色。不要一开始就把所有机器都塞进同一个 all 组里,否则后续扩展数据库节点、缓存节点、Web 节点时会很混乱。
一个简化的 inventory 可以这样写:
[web]
web1 ansible_host=192.0.2.11 ansible_user=deploy
web2 ansible_host=192.0.2.12 ansible_user=deploy
web3 ansible_host=192.0.2.13 ansible_user=deploy
[web:vars]
ansible_port=22
ansible_python_interpreter=/usr/bin/python3
这里的 web 是业务分组,ansible_host 是连接地址,ansible_user 是登录用户。示例使用文档保留网段,不代表真实公网 IP。生产环境中,不建议把密码直接写进 inventory;更常见的做法是使用 SSH 密钥、堡垒机策略,或结合 Ansible Vault(加密变量工具)保存敏感内容。

写完 inventory 后,先不要急着安装软件。第一步应该验证控制端是否能连接所有目标主机:
ansible -i inventory.ini web -m ping
如果返回 pong,说明 Ansible 能调用远端 Python 模块;如果失败,优先检查 3 个位置:SSH 用户是否正确、目标端口是否放行、目标系统是否存在 /usr/bin/python3。对于 服务器配置 类任务,连接验证是后续所有 Playbook 的前置条件,跳过这一步会让排障范围变大。
用 ad-hoc 命令做探测,不要把临时命令当长期方案
ad-hoc 命令适合做一次性探测和快速修复。它的优点是短、直接、反馈快;缺点是执行逻辑留在终端历史里,难以审查和复用。我们通常把它用于“确认状态”,而不是长期承载完整部署流程。
例如查看三台 Web 节点的系统版本:
ansible -i inventory.ini web -m command -a "cat /etc/os-release"
检查 Nginx 是否已安装:
ansible -i inventory.ini web -m command -a "nginx -v"
如果发现 3 台里有 1 台缺少软件,不建议手工登录那一台补装。更好的做法是把“确保 Nginx 存在”写进 Playbook,让所有节点都执行同一个目标状态。这样即便其中 2 台已经安装,Ansible 也会报告无需变更;只有缺失的节点会被修改。
ad-hoc 命令还有一个实用场景:发布前批量确认端口。下面命令会在所有 Web 节点上查看 80 端口监听情况:
ansible -i inventory.ini web -m shell -a "ss -lntp | grep ':80 '"
使用 shell 模块时要谨慎,因为它会经过 shell 解释,变量展开、管道和重定向都可能带来额外风险。能用 command 模块完成的动作,优先不用 shell。把这条边界定清楚,后面写 Playbook 时也更容易减少不可预期行为。
把服务器初始化整理成 Playbook
当探测命令稳定后,就可以把目标状态写进 Playbook。下面示例完成 4 件事:更新软件缓存、安装 Nginx、创建站点目录、确保服务启动。示例面向 Debian/Ubuntu 系统,其他发行版需要替换包管理模块。
---
- name: Prepare web servers
hosts: web
become: true
tasks:
- name: Update package cache
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
- name: Install nginx
ansible.builtin.apt:
name: nginx
state: present
- name: Create site directory
ansible.builtin.file:
path: /var/www/example-site
state: directory
owner: www-data
group: www-data
mode: "0755"
- name: Ensure nginx is running
ansible.builtin.service:
name: nginx
state: started
enabled: true
执行命令如下:
ansible-playbook -i inventory.ini web-init.yml
Playbook 的关键不是“把命令换成 YAML”,而是描述目标状态。state: present 表示软件应该存在,state: started 表示服务应该运行。重复执行时,如果目标已经满足条件,Ansible 会尽量保持不变,这就是幂等性。幂等性越好,越适合在灰度发布、灾备恢复和新节点扩容时反复使用。

如果你同时管理建站环境、业务 API 和后台任务,可以把不同角色拆成多个 Playbook 或 role(角色目录)。例如 roles/nginx 管 Web 服务,roles/users 管用户,roles/firewall 管端口规则。拆分不是为了显得复杂,而是为了让一次变更只影响明确范围。
变量、模板和敏感信息:让配置可复用但不失控
真实项目不会永远使用同一个域名、端口和目录。变量可以把“会变化的部分”从任务里抽出来,让 Playbook 在测试、预生产和生产环境之间复用。一个常见做法是在 group_vars/web.yml 中保存 Web 组变量:
site_root: /var/www/example-site
nginx_worker_connections: 1024
site_domain: example.com
随后在任务里引用变量:
- name: Create site directory
ansible.builtin.file:
path: "{{ site_root }}"
state: directory
owner: www-data
group: www-data
mode: "0755"
当配置文件需要随变量生成时,可以使用 Jinja2 模板。例如把 Nginx 站点配置保存为 templates/site.conf.j2,再通过 template 模块下发。模板文件中可以引用 {{ site_domain }} 和 {{ site_root }},这样同一套结构可以服务多个站点。
敏感信息不要放进普通 YAML。数据库密码、API token、私钥片段应使用 Ansible Vault 加密,或放入受控的密钥系统。即使仓库是私有的,也要假设它未来可能被更多协作人员读取。一个简单底线是:能公开给新同事看的配置放 Git;不能公开的内容必须加密或外置。
这部分也适合和 运维指南 文档配合使用:文档说明“为什么这么配置”,Playbook 负责“如何落地配置”。两者放在同一个仓库中,变更记录会比零散工单更容易追踪。
验证与回滚:批量执行前必须设计刹车
批量自动化的风险在于,一条错误配置可能同时影响多台服务器。因此 Playbook 写完后,不应直接对生产全量执行。我们建议按照“语法检查→空跑→小批量→全量”的顺序推进。
常用验证命令如下:
ansible-playbook -i inventory.ini web-init.yml --syntax-check
ansible-playbook -i inventory.ini web-init.yml --check
ansible-playbook -i inventory.ini web-init.yml --limit web1
--syntax-check 只能发现 YAML 或任务格式问题,不能保证逻辑正确;--check 是空跑模式,适合预估会修改哪些资源;--limit web1 可以先对 1 台机器执行,确认无误后再扩展到整个 web 组。对于涉及防火墙、SSH 配置、Nginx 主配置的任务,先小批量验证尤其重要。
回滚也要提前设计。Ansible 不是传统意义上的事务系统,不会自动把所有变更恢复到执行前。更可靠的方式是为关键配置保留备份,并把回滚动作也写成 Playbook。例如下发 Nginx 配置前使用 backup: true,或将旧版本配置保存在版本库里,需要时按 commit 回退。

如果你在 Hostease 的 VPS(虚拟专用服务器)或其他自管服务器上实践,建议先创建 1 台测试节点,把 inventory、Playbook、变量和回滚步骤跑通,再迁移到生产分组。这样做的意义不是追求一次成功,而是让失败范围可控、验证证据清楚。
团队落地建议:从一套小流程开始标准化
Ansible 批量服务器配置不必一开始就做成庞大的自动化平台。对多数团队来说,第一阶段只要把 3 类高频任务沉淀下来,就能明显减少重复劳动:新服务器初始化、Web 服务配置、基础安全加固。每一类任务都应包含 inventory、Playbook、变量文件和 README,README 里写清楚适用系统版本、执行命令、验证方法和回滚方式。
建议你用下面的顺序推进:先选 2-3 台非核心节点试点;再把手工命令转换成 Playbook;随后用 --check 和 --limit 控制范围;最后把执行记录纳入代码仓库或变更工单。这样既能保留自动化效率,也不会因为一次批量执行影响全部业务。
总结来看,ad-hoc 命令适合探测,Playbook 适合沉淀流程,变量和模板负责复用,验证与回滚负责控制风险。如果你需要稳定管理多台 服务器、部署多个站点,或正在把手工运维流程标准化,可以考虑从本文这套最小实践开始,再逐步扩展到监控、备份和发布流程。