1. 概述

Ansible 使用 Inventory 文件 来记录基础设施中的主机信息。Inventory 文件中通常包含主机列表、主机组定义,还可以指定连接方式等信息。

有时候我们并不想在所有主机上运行 Playbook,比如在调试阶段,我们可能只想在单个主机上验证逻辑。本文将介绍几种 不修改 inventory 文件 的前提下,在单个主机上运行 Ansible Playbook 的方法。文中使用的 Ansible 版本为 2.12.0。


2. 示例 Playbook

我们将使用如下 Playbook:example_playbook.yml

$ cat example_playbook.yml
- hosts: all
  name: Example Ansible Playbook
  tasks:
    - name: Print message
      debug:
        msg: Hello Baeldung

该 Playbook 定义了一个任务,使用 Ansible 内置的 debug 模块输出 Hello Baeldung

我们使用的 inventory 文件内容如下:

$ cat inventory
host1
host2
host3

这个 inventory 包含了三个主机:host1、host2 和 host3。

2.1. 测试 Playbook

我们先运行一下这个 Playbook:

$ ansible-playbook -i inventory example_playbook.yml

输出如下:

PLAY [Example Ansible Playbook] ************************************************

TASK [Gathering Facts] *********************************************************
ok: [host1]
ok: [host2]
ok: [host3]

TASK [Print message] ***********************************************************
ok: [host1] => {
    "msg": "Hello Baeldung "
}
ok: [host2] => {
    "msg": "Hello Baeldung "
}
ok: [host3] => {
    "msg": "Hello Baeldung"
}

PLAY RECAP *********************************************************************
host1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
host2                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host3                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

由于 Playbook 中的 hosts: all,任务会在所有主机上执行。现在我们的目标是 不在修改 inventory 的前提下,只在某一台主机上运行这个 Playbook。


3. 修改 Playbook

3.1. 修改 hosts 字段

最直接的方式是修改 Playbook 中的 hosts 字段,指定为某一个主机:

- hosts: host2

修改后运行 Playbook:

$ ansible-playbook -i inventory example_playbook.yml

输出显示 Playbook 只在 host2 上运行。✅

⚠️ 缺点是每次换主机都要改 Playbook,维护成本高。

3.2. 使用 when 条件控制任务执行

我们也可以使用 Ansible 的条件判断机制,比如:

- name: Print message
  debug:
    msg: Hello Baeldung
  when: inventory_hostname == "host2"

inventory_hostname 是 Ansible 的内置变量,表示当前正在执行的主机。

运行后可以看到,只有 host2 执行了任务,其余主机跳过。✅

⚠️ 同样,这种方式也需要修改 Playbook,不适合频繁切换目标主机的场景。


4. 使用变量控制目标主机

我们可以将目标主机作为变量传入,从而避免修改 Playbook 内容。

修改 Playbook:

- hosts: '{{ target }}'

然后通过命令行传入变量值:

$ ansible-playbook -i inventory example_playbook.yml -e "target=host2"

输出显示任务只在 host2 上执行。✅

💡 使用 -e "target=all" 可以恢复对所有主机的操作。


5. 使用主机列表(Host List)

Ansible 的 -i 参数不仅可以指定 inventory 文件,也可以直接传入一个主机列表:

$ ansible-playbook -i host2, example_playbook.yml

注意结尾的逗号 ,,表示这是一个主机列表。否则 Ansible 会尝试将其当作 inventory 文件路径解析。

✅ 这种方式非常方便,无需修改 Playbook 或 inventory 文件。

💡 如果想在多个主机上运行,比如 host2 和 host3,可以写成:

$ ansible-playbook -i host2,host3, example_playbook.yml

6. 使用 --limit 参数

Ansible 提供了 --limit 参数,用于限制执行范围:

$ ansible-playbook -i inventory --limit host2 example_playbook.yml

输出显示 Playbook 只在 host2 上运行。✅

💡 也可以限制多个主机,例如:

$ ansible-playbook -i inventory --limit host2,host3 example_playbook.yml

7. 总结

方法 是否修改 Playbook 是否修改 Inventory 灵活性 推荐程度
修改 hosts 字段 ✅ 是 ❌ 否 ❌ 低 ⭐⭐
使用 when 条件 ✅ 是 ❌ 否 ❌ 低 ⭐⭐
使用变量传参 ✅ 是(仅一次) ❌ 否 ✅ 高 ⭐⭐⭐⭐
使用 Host List(-i host, ❌ 否 ❌ 否 ✅ 高 ⭐⭐⭐⭐⭐
使用 --limit ❌ 否 ❌ 否 ✅ 高 ⭐⭐⭐⭐⭐

✅ **推荐优先使用 -i host,--limit**,这两种方式无需修改 Playbook 或 inventory,适合临时调试和生产环境快速部署。



原始标题:Running an Ansible Playbook on a Single Host