仅在定义数量的主机上运行任务



我的目标是检查哪些服务器有任何等待更新的包:

- name: yum check | Check for updates
yum:
list: updates
update_cache: true
register: stat_yum_check_output

然后运行一些任务+

- name: Upgrade all packages, excluding java
ansible.builtin.yum:
name: '*'
state: latest
exclude: java*

在返回的主机中的{{number_of_hosts}}主机上{{stat_check_output.results | length > 0}}.


旧描述:

我正在寻找一种方法来限制在两个不同级别上的运行。Righ现在我有了一个运行的剧本,针对50台主机的库存。一个任务输出注册在:中

register: stat_check_output

我还定义了var:

number-of-hosts: 3   # > 1

然后我需要只在{{ number-of-hosts }}主机上扮演其他块/角色/其他什么,它也匹配:

when: "stat_check_output.results | length > 0"

到目前为止,我试图构建一个与when子句匹配的主机项列表,用add_host模块和其他我已经忘记的东西生成新的ansible组。到目前为止,任何方法都在某个时刻失败了。每一次,原因都是无法在全球范围内定义某些东西。

在我看来,我正在寻找类似于run_once但具有可定义计数器的东西。。。

有人能给我指正确的方向吗?

我感觉你遇到了xy问题。你可能会从提供更多的背景信息中受益,了解你需要以这种方式运行哪种任务以及你试图实现的总体目标。

同时,这里有一个尝试来回答你的直接问题。

对于处于其他任务中间的任务,下面的任务应该可以做到。

请注意number-of-hosts是ansible的无效变量名。我用有效的number_of_hosts替换了它

- name: "play this on {{ number_of_hosts }} valid hosts"
vars:
play_hostvars: "{{ ansible_play_hosts | map('extract', hostvars) }}"
results_length: "{{ play_hostvars | map(attribute='stat_check_output.results')
| map('length') }}"
valid_hosts: "{{ play_hostvars | zip(results_length)
| selectattr(1, '>', 0) | map(attribute='0.inventory_hostname') }}"
debug:
msg: "Do something on {{ inventory_hostname }}"
when: inventory_hostname in valid_hosts[:number_of_hosts]

请注意,如果您的游戏以50个主机为目标,则除匹配的主机外,您在这些条件下玩的任何任务都将在每个主机上跳过。

为了提高效率,您可以尝试以下操作,它将创建一组有效的主机,并仅针对特定播放中配置的数量:

- name: A play targeting all hosts:
hosts: all
vars:
number_of_hosts: 3

tasks:
# ... previous needed tasks including the one
# which registers `stat_check_output`
- name: Tag valid hosts with a fact
set_fact:
host_valid: "{{ stat_check_output.results | length > 0 }}"
- name: "Dynamically add {{ number_of_hosts }} valid hosts to a specific group"
vars:
all_valid_hosts: "{{ hostvars | dict2items | selectattr('value.host_valid') | map(attribute='key') }}"
add_host:
name: "{{ item }}"
groups:
- valid_hosts
loop: "{{ all_valid_hosts[:number_of_hosts] }}"
- name: play targeted only against previously selected hosts
hosts: valid_hosts

tasks:
- name: do work to be done
debug:
msg: "do something on {{ inventory_hostname }}"

最新更新