Ansible中如何聚合不同主机的num变量并为各主机分配专属数值区间
实现方案
两种常用实现方式,可根据你的使用场景选择:
方案1:Play层预计算(推荐)
适合需要在多个任务中复用from变量的场景,提前计算后存入各主机的facts中,后续任务可直接调用。
完整playbook示例:
- name: 计算并分配主机数值区间 hosts: all gather_facts: false tasks: - name: 预计算前缀和映射关系 run_once: true block: - name: 按固定顺序获取所有主机的num值 set_fact: # sort保证主机顺序固定,可根据需要删除sort按inventory默认顺序 sorted_hosts: "{{ groups.all | sort }}" from_map: {} current_offset: 1 - name: 遍历计算每个主机的起始值 set_fact: from_map: "{{ from_map | combine({item: current_offset}) }}" current_offset: "{{ current_offset | int + hostvars[item].num | int }}" loop: "{{ sorted_hosts }}" - name: 为每个主机绑定from变量 set_fact: host_from: "{{ from_map[inventory_hostname] }}" host_to: "{{ from_map[inventory_hostname] | int + num | int - 1 }}" # 后续下发模板等任务可直接使用 host_from 和 host_to 变量 - name: 下发配置模板 template: src: your_template.j2 dest: /etc/your_config_path
方案2:Jinja2模板内直接计算
如果仅需在单个模板文件中用到区间值,不需要额外增加Play任务,可直接在模板内完成前缀和计算:
模板示例:
{% set sorted_hosts = groups.all | sort %} {% set offset = 1 %} {% for host in sorted_hosts %} {% if host == inventory_hostname %} # 当前主机数值区间 from = {{ offset }} to = {{ offset + num | int - 1 }} {% endif %} {% set offset = offset + hostvars[host].num | int %} {% endfor %}
注意事项
- 两种方案都对主机列表做了排序处理,目的是保证每次运行时主机顺序固定,分配的区间不会发生变化,如果明确要按inventory写入顺序分配,可以删除
sort过滤器 - 如果存在部分主机未定义num变量的情况,可在获取num时添加默认值避免报错,例如
hostvars[item].num | default(0) | int
内容的提问来源于stack exchange,提问作者mikhub
相关产品推荐
相关产品推荐

