Ansible渲染Jinja2模板如何仅保留目标节点对应的Inventory配置
解决方案
问题根因
你当前模板最外层遍历了groups['ceph_osd']下的所有主机,所以每个节点渲染脚本时,都会把三个节点的规则全部生成,最终所有节点的脚本内容完全一致。
具体修改步骤
1. 替换Jinja2模板内容
直接调用当前节点自身的rules变量即可,无需遍历所有主机,修改后的clean_bcache.sh.j2如下:
# clean_bcache.sh.j2 #!/bin/sh {% for rule in rules.values() %} {% if rule.bcache != 'none' %} bcache_name=$(lsblk -o KNAME {{ rule.bcache }} | grep bcache) cset.uuid=$(bcache-super-show {{ rule.bcache }} | grep cset.uuid | awk -F' ' '{print $2}') echo ${cset.uuid} > /sys/block/$bcache_name/bcache/detach sleep 1 echo 1 >/sys/fs/bcache/${cset.uuid}/unregister sleep 1 {% for backing_dev in rule.disks %} echo 1 > /sys/block/{{backing_dev}}/bcache/stop {% endfor %} {% endif %} {% endfor %}
2. (可选)优化Inventory变量格式
你当前Inventory里的rules是字符串格式,Ansible可能不会自动解析为字典,建议调整为合法可识别的格式,两种方案二选一即可:
方案A:修改为INI格式原生变量
[cluster] ops1 ansible_host=192.168.15.80 ops2 ansible_host=192.168.15.81 ops3 ansible_host=192.168.15.82 [ceph_osd] ops1 rules='{"rule1":{"bcache": "/dev/nvme1n1p7", "disks": ["/dev/sdb"]},"rule2":{"bcache": "/dev/nvme1n1p8", "disks": ["/dev/sdc"]}}' ops2 rules='{"rule1":{"bcache": "/dev/nvme1n1p7", "disks": ["/dev/sdb"]},"rule2":{"bcache": "/dev/nvme1n1p8", "disks": ["/dev/sdd"]}}' ops3 rules='{"rule1":{"bcache": "/dev/nvme1n1p7", "disks": ["/dev/sdc"]},"rule2":{"bcache": "/dev/nvme1n1p8", "disks": ["/dev/sdf"]}}'
同时模板里调用变量时加上JSON解析过滤:
{% for rule in (rules | from_json).values() %}
方案B:切换为YAML格式Inventory
cluster: hosts: ops1: ansible_host: 192.168.15.80 ops2: ansible_host: 192.168.15.81 ops3: ansible_host: 192.168.15.82 ceph_osd: hosts: ops1: rules: rule1: bcache: /dev/nvme1n1p7 disks: - /dev/sdb rule2: bcache: /dev/nvme1n1p8 disks: - /dev/sdc ops2: rules: rule1: bcache: /dev/nvme1n1p7 disks: - /dev/sdb rule2: bcache: /dev/nvme1n1p8 disks: - /dev/sdd ops3: rules: rule1: bcache: /dev/nvme1n1p7 disks: - /dev/sdc rule2: bcache: /dev/nvme1n1p8 disks: - /dev/sdf
这种格式无需额外处理,直接用修改后的模板即可正常渲染。
你的Ansible任务配置无需修改,执行后每个节点的脚本就只会包含自身对应的规则。
内容的提问来源于stack exchange,提问作者Phoenix Chao
相关产品推荐
相关产品推荐

