如何让Ansible只在一台主机上运行一个特定的任务?

nus*_*ver 13 ansible

剧本看起来像:

- hosts: all
  tasks:
    - name: "run on all hosts,1"
      shell: something1
    - name: "run on all hosts,2"
      shell: something2
    - name: "run on one host, any host would do"
      shell: this_command_should_run_on_one_host
    - name: "run on all hosts,3"
      shell: something3
Run Code Online (Sandbox Code Playgroud)

我知道使用命令行选项--limit,我可以限制为一个主机,是否可以在playbook中执行此操作?

tec*_*raf 21

对于任何(默认情况下它将匹配列表中的第一个)主机:

- name: "run on first found host"
  shell: this_command_should_run_on_one_host
  run_once: true
Run Code Online (Sandbox Code Playgroud)

对于特定主持人:

- name: "run on that_one_host host"
  shell: this_command_should_run_on_one_host
  when: ansible_hostname == ‘that_one_host’
Run Code Online (Sandbox Code Playgroud)

或者inventory_hostname(Ansible清单ansible_hostname中定义的主机名)而不是(目标计算机上定义的主机名),具体取决于您要使用的名称.

  • 您还可以执行 `when: inventory_hostname == play_hosts[0]` 来仅在一台主机上运行。然后您可以使用“when: inventory_hostname != play_hosts[0]”在所有其他主机上运行任务。 (7认同)
  • 值得指出的是,@techraf 在他们的答案中加入了一些不起作用的字符。将 `'that_one_host'` 更改为 `'that_one_host'`(将 `'` 更改为 `'`) (2认同)

fab*_*bio 21

Techraf 的第一个答案与OP 的问题完全相同。

我只是想展示一种在特定主机上运行任务的更好方法:

- name: "run on that_one_host host"
  shell: this_command_should_run_on_one_host
  run_once: true
  delegate_to: that_one_host
Run Code Online (Sandbox Code Playgroud)

如果运行 playbook 的组包含许多主机,则使用when: ansible_hostname == 'that_one_host'when: ansible_hostname == ansible_play_hosts[0]将评估所有主机上的 when 子句(如果 when 子句有其他更复杂的条件,则可能会很长),并导致在剧本的输出。

结合run_oncedelegate_to,剧本的输出将更加清晰,仅显示在所选主机上执行的任务。

- hosts: all
  gather_facts: no
  tasks:
    - name: Run on one specific host | when-clause
      debug:
        msg: "Hello world"
      when: inventory_hostname == ansible_play_hosts[0]
    
    - name: Run on one specific host | run_once + delegate_to
      debug:
        msg: "Hello world"
      run_once: true
      delegate_to: ansible_play_hosts[0]
Run Code Online (Sandbox Code Playgroud)
TASK [Run on one specific host | when-clause] **********************************************************************************
skipping: [host2]
skipping: [host3]
ok: [host1] => {
    "msg": "Hello world"
}
skipping: [host4]

TASK [Run on one specific host | run_once + delegate_to] ***********************************************************************
ok: [host2 -> ansible_play_hosts[0]] => {
    "msg": "Hello world"
}
Run Code Online (Sandbox Code Playgroud)

无论您选择哪种解决方案,如果您希望任务在精确的主机上运行一次,都不要组合使用这些解决方案:

  • run_once: true
  • when: inventory_hostname == 'that_one_host'

如果这样做,将无法提前知道任务是否会被执行(我已经通过惨痛的教训学会了这一点)。原因是,run_once: true将在播放组中随机选择一个主机,然后才应用 when 子句:

  • 如果 run_once 选择在 'that_one_host' 上运行任务,则将执行该任务
  • 如果 run_once 选择“another_host”,则任务将被跳过。

  • play_hosts 现已弃用,我理解我们应该使用 ansible_play_batch ? (2认同)