如何在变量中保存hostvars中的主机列表,localhost除外

时间:2018-02-06 12:44:22

标签: ansible

我想要什么

例如,我在同一台服务器上有一个redis复制设置和应用程序。我想告诉我的应用程序,有些主机有redis实例。

App从.env文件中读取主机(它也是模板):

REDIS_URLS=rediscache://{{ redis_hosts|join(",") }}

我可以像这样描述剧本中的主持人:

  ...
  vars:
    redis_hosts:
      - 'redis1.exmaple.com:6379'
      - 'redis2.exmaple.com:6379'
  ...

但是...

问题是什么

  1. 我不想手动指定这些主机,因为Ansible已经知道它们(它们都是hostvars个密钥)。
  2. 我想在与应用程序在同一服务器中的redis实例时请求localhost而不是公共主机名。
  3. 所以我对这样的事情感到困惑:

      ...
      vars:
        redis_hosts:
          - 'localhost:6379' # it's always here
          - '{{ item.key }}:6379'
          with_dict: hostvars
          when: item.key != inventory_hostname
      ...
    

    但它显然不起作用。

    或者我可以将逻辑移到.env文件:

    REDIS_URLS=rediscache://{% for host in hostvars.keys() -%}
        {%- if inventory_hostname == host -%}
            localhost:6379
        {%- else -%}
            {{ host }}:6379
        {%- endif -%}
    {%- if not loop.last -%},{%- endif -%}
    {%- endfor %}
    

    但我也有一个角色,需要相同的主机列表。

1 个答案:

答案 0 :(得分:1)

您可以从列表中删除当前节点(例如inventory_hostname)并将其替换为localhost

# msg is constructed from 'redis_hosts' variable
- debug:
    msg: "{{ redis_list | join(',') }}"
  vars:
    redis_list: "{{ ['localhost:6379'] + redis_hosts | reject('match',inventory_hostname) | list }}"

但似乎你有一些复制粘贴:如果你的库存中有redis主机,为什么你有单独的变量redis_hosts呢?

您可以从广告资源组中构建此列表,我们假设它是redis

# msg is constructed from inventory group 'redis'
- debug:
    msg: "{{ redis_list | join(',') }}"
  vars:
    redis_nodes: "{{ ['localhost'] + groups['redis'] | difference([inventory_hostname]) }}"
    redis_port: 6379
    redis_list: "{{ redis_nodes | map('regex_replace','$',':'+redis_port|string) | list }}"