访问其他主机的字典变量

时间:2020-08-31 17:30:51

标签: ansible

假设我有这个hosts.yml

alpinehosts:
  hosta:
  hostb:

这些是./host_vars/hosta.yml(反向代理)中的玉host属植物hostvars

rproxyitems:
- rproxyfqdn: "pageA.com"
  comment: "This ia website A"
  rproxyaltfqdn: "alternativeA1.com alternativeA2.com"
  rproxytarget: "http://destinationA"
- rproxyfqdn: "pageB.com"
  comment: "This ia website B"
  rproxyaltfqdn: "alternativeB1.com alternativeBb.com"
  rproxytarget: "http://destinationB"

在主机上,请求被重定向到我想要的Nginx具有server_name,就像在反向代理中一样。写一次,用很多。

那是我的目标虚拟主机。/host_vars/hostb.yml(Web服务器请求被重定向到)

nginxvhost:
- fqdn: pageA.com
  servername: {{ hostvars[hosta].rproxyitems[rproxyfqdn[pageA.com]] }}
  serveraltname: {{ hostvars[hosta].rproxyitems[rproxyfqdn[pageA.com]].rproxyaltfqdn }}
  comment: "This is website A target webservice"
- fqdn: pageB.com
  servername: {{ hostvars[hosta].rproxyitems[rproxyfqdn[pageB.com]] }}
  serveraltname: {{ hostvars[hosta].rproxyitems[rproxyfqdn[pageB.com]].rproxyaltfqdn }}
  comment: "This is website B target webservice"

我的方法行不通,但希望您能明白。如何仅访问对方的主机(hostA)词典变量元素?我当然可以手动输入值,但是我不喜欢这个概念。我想定义一次,并经常使用。

有关错误,请查看屏幕截图。error message

1 个答案:

答案 0 :(得分:1)

好吧,您非常接近您的解决方案,因为pageA.com肯定表明您处在正确的轨道上。
但是,由于pageB.comrproxyfqdn是列表的值,而不是键或字典的值,因此这使您的任务变得更加复杂。

针对您的问题的两种解决方案:

  1. 通过实际的列表结构,您可以使用Jinja过滤器select和Ansible的match测试,以匹配列表中具有特定rproxyitems | selectattr('rproxyfqdn', 'match', 'pageA.com')的元素:{{1 }}。这将返回一个列表,因此,如果您确定始终只有一个项目匹配,只需添加一个first过滤器即可。
    鉴于剧本
    - hosts: hostb
      gather_facts: no
    
      tasks:
        - debug:
            msg: "{{ nginxvhost }}"
          vars:
            nginxvhost:
              - fqdn: pageA.com
                servername: "{{ (hostvars['hosta'].rproxyitems | selectattr('rproxyfqdn', 'match', 'pageA.com') | first).rproxytarget }}"
                serveraltname: "{{ (hostvars['hosta'].rproxyitems | selectattr('rproxyfqdn', 'match', 'pageA.com') | first).rproxyaltfqdn }}"
                comment: "This is website A target webservice"
              - fqdn: pageB.com
                servername: "{{ (hostvars['hosta'].rproxyitems | selectattr('rproxyfqdn', 'match', 'pageB.com') | first).rproxytarget }}"
                serveraltname: "{{ (hostvars['hosta'].rproxyitems | selectattr('rproxyfqdn', 'match', 'pageB.com') | first).rproxyaltfqdn }}"
                comment: "This is website B target webservice"
    
    总结一下:
    PLAY [hostb] *****************************************************************************************************
    
    TASK [debug] *****************************************************************************************************
    ok: [hostb] => {
        "msg": [
            {
                "comment": "This is website A target webservice",
                "fqdn": "pageA.com",
                "serveraltname": "alternativeA1.com alternativeA2.com",
                "servername": "http://destinationA"
            },
            {
                "comment": "This is website B target webservice",
                "fqdn": "pageB.com",
                "serveraltname": "alternativeB1.com alternativeBb.com",
                "servername": "http://destinationB"
            }
        ]
    }
    
    PLAY RECAP *******************************************************************************************************
    hostb                      : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    
  2. 您还可以稍微更改数据结构,并使用字典而不是列表,从而更轻松地访问特定条目:
    rproxyitems:
      pageA.com:
        comment: "This ia website A"
        rproxyaltfqdn: "alternativeA1.com alternativeA2.com"
        rproxytarget: "http://destinationA"
      pageB.com:
        comment: "This ia website B"
        rproxyaltfqdn: "alternativeB1.com alternativeBb.com"
        rproxytarget: "http://destinationB"
    
    这使我们可以直接访问rproxyitems['pageA.com'],并使剧本更简单:
    - hosts: hostb
      gather_facts: no
    
      tasks:
        - debug:
            msg: "{{ nginxvhost }}"
          vars:
            nginxvhost:
              - fqdn: pageA.com
                servername: "{{ hostvars['hosta'].rproxyitems['pageA.com'].rproxytarget }}"
                serveraltname: "{{ hostvars['hosta'].rproxyitems['pageA.com'].rproxyaltfqdn }}"
                comment: "This is website A target webservice"
              - fqdn: pageB.com
                servername: "{{ hostvars['hosta'].rproxyitems['pageB.com'].rproxytarget }}"
                serveraltname: "{{ hostvars['hosta'].rproxyitems['pageB.com'].rproxyaltfqdn }}"
                comment: "This is website B target webservice"
    
    这将给出与上述相同的内容。