如何基于另一个变量在ansible中注册变量?

如何基于另一个变量在ansible中注册变量?,ansible,Ansible,我在不同的子网上有很多服务器。我想为每个安装点配置一个NFS安装点,根据它们所在的子网选择NFS服务器。我可以很容易地使用多个代码块,每个代码块在条件下具有不同的,但使用的不仅仅是几个网络,这会导致大量代码重复: - name: mount /home for 192.168.1.0 mount: path: /home src: nfsserver-1.domain.net:/vol/home fstype: nfs opts: tcp,hard,intr,

我在不同的子网上有很多服务器。我想为每个安装点配置一个NFS安装点,根据它们所在的子网选择NFS服务器。我可以很容易地使用多个代码块,每个代码块在条件下具有不同的,但使用的不仅仅是几个网络,这会导致大量代码重复:

- name: mount /home for 192.168.1.0
  mount:
    path: /home
    src: nfsserver-1.domain.net:/vol/home
    fstype: nfs
    opts: tcp,hard,intr,bg
    state: mounted
  when: ansible_default_ipv4.network == '192.168.1.0'

- name: mount /home for 192.168.2.0
  mount:
    path: /home
    src: nfsserver-2.domain.net:/vol/home
    fstype: nfs
    opts: tcp,hard,intr,bg
    state: mounted
  when: ansible_default_ipv4.network == '192.168.2.0'
如何基于另一个变量注册变量?当我尝试下面的代码块时,它失败了,因为多个任务注册
检测到\u nfs\u server
并相互冲突。(当
块适用时,
不只是注册变量)

到目前为止,我找到的最佳解决方案是运行shell脚本,如下所示。这很好,但需要使用shell脚本,而不是在ansible内部执行变量操作。有没有一种好方法可以基于另一个变量而不是依赖shell脚本在ansible中注册一个变量

- name: detect_nfs_server
  shell: if [ '{{ ansible_default_ipv4.network }}' = '192.168.1.0' ] ; then echo 'nfsserver-1.domain.net' ; elif [ '{{ ansible_default_ipv4.network }}' = '192.168.2.0' ] ; then echo 'nfsserver-2.domain.net' ; else echo 'domain not detected' ; fi
  register: detected_nfs_server
  changed_when: False

- name: fail if domain not detected
  fail:
    msg: 'domain not detected'
  when: detected_domain.stdout == 'domain not detected'

- name: mount /home
  mount:
    path: /home
    src: {{ detected_nfs_server.stdout }}:/vol/home
    fstype: nfs
    opts: tcp,hard,intr,bg
    state: mounted

一种选择可能是在不同子网上的每个NFS服务器上加载一个var文件。然后您可以引用变量

nfs1 = 192.168.1.x
nfs2 = 192.168.2.x
nfs3 = 192.168.3.x

还有更多的选择。可以使用字典(存储在组中?)。比如说

vars:
  detected_nfs_server:
    192.168.1.0: nfsserver-1.domain.net
    192.168.2.0: nfsserver-2.domain.net
    192.168.3.0: nfsserver-3.domain.net
tasks:
- name: mount /home
  mount:
    path: /home
    src: "{{ detected_nfs_server[ansible_default_ipv4.network] }}:/vol/home"
    fstype: nfs
    opts: tcp,hard,intr,bg
    state: mounted
- set_fact:
    detected_nfs_server: "{{ 'nfsserver-' ~
                              address.split('.').2 ~
                             '.domain.net' }}"
- name: mount /home
  mount:
    path: /home
    src: "{{ detected_nfs_server }}:/vol/home"
    fstype: nfs
    opts: tcp,hard,intr,bg
    state: mounted
下一个选项是生成服务器的名称。比如说

vars:
  detected_nfs_server:
    192.168.1.0: nfsserver-1.domain.net
    192.168.2.0: nfsserver-2.domain.net
    192.168.3.0: nfsserver-3.domain.net
tasks:
- name: mount /home
  mount:
    path: /home
    src: "{{ detected_nfs_server[ansible_default_ipv4.network] }}:/vol/home"
    fstype: nfs
    opts: tcp,hard,intr,bg
    state: mounted
- set_fact:
    detected_nfs_server: "{{ 'nfsserver-' ~
                              address.split('.').2 ~
                             '.domain.net' }}"
- name: mount /home
  mount:
    path: /home
    src: "{{ detected_nfs_server }}:/vol/home"
    fstype: nfs
    opts: tcp,hard,intr,bg
    state: mounted

如果我设置这些变量,有没有办法让它们变得有用?看起来,我能写的任何引用这些变量的代码,我都可以用这些变量替换其中的IP地址,这并没有解决代码重复的实际问题。我想不出来。本指南更深入地介绍了如何注册和使用变量。简而言之,您可以将命令的输出注册为变量,然后在游戏中重复使用。这非常有效。我使用
set\u fact
设置
检测到的\u nfs\u服务器
,然后使用
detected\u nfs\u服务器[ansible\u default\u ipv4.network]
根据
网络
变量提取所需的值。谢谢