无需任何魔法即可使用 Ansible 的神奇变量“hostvars”

无需任何魔法即可使用 Ansible 的神奇变量“hostvars”-每日运维

首先,一些基本的定义和规则: 在Ansible中,有一组保留变量,称为魔术 变量。由于它们是保留的,因此用户无法设置它们,如果尝试设置,Ansible 将覆盖它们。

本文特别关注一个神奇变量:  hostvars,它可以在 playbook 运行的任何时刻访问为 play 中的任何主机定义的变量。

大多数 Ansible 用户都知道清单可能包含分配给特定主机的其他变量。有时,在 playbook 运行期间,其他主机可能需要这些与主机关联的变量。在本文中,我将扩展您对使用hostvars线性主变量与主关系之外的关系的理解。

创建一个简单的库存

首先,我将ini根据一些通用角色扮演角色类型创建一个简单的类型清单。为了简单起见,我将避免使用groupsor group_vars。我还将通过使用变量的环回来避免为此练习启动任何其他主机ansible_host

库存.ini

servera ansible_host=127.0.0.1 character_type=Bard spell1=Blindness spell2=Confusion

serverb ansible_host=127.0.0.1 character_type=Wizard spell1=Lightning spell2=Fireball

serverc ansible_host=127.0.0.1 character_type=Druid spell1=Poison spell2=Plague

serverd ansible_host=127.0.0.1 character_type=Paladin spell1="Magic Missile" spell2=Fear

每个主机都分配有以下变量:ansible_hostcharacter_typespell1spell2。除 之外的每个值ansible_host对于清单中的主机来说都是唯一的。

显示主机变量

我将创建一个剧本来展示hostvars可用的内容。我还将跳过收集事实来简化剧本。

示例1.yml

<span class="hljs-meta">---</span>
<span class="hljs-attr">- name:</span> <span class="hljs-string">Example</span> <span class="hljs-string">playbook</span> <span class="hljs-string">to</span> <span class="hljs-string">showcase</span> <span class="hljs-string">hostvars</span>
<span class="hljs-attr">  hosts:</span> <span class="hljs-string">all</span>
<span class="hljs-attr">  connection:</span> <span class="hljs-string">local</span>
<span class="hljs-attr">  gather_facts:</span> <span class="hljs-literal">false</span>
<span class="hljs-attr">  tasks:</span>
<span class="hljs-attr">    - name:</span> <span class="hljs-string">Display</span> <span class="hljs-string">the</span> <span class="hljs-string">specific</span> <span class="hljs-string">hostvars</span> <span class="hljs-string">that</span> <span class="hljs-string">are</span> <span class="hljs-string">set</span> <span class="hljs-string">in</span> <span class="hljs-string">the</span> <span class="hljs-string">inventory</span> <span class="hljs-string">for</span> <span class="hljs-string">each</span> <span class="hljs-string">host</span>
      <span class="hljs-string">ansible.builtin.debug:</span>
<span class="hljs-attr">        var:</span> <span class="hljs-string">hostvars[inventory_hostname]|json_query('[character_type,spell1,spell2]')</span>

注意:您必须安装community.general集合才能使用json_query过滤器。

现在,我将运行第一个剧本:

<span class="hljs-meta">$</span>
<span class="bash"> ansible-playbook -i inventory.ini example1.yml  </span>

example1.yml 结果


PLAY [Example playbook to showcase hostvars] ***********************************

TASK [Display all of the hostvars <span class="hljs-keyword">for</span> each host] *******************************
Sunday 09 April 2023  13:09:46 -0400 (0:00:00.018)       0:00:00.018 ********** 
ok: [servera] => {
    <span class="hljs-string">"hostvars[inventory_hostname]|json_query('[character_type,spell1,spell2]')"</span>: [
        <span class="hljs-string">"Bard"</span>,
        <span class="hljs-string">"Blindness"</span>,
        <span class="hljs-string">"Confusion"</span>
    ]
}
ok: [serverb] => {
    <span class="hljs-string">"hostvars[inventory_hostname]|json_query('[character_type,spell1,spell2]')"</span>: [
        <span class="hljs-string">"Wizard"</span>,
        <span class="hljs-string">"Lightning"</span>,
        <span class="hljs-string">"Fireball"</span>
    ]
}
ok: [serverc] => {
    <span class="hljs-string">"hostvars[inventory_hostname]|json_query('[character_type,spell1,spell2]')"</span>: [
        <span class="hljs-string">"Druid"</span>,
        <span class="hljs-string">"Poison"</span>,
        <span class="hljs-string">"Plague"</span>
    ]
}
ok: [serverd] => {
    <span class="hljs-string">"hostvars[inventory_hostname]|json_query('[character_type,spell1,spell2]')"</span>: [
        <span class="hljs-string">"Paladin"</span>,
        <span class="hljs-string">"Magic Missile"</span>,
        <span class="hljs-string">"Fear"</span>
    ]
}

PLAY RECAP *********************************************************************
servera                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
serverb                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
serverc                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
serverd                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

正如您在上面看到的,剧本hostvars在针对每个主机运行时提取了唯一的内容。这是 的典型用法hostvars

如果我需要使用来自不同主机的主机变量怎么办?

有时,单个主机可能需要来自另一个主机的变量。我将在第二本剧本中解决这个问题。

示例2.yml

<span class="hljs-meta">---</span>
<span class="hljs-attr">- name:</span> <span class="hljs-string">Example</span> <span class="hljs-string">playbook</span> <span class="hljs-string">to</span> <span class="hljs-string">showcase</span> <span class="hljs-string">hostvars</span>
<span class="hljs-attr">  hosts:</span> <span class="hljs-string">all</span>
<span class="hljs-attr">  gather_facts:</span> <span class="hljs-literal">false</span>
<span class="hljs-attr">  connection:</span> <span class="hljs-string">local</span>
<span class="hljs-attr">  tasks:</span>
<span class="hljs-attr">    - name:</span> <span class="hljs-string">Set</span> <span class="hljs-string">a</span> <span class="hljs-string">fact</span> <span class="hljs-string">for</span> <span class="hljs-string">servera</span> <span class="hljs-string">using</span> <span class="hljs-string">serverd</span> <span class="hljs-string">host</span> <span class="hljs-string">variable</span>
      <span class="hljs-string">ansible.builtin.set_fact:</span>
<span class="hljs-attr">        opponent:</span> <span class="hljs-string">"<span class="hljs-template-variable">{{ hostvars['serverd']['character_type'] }}</span>"</span>
<span class="hljs-attr">      when:</span> <span class="hljs-string">inventory_hostname</span> <span class="hljs-string">==</span> <span class="hljs-string">"servera"</span>

<span class="hljs-attr">    - name:</span> <span class="hljs-string">Print</span> <span class="hljs-string">servera</span> <span class="hljs-string">hostvars</span> <span class="hljs-string">setting</span> <span class="hljs-string">derived</span> <span class="hljs-string">from</span> <span class="hljs-string">a</span> <span class="hljs-string">variable</span> <span class="hljs-string">from</span> <span class="hljs-string">serverd</span>
      <span class="hljs-string">ansible.builtin.debug:</span>
<span class="hljs-attr">        var:</span> <span class="hljs-string">hostvars[inventory_hostname]['opponent']</span>
<span class="hljs-attr">      when:</span>
<span class="hljs-bullet">        -</span> <span class="hljs-string">opponent</span> <span class="hljs-string">is</span> <span class="hljs-string">defined</span>

<span class="hljs-attr">    - name:</span> <span class="hljs-string">Print</span> <span class="hljs-string">PvP</span> <span class="hljs-string">message</span>
      <span class="hljs-string">ansible.builtin.debug:</span>
<span class="hljs-attr">        msg:</span>
<span class="hljs-bullet">          -</span> <span class="hljs-string">"Round1: <span class="hljs-template-variable">{{ character_type }}</span> vs <span class="hljs-template-variable">{{ opponent }}</span>"</span>
<span class="hljs-attr">      when:</span> <span class="hljs-string">opponent</span> <span class="hljs-string">is</span> <span class="hljs-string">defined</span>
<span class="hljs-meta">$</span>
<span class="bash"> ansible-playbook -i inventory.ini example2.yml  </span>

example2.yml 结果

PLAY [Example playbook to showcase hostvars] ***********************************

TASK [Set a fact from serverd to use <span class="hljs-keyword">for</span> servera] ******************************
Sunday 09 April 2023  14:34:19 -0400 (0:00:00.029)       0:00:00.030 ********** 
skipping: [serverb]
ok: [servera]
skipping: [serverc]
skipping: [serverd]

TASK [Print servera hostvars setting derived from a variable from serverd] ***************
Sunday 09 April 2023  14:34:20 -0400 (0:00:00.061)       0:00:00.091 ********** 
skipping: [serverb]
ok: [servera] => {
    <span class="hljs-string">"hostvars[inventory_hostname]['opponent']"</span>: <span class="hljs-string">"Paladin"</span>
}
skipping: [serverc]
skipping: [serverd]

TASK [Print PvP message] *******************************************************
Sunday 09 April 2023  14:34:20 -0400 (0:00:00.079)       0:00:00.170 ********** 
ok: [servera] => {
    <span class="hljs-string">"msg"</span>: [
        <span class="hljs-string">"Round1: Bard vs Paladin"</span>
    ]
}
skipping: [serverb]
skipping: [serverc]
skipping: [serverd]

PLAY RECAP *********************************************************************
servera                    : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
serverb                    : ok=0    changed=0    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0   
serverc                    : ok=0    changed=0    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0   
serverd                    : ok=0    changed=0    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0   

嗯,那太酷了!使用character_type变量 from serverd,剧本可以将其分配为要servera使用的变量。

如果我需要在所有主机上使用每个主机的所有特定主机变量怎么办?

有时您需要从所有主机动态获取所需的主机变量并在所有服务器上使用它们。我将创建 playbook 3 来展示这一点。

example3.yml

<span class="hljs-meta">---</span>
<span class="hljs-attr">- name:</span> <span class="hljs-string">Example</span> <span class="hljs-string">playbook</span> <span class="hljs-string">to</span> <span class="hljs-string">showcase</span> <span class="hljs-string">hostvars</span>
<span class="hljs-attr">  hosts:</span> <span class="hljs-string">all</span>
<span class="hljs-attr">  gather_facts:</span> <span class="hljs-literal">false</span>
<span class="hljs-attr">  connection:</span> <span class="hljs-string">local</span>
<span class="hljs-attr">  tasks:</span>
<span class="hljs-attr">    - name:</span> <span class="hljs-string">Set</span> <span class="hljs-string">a</span> <span class="hljs-string">fact</span> <span class="hljs-string">called</span> <span class="hljs-string">all_character_types</span>
      <span class="hljs-string">ansible.builtin.set_fact:</span>
<span class="hljs-attr">        all_character_types:</span> <span class="hljs-string">"<span class="hljs-template-variable">{{ all_character_types|default([])  + [ hostvars[item]['character_type'] ]  }}</span>"</span>
<span class="hljs-attr">      loop:</span> <span class="hljs-string">"<span class="hljs-template-variable">{{ groups['all'] }}</span>"</span>
<span class="hljs-attr">      run_once:</span> <span class="hljs-literal">true</span>

<span class="hljs-attr">    - name:</span> <span class="hljs-string">Print</span> <span class="hljs-string">hostvars</span> <span class="hljs-string">that</span> <span class="hljs-string">shows</span> <span class="hljs-string">servera</span> <span class="hljs-string">has</span> <span class="hljs-string">all</span> <span class="hljs-string">character_types</span>
      <span class="hljs-string">ansible.builtin.debug:</span>
<span class="hljs-attr">        var:</span> <span class="hljs-string">all_character_types</span>
<span class="hljs-attr">      when:</span> <span class="hljs-string">inventory_hostname</span> <span class="hljs-string">==</span> <span class="hljs-string">"servera"</span>

<span class="hljs-attr">    - name:</span> <span class="hljs-string">Print</span> <span class="hljs-string">hostvars</span> <span class="hljs-string">that</span> <span class="hljs-string">shows</span> <span class="hljs-string">serverb</span> <span class="hljs-string">has</span> <span class="hljs-string">all</span> <span class="hljs-string">character_types</span>
      <span class="hljs-string">ansible.builtin.debug:</span>
<span class="hljs-attr">        var:</span> <span class="hljs-string">all_character_types</span>
<span class="hljs-attr">      when:</span> <span class="hljs-string">inventory_hostname</span> <span class="hljs-string">==</span> <span class="hljs-string">"serverb"</span>

<span class="hljs-attr">    - name:</span> <span class="hljs-string">Print</span> <span class="hljs-string">hostvars</span> <span class="hljs-string">that</span> <span class="hljs-string">shows</span> <span class="hljs-string">serverc</span> <span class="hljs-string">has</span> <span class="hljs-string">all</span> <span class="hljs-string">character_types</span>
      <span class="hljs-string">ansible.builtin.debug:</span>
<span class="hljs-attr">        var:</span> <span class="hljs-string">all_character_types</span>
<span class="hljs-attr">      when:</span> <span class="hljs-string">inventory_hostname</span> <span class="hljs-string">==</span> <span class="hljs-string">"serverc"</span>

<span class="hljs-attr">    - name:</span> <span class="hljs-string">Print</span> <span class="hljs-string">hostvars</span> <span class="hljs-string">that</span> <span class="hljs-string">shows</span> <span class="hljs-string">serverd</span> <span class="hljs-string">has</span> <span class="hljs-string">all</span> <span class="hljs-string">character_types</span>
      <span class="hljs-string">ansible.builtin.debug:</span>
<span class="hljs-attr">        var:</span> <span class="hljs-string">all_character_types</span>
<span class="hljs-attr">      when:</span> <span class="hljs-string">inventory_hostname</span> <span class="hljs-string">==</span> <span class="hljs-string">"serverd"</span>

现在我将运行 playbook 3:

<span class="hljs-meta">$</span>
<span class="bash"> ansible-playbook -i inventory.ini example3.yml  </span>

example3.yml 结果

PLAY [Example playbook to showcase hostvars] ***********************************

TASK [Set a fact called all_character_types] ******************************************
Sunday 09 April 2023  14:59:33 -0400 (0:00:00.030)       0:00:00.030 ********** 
ok: [servera] => (item=servera)
ok: [servera] => (item=serverb)
ok: [servera] => (item=serverc)
ok: [servera] => (item=serverd)

TASK [Print hostvars that shows servera has all character_types] *********************
Sunday 09 April 2023  14:59:33 -0400 (0:00:00.080)       0:00:00.111 ********** 
skipping: [serverb]
ok: [servera] => {
    <span class="hljs-string">"all_character_types"</span>: [
        <span class="hljs-string">"Bard"</span>,
        <span class="hljs-string">"Wizard"</span>,
        <span class="hljs-string">"Druid"</span>,
        <span class="hljs-string">"Paladin"</span>
    ]
}
skipping: [serverc]
skipping: [serverd]

TASK [Print hostvars that shows serverb has all character_types] *********************
Sunday 09 April 2023  14:59:33 -0400 (0:00:00.056)       0:00:00.167 ********** 
skipping: [servera]
skipping: [serverc]
ok: [serverb] => {
    <span class="hljs-string">"all_character_types"</span>: [
        <span class="hljs-string">"Bard"</span>,
        <span class="hljs-string">"Wizard"</span>,
        <span class="hljs-string">"Druid"</span>,
        <span class="hljs-string">"Paladin"</span>
    ]
}
skipping: [serverd]

TASK [Print hostvars that shows serverc has all character_types] *********************
Sunday 09 April 2023  14:59:33 -0400 (0:00:00.054)       0:00:00.221 ********** 
skipping: [servera]
skipping: [serverb]
ok: [serverc] => {
    <span class="hljs-string">"all_character_types"</span>: [
        <span class="hljs-string">"Bard"</span>,
        <span class="hljs-string">"Wizard"</span>,
        <span class="hljs-string">"Druid"</span>,
        <span class="hljs-string">"Paladin"</span>
    ]
}
skipping: [serverd]

TASK [Print hostvars that shows serverd has all character_types] *********************
Sunday 09 April 2023  14:59:33 -0400 (0:00:00.053)       0:00:00.275 ********** 
skipping: [servera]
skipping: [serverb]
skipping: [serverc]
ok: [serverd] => {
    <span class="hljs-string">"all_character_types"</span>: [
        <span class="hljs-string">"Bard"</span>,
        <span class="hljs-string">"Wizard"</span>,
        <span class="hljs-string">"Druid"</span>,
        <span class="hljs-string">"Paladin"</span>
    ]
}

PLAY RECAP *********************************************************************
servera                    : ok=2    changed=0    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0   
serverb                    : ok=1    changed=0    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0   
serverc                    : ok=1    changed=0    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0   
serverd                    : ok=1    changed=0    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0   

在上面的输出中,您可以看到剧本设置了一个名为 的事实all_character_types。您还可以看到每个主机现在都可以使用该事实。通过根据hostvars每个主机创建事实,您现在拥有所有character_types. 您稍后可以使用这个事实。

法术战斗

character_types我将为每个角色创建一个匹配的剧本和一个随机咒语。

我将循环访问清单中的所有主机,并hostvars在循环期间利用每个主机。我还将补充剧本以使用以下 Jinja 过滤器:

  • 随机的
  • 拒绝

example4.yml

<span class="hljs-meta">---</span>
<span class="hljs-attr">- name:</span> <span class="hljs-string">Example</span> <span class="hljs-string">playbook</span> <span class="hljs-string">to</span> <span class="hljs-string">showcase</span> <span class="hljs-string">hostvars</span>
<span class="hljs-attr">  hosts:</span> <span class="hljs-string">all</span>
<span class="hljs-attr">  gather_facts:</span> <span class="hljs-literal">false</span>
<span class="hljs-attr">  connection:</span> <span class="hljs-string">local</span>
<span class="hljs-attr">  tasks:</span>
<span class="hljs-attr">    - name:</span> <span class="hljs-string">Select</span> <span class="hljs-string">a</span> <span class="hljs-string">spell</span> <span class="hljs-string">to</span> <span class="hljs-string">be</span> <span class="hljs-string">used</span> <span class="hljs-string">against</span> <span class="hljs-string">another</span> <span class="hljs-string">opponent</span>
      <span class="hljs-string">ansible.builtin.debug:</span>
<span class="hljs-attr">        msg:</span>  
<span class="hljs-bullet">          -</span> <span class="hljs-string">"<span class="hljs-template-variable">{{ character_type }}</span> uses his <span class="hljs-template-variable">{{ [spell1,spell2]|random }}</span> spell against <span class="hljs-template-variable">{{ hostvars[item]['character_type'] }}</span>"</span>
<span class="hljs-bullet">          -</span> <span class="hljs-string">"<span class="hljs-template-variable">{{ hostvars[item]['character_type'] }}</span> uses <span class="hljs-template-variable">{{ hostvars[item][('spell1','spell2')|random] }}</span> spell against <span class="hljs-template-variable">{{ character_type }}</span>"</span>
<span class="hljs-attr">      loop:</span> <span class="hljs-string">"<span class="hljs-template-variable">{{ groups['all']|reject('search',inventory_hostname)|sort|list }}</span>"</span> 

现在我将运行 playbook 4:

<span class="hljs-meta">$</span>
<span class="bash"> ansible-playbook -i inventory.ini example4.yml  </span>

example4.yml 结果

PLAY [Example playbook to showcase hostvars] ***********************************

TASK [Select a spell to be used against another opponent] *******************
Sunday 09 April 2023  17:48:38 -0400 (0:00:00.030)       0:00:00.030 ********** 
ok: [servera] => (item=serverb) => {
    <span class="hljs-string">"msg"</span>: [
        <span class="hljs-string">"Bard uses his Blindness spell against Wizard"</span>,
        <span class="hljs-string">"Wizard uses Fireball spell against Bard"</span>
    ]
}
ok: [serverb] => (item=servera) => {
    <span class="hljs-string">"msg"</span>: [
        <span class="hljs-string">"Wizard uses his Fireball spell against Bard"</span>,
        <span class="hljs-string">"Bard uses Blindness spell against Wizard"</span>
    ]
}
ok: [serverc] => (item=servera) => {
    <span class="hljs-string">"msg"</span>: [
        <span class="hljs-string">"Druid uses his Plague spell against Bard"</span>,
        <span class="hljs-string">"Bard uses Confusion spell against Druid"</span>
    ]
}
ok: [servera] => (item=serverc) => {
    <span class="hljs-string">"msg"</span>: [
        <span class="hljs-string">"Bard uses his Confusion spell against Druid"</span>,
        <span class="hljs-string">"Druid uses Poison spell against Bard"</span>
    ]
}
ok: [serverd] => (item=servera) => {
    <span class="hljs-string">"msg"</span>: [
        <span class="hljs-string">"Paladin uses his Fear spell against Bard"</span>,
        <span class="hljs-string">"Bard uses Confusion spell against Paladin"</span>
    ]
}
ok: [serverb] => (item=serverc) => {
    <span class="hljs-string">"msg"</span>: [
        <span class="hljs-string">"Wizard uses his Lightning spell against Druid"</span>,
        <span class="hljs-string">"Druid uses Poison spell against Wizard"</span>
    ]
}
ok: [serverc] => (item=serverb) => {
    <span class="hljs-string">"msg"</span>: [
        <span class="hljs-string">"Druid uses his Poison spell against Wizard"</span>,
        <span class="hljs-string">"Wizard uses Lightning spell against Druid"</span>
    ]
}
ok: [servera] => (item=serverd) => {
    <span class="hljs-string">"msg"</span>: [
        <span class="hljs-string">"Bard uses his Confusion spell against Paladin"</span>,
        <span class="hljs-string">"Paladin uses Fear spell against Bard"</span>
    ]
}
ok: [serverb] => (item=serverd) => {
    <span class="hljs-string">"msg"</span>: [
        <span class="hljs-string">"Wizard uses his Fireball spell against Paladin"</span>,
        <span class="hljs-string">"Paladin uses Fear spell against Wizard"</span>
    ]
}
ok: [serverd] => (item=serverb) => {
    <span class="hljs-string">"msg"</span>: [
        <span class="hljs-string">"Paladin uses his Fear spell against Wizard"</span>,
         <span class="hljs-string">"Wizard uses Lightning spell against Paladin"</span>
    ]
}
ok: [serverc] => (item=serverd) => {
    <span class="hljs-string">"msg"</span>: [
        <span class="hljs-string">"Druid uses his Poison spell against Paladin"</span>,
        <span class="hljs-string">"Paladin uses Magic Missile spell against Druid"</span>
    ]
}
ok: [serverd] => (item=serverc) => {
    <span class="hljs-string">"msg"</span>: [
        <span class="hljs-string">"Paladin uses his Magic Missile spell against Druid"</span>,
        <span class="hljs-string">"Druid uses Plague against spell Paladin"</span>
    ]
}

PLAY RECAP *********************************************************************
servera                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
serverb                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
serverc                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
serverd                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

在最后一个示例中,我将使用mapjson_query针对hostvars. 虽然这与第一个示例非常相似,但我实际上是hostvars使用 Jinja 地图过滤器来提取的。然后我将该信息传递给json_query并获取 2 个特定的信息位

注意json_query过滤器要求您安装该community.general集合。

example5.yml

<span class="hljs-meta">---</span>
<span class="hljs-attr">- name:</span> <span class="hljs-string">Example</span> <span class="hljs-string">playbook</span> <span class="hljs-string">to</span> <span class="hljs-string">showcase</span> <span class="hljs-string">hostvars</span>
<span class="hljs-attr">  hosts:</span> <span class="hljs-string">all</span>
<span class="hljs-attr">  gather_facts:</span> <span class="hljs-literal">false</span>
<span class="hljs-attr">  connection:</span> <span class="hljs-string">local</span>
<span class="hljs-attr">  tasks:</span>
<span class="hljs-attr">    - name:</span> <span class="hljs-string">Print</span> <span class="hljs-string">specific</span> <span class="hljs-string">hostvars</span> <span class="hljs-string">from</span> <span class="hljs-string">all</span> <span class="hljs-string">groups</span>
      <span class="hljs-string">ansible.builtin.debug:</span>
<span class="hljs-attr">        var:</span> <span class="hljs-string">groups['all']</span> <span class="hljs-string">| map('extract',hostvars)|json_query('[].[character_type,spell2]')
</span>
<span class="hljs-attr">      delegate_to:</span> <span class="hljs-string">localhost</span>
<span class="hljs-attr">      become:</span> <span class="hljs-literal">false</span>
<span class="hljs-attr">      run_once:</span> <span class="hljs-literal">true</span>

现在我将运行 playbook 5:

<span class="hljs-meta">$</span>
<span class="bash"> ansible-playbook -i inventory.ini example5.yml</span>

example5.yml 结果

PLAY [Example playbook to showcase hostvars] ***********************************

TASK [Print specific hostvars from all groups ] ******************
ok: [servera -> localhost] => {
    <span class="hljs-string">"groups['all'] | map('extract',hostvars)|json_query('[].[character_type,spell2]')"</span>: [
        [
            <span class="hljs-string">"Bard"</span>,
            <span class="hljs-string">"Confusion"</span>
        ],
        [
            <span class="hljs-string">"Wizard"</span>,
            <span class="hljs-string">"Fireball"</span>
        ],
        [
            <span class="hljs-string">"Druid"</span>,
            <span class="hljs-string">"Plague"</span>
        ],
        [
            <span class="hljs-string">"Paladin"</span>,
            <span class="hljs-string">"Fear"</span>
        ]
    ]
}

PLAY RECAP *********************************************************************
servera                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

包起来

就我个人而言,我花了一段时间才开始 hostvars 按照本文所示的方式使用魔法变量。但是,您不必是魔术师才能使用,hostvars因为魔术就在上面的示例中。摆脱hostvars困难的幻想,开始在你的剧本、任务和角色中使用它们。您会惊讶地发现它是如此简单,并且您的代码将得到如此大的改进。