让 ansible 跳过 运行 在机器上玩 运行 Ansible 剧本

Have ansible skip running a play on the machine running the Ansible playbook

我如何构建剧本,以便不在 运行 来自 Ansible 的机器上执行单个剧本?

例如,如果我有一个简单的双人游戏剧本:

- name: Patch and reboot
  hosts: all
  gather_facts: true

  tasks:
  - name: Fully patch system
    package:
      name: "*"
      state: latest
    become: true
    register: patchstatus

  - name: Reboot if patched
    reboot:
    become: true
    when: patchstatus is changed

但我不希望在 运行 机器 运行 Ansible 上触发重启。

我知道维护得更好的清单不会让我的 Ansible 系统与其他系统放在一起,但这是一个实验室,我想要一个简单的剧本,我可以每晚启动 - 我宁愿它不重启我的 Ansible剧本(至少在它是最后一个重启之前)。

简单地说,我正在寻找一个预定义的变量,这样我就可以使用一个简单的 when: ansible_hostname != ansible_execution_server 可以简单地用来跳过播放。 (假设 ansible_execution_serveransible-playbook 从中执行的系统的名称。)

那么重启部分可能是这样的:

  - name: Reboot if patched
    reboot:
    become: true
    when:
      - patchstatus is changed
      - ansible_hostname != ansible_execution_server

如果您在 运行 您的 Playbook 时没有成为现有清单文件的目标,那么您的工作站将成为 Implicit Localhost 的目标。

您遇到的行为是因为全局 hosts 变量设置为 all。您可能知道,其中指定每个任务应该 运行 在您清单中的所有主机上。

如果您不希望在 运行 运行 Playbook 的机器上触发重启,那么您需要确保将其排除在外。这通常通过清单文件中的组来完成。

我对使用 Ansible 清单文件比较熟悉,而且我从来没有 运行 遇到使用一个会增加您在描述的最后一段中描述的限制的情况。

首先,here is the documentation 用于 Ansible Inventory 文件。我知道 Ansible 文档非常冗长。但是 Ansible 的许多更精细的工作都是细微差别的,如果您通常通过文档搜索特定的实现信息,您可能会错过很多上下文。如果您还没有,我鼓励您在继续之前阅读整个文档。

之后,像这样构建一个清单文件:

[hardware]
my.router.name
my.switch.name
my.computer.name
my.first.server
my.second.server
my.third.server

[networking]
my.router.name
my.switch.name
my.second.server

[servers]
my.first.server
my.second.server
my.third.server

[computers]
my.computer.name
wife.computer.name

[instances:children]
my.router.name
my.switch.name
my.computer.name
wife.computer.name
my.first.server
my.second.server
my.third.server

在本例中,您总共定义了 7 个设备。它们出现在您的 children 部分中。从那里,您可以派生出不同的主机组。例如,我在这里创建了 hardwarenetworkingserverscomputers 组。

假设您想使用 Playbook 重新启动所有个人计算机。然后将第 2 行设置为 hosts: computers。如果您想重新启动所有服务器和所有网络设备,那么您可以将其设置为如下所示:hosts: networking:servers

如果您希望除 my.computer.name 之外的所有设备都打补丁并重新启动,那么您可以这样编写您的 Playbook:

- hosts: hardware:networking:servers:wife.computer.name
  gather_facts: true
  become: true

  tasks:
    - package:
        name: "*"
        state: latest
      register: patchstatus

    - reboot:
      when: patchstatus is changed

让我知道这是否有帮助,或者如果我错过了您的问题。 Ansible 使用起来很有趣,所以我总是很乐意提供帮助。

当当前主机名等于 localhost 或者如果您当前的主机是您的 ansible 控制器主机的 FQDN(基本上,第二个条件仅适用于您在 hosts 文件中明确定义 ansible 控制器的 fqdn)

- name: Patch and reboot
  hosts: all
  gather_facts: true

  tasks:
  - name: Fully patch system
    package:
      name: "*"
      state: latest
    become: true
    register: patchstatus

  - name: Reboot if patched
    reboot:
    become: true
    when: 
      - patchstatus is changed
      - inventory_hostname != 'localhost' or inventory_hostname != 'ansible_controller_fqdn'