使用Ansible搭建Elasticsearch集群的Jinja2模板配置问题
Ansible Jinja2模板配置Elasticsearch discovery.seeds_hosts问题解决
问题背景
使用Ansible搭建Elasticsearch集群时,需要通过Jinja2模板动态设置discovery.seeds_hosts参数,需求如下:
- 当
elasticsearch组内主机数量≥2时,参数值为当前主机之外的所有集群主机IP,以逗号分隔 - 当组内仅1台主机时,参数值为当前主机自身IP
现有inventory.ini配置:
[elasticsearch] 192.168.0.1 192.168.0.2 192.168.0.3
此前尝试的模板代码(针对主机名)仅在多主机场景生效,单主机时discovery.seeds_hosts会为空:
{% for host in groups['elasticsearch'] %}{% if host == ansible_host %}{% else %}{%if loop.index0 > 0 %}{% endif %}elasticsearch-{{ loop.index }}{% if not loop.last %},{% endif %}{% endif %}{% endfor %}
Ansible版本信息:
ansible [core 2.14.1] config file = /etc/ansible/ansible.cfg configured module search path = ['/home/ansible/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /usr/local/lib/python3.10/site-packages/ansible ansible collection location = /home/ansible/.ansible/collections:/usr/share/ansible/collections executable location = /usr/local/bin/ansible python version = 3.10.9 (main, Dec 8 2022, 01:46:27) [GCC 10.2.1 20210110] (/usr/local/bin/python) jinja version = 3.1.2 libyaml = True
解决方案
以下两种Jinja2模板写法均可满足需求:
写法一:使用变量过滤与默认值
{% set other_cluster_hosts = groups['elasticsearch'] | difference([ansible_host]) %} {% set seed_hosts_list = other_cluster_hosts if other_cluster_hosts | length > 0 else [ansible_host] %} discovery.seeds_hosts={{ seed_hosts_list | join(',') }}
逻辑说明:
- 用
difference过滤器从集群主机组中排除当前主机,得到其他主机列表 - 判断其他主机列表是否为空:为空则使用当前主机IP,否则使用其他主机列表
- 用
join过滤器将列表转为逗号分隔的字符串
写法二:直接判断集群主机数量
{% if groups['elasticsearch'] | length > 1 %} discovery.seeds_hosts={{ groups['elasticsearch'] | difference([ansible_host]) | join(',') }} {% else %} discovery.seeds_hosts={{ ansible_host }} {% endif %}
逻辑说明:
- 先判断集群主机组的数量是否大于1
- 多主机场景:取当前主机之外的所有主机IP,拼接为逗号分隔字符串
- 单主机场景:直接使用当前主机IP
两种写法均能覆盖单/多主机场景,避免单主机时参数为空的问题。
内容的提问来源于stack exchange,提问作者Solaire
相关产品推荐
相关产品推荐

