我有以下库存结构:
cluster:
server01.domain.com:
host_id: 1
host_role: master
server02.domain.com:
host_id: 2
host_role: follower
server03.domain.com:
host_id: 3
host_role: follower
我需要实现一个任务,仅在服务器2和3上运行,在其中我应该能够看到server01名称。
我试过
- name: my test task
debug: "the fqdn of the server is: {{ vars['play_hosts'][0] }}"
when: host_role == 'follower'
但我在库存中使用的订单没有得到尊重。
当集群元素的host_role等于master时,有没有方法调用它?
否则,设置">"是可行的;全局变量">a可以用于每个主机。
- set_fact:
master_fqdn: {{ inventory_hostname }}
when: host_role == 'master'
不幸的是,此解决方案将创建仅可用于第一台主机的master_fqdn变量。
更新
order:inventory
选项可能是一个解决方案,但正如我所说,它在我的剧本中没有得到尊重。我不知道为什么,但打印{{ vars['play_hosts'] }}
不会报告库存订单。
无论如何,我真正需要的是在其他主机上运行的任务中检索我的第一个服务器名称的可能性,只需根据host_role
属性值过滤整个play_hosts
数组。换句话说:
- 任务应运行
when host_role == 'worker'
- 我应该访问
vars['play_hosts'].key()
IFhost_role == 'master'
考虑到声明master_fqdn这样的全局变量可接受的可能性,我尝试了
set_fact:
master_fqdn: {{ inventory_hostname }}
when: host_role == 'master'
但不幸的是,这只适用于我的第一位主持人。
您可以将hosts
变量视为list
,并将slice
变量视为仅选择最后两个主机。
例如:假设您有以下库存:
[cluster]
server01 ansible_host=127.0.0.1 host_id=1 host_role=master
server02 ansible_host=127.0.0.1 host_id=2 host_role=worker
server03 ansible_host=127.0.0.1 host_id=3 host_role=worker
您可以使用以下slice
:编写playbook
- hosts: cluster[1:2]
gather_facts: no
connection: local
tasks:
- debug:
var: groups.cluster[0]
输出将如下所示:
❯ ansible-playbook playbooks/limit.yml
PLAY [cluster[1:2]] ************************************************************
Tuesday 01 June 2021 11:49:23 -0300 (0:00:00.020) 0:00:00.020 **********
TASK [debug] *******************************************************************
ok: [server02] =>
groups.cluster[0]: server01
ok: [server03] =>
groups.cluster[0]: server01
编辑
您可以通过修改:来控制playbook
的执行
order
:设置Ansible挑选主机的顺序serial
:设置运行的批处理大小throttle
:限制执行时间或CPU密集型任务strategy
:控制Ansible任务执行行为run_once
:在单个主机上运行任务,并将结果应用于所有主机
以下是总结其用途的文档摘录:
您可以使用
serial
设置一次要管理的主机数量、百分比或列表。在启动下一批主机之前,Ansible在指定数量或百分比的主机上完成播放。您可以使用throttle
限制分配给块或任务的工作人员数量。您可以使用order
控制Ansible如何选择组中的下一个主机来执行。您可以使用run_once
在单个主机上运行任务。这些关键词不是策略。它们是应用于播放、块或任务的指令或选项。
您提到库存订单没有得到遵守。这不是真的。默认情况下,Ansible将使用库存的顺序。问题是Ansible还将并行运行任务,每次运行任务的完成情况都会有所不同。
除了所有这些选项之外,您还可以使用when
选项告诉Ansible,如果不满足条件,它应该跳过运行该任务。如果不想在多个tasks
上写入when
,可以将其与import_tasks
选项结合使用。例如:
- hosts: cluster
gather_facts: no
connection: local
order: inventory
strategy: linear
serial: 1
tasks:
- import_tasks: ../tasks/when.yml
when: host_role == "worker"
这是输出:
❯ ansible-playbook playbooks/limit_2.yml
PLAY [cluster] *****************************************************************
Wednesday 02 June 2021 11:39:41 -0300 (0:00:00.019) 0:00:00.019 ********
PLAY [cluster] *****************************************************************
Wednesday 02 June 2021 11:39:41 -0300 (0:00:00.061) 0:00:00.081 ********
TASK [debug] *******************************************************************
ok: [server02] =>
groups.cluster[0]: server01
PLAY [cluster] *****************************************************************
Wednesday 02 June 2021 11:39:41 -0300 (0:00:00.061) 0:00:00.142 ********
ok: [server03] =>
groups.cluster[0]: server01
PLAY RECAP *********************************************************************
server01 : ok=0 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
server02 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
server03 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
您可以看到Ansible跳过了server01
上的任务。我还配置了前面提到的一些选项来展示如何使用它们。