Ansible Tips: hostvarsによる他ノードにおける変数の参照において、play varsなどは参照不可

備忘



# サマリー
hostvarsによる他ノードにおける変数の参照において、以下の状況

|      変数      | hostvarsによる他ノードにおける変数の参照 |
| :------------: | :----------------: |
| ansible facts  |         ◯          |
| set_facts vars |         ◯          |
| inventory vars |         ◯          |
|   play vars    |         ×          |
|   block vars   |         ×          |
|   task vars    |         ×          |
| registered vars |         ◯          |

role varsなどは未検証

このあたりが影響していそう

https://docs.ansible.com/ansible/2.9_ja/user_guide/playbooks_variables.html?#registered-variables

>> 登録される変数はファクトに似ていますが、いくつかの相違点があります。ファクトと同様に、登録される変数はホストレベルの変数です。ただし、登録した変数はメモリーにのみ保存されます。(Ansible のファクトは、設定したキャッシュプラグインによってサポートされます)。 登録済みの変数は、現在の Playbook 実行の残りの部分に対してホスト上でのみ有効です。



# 環境
```
% ansible --version
ansible [core 2.15.5]
  config file = None
...
  python version = 3.9.6 (default, Feb  3 2024, 15:58:27) [Clang 15.0.0 (clang-1500.3.9.4)] (/Library/Developer/CommandLineTools/usr/bin/python3)
  jinja version = 3.1.2
  libyaml = True
```


## 例
###  inventory

```ini
host1  inventory_var1=10
host2

[all:vars]
ansible_host=localhost
ansible_connection=local
```
### playbook
```
---
- hosts: all
  vars:
    play_var1: "{{ play_var2 }}"
    play_var2: 20

  tasks:
    - name: Set_fact
      ansible.builtin.set_fact:
        set_fact3: 30

    - name: Hostvarsにおいてinventory_hostnameなどansible_factsは参照可◯
      ansible.builtin.debug:
        var: hostvars.host1.inventory_hostname

    - name: Hostvarsにおいてinventory varsは参照可◯
      ansible.builtin.debug:
        var: hostvars.host1.inventory_var1

    - name: Hostvarsにおいてplay varsは参照不可×
      ansible.builtin.debug:
        var: hostvars.host1.play_var1

    - name: Hostvarsにおいてplay vars(間接参照)は参照不可×
      ansible.builtin.debug:
        var: hostvars.host1.play_var2

    - name: Hostvarsにおいてset_factされた変数は参照可◯
      ansible.builtin.debug:
        var: hostvars.host1.set_fact3

    - name: 元play varsをset_fact
      ansible.builtin.set_fact:
        play_var1: "{{ play_var1 }}"

    - name: 元play varsもset_factによりhostvarsにおいて参照可◯  (ただし固定された為、間接参照はできない)
      ansible.builtin.debug:
        var: hostvars.host1.play_var1
      vars:
        play_var2: 200

    - name: 元play varsをset_fact
      ansible.builtin.set_fact:
        play_var2: "{{ play_var2 }}"

    - name: 元play varsもset_factによりhostvarsにおいて参照可◯
      ansible.builtin.debug:
        var: hostvars.host1.play_var2

    - name: レジスター変数を設定
      ansible.builtin.shell: hostname
      register: r

    - name: Hostvarsにおいてレジスター変数は参照可◯
      ansible.builtin.debug:
        var: hostvars.host1.r.stdout

    - name: Block varsを設定
      vars:
        block_var1: 40
      block:
        - name: Hostvarsにおいてblock varsは参照不可×
          ansible.builtin.debug:
            var: hostvars.host1.block_var1

    - name: Hostvarsにおいてtask varsは参照不可×
      vars:
        task_var1: 50
      ansible.builtin.debug:
        var: hostvars.host1.task_var1
```

### 実行
```
% ansible-playbook -i hostvars.ini hostvars.yml
...

PLAY [all] **************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************
ok: [host2]
ok: [host1]

TASK [Set_fact] *********************************************************************************************************************
ok: [host1]
ok: [host2]

TASK [Hostvarsにおいてinventory_hostnameなどansible_factsは参照可◯] *****************************************************************
ok: [host1] => {
    "hostvars.host1.inventory_hostname": "host1"
}
ok: [host2] => {
    "hostvars.host1.inventory_hostname": "host1"
}

TASK [Hostvarsにおいてinventory varsは参照可◯] **************************************************************************************
ok: [host1] => {
    "hostvars.host1.inventory_var1": "10"
}
ok: [host2] => {
    "hostvars.host1.inventory_var1": "10"
}

TASK [Hostvarsにおいてplay varsは参照不可×] *****************************************************************************************
ok: [host1] => {
    "hostvars.host1.play_var1": "VARIABLE IS NOT DEFINED!"
}
ok: [host2] => {
    "hostvars.host1.play_var1": "VARIABLE IS NOT DEFINED!"
}

TASK [Hostvarsにおいてplay vars(間接参照)は参照不可×] *******************************************************************************
ok: [host1] => {
    "hostvars.host1.play_var2": "VARIABLE IS NOT DEFINED!"
}
ok: [host2] => {
    "hostvars.host1.play_var2": "VARIABLE IS NOT DEFINED!"
}

TASK [Hostvarsにおいてset_factされた変数は参照可◯] **********************************************************************************
ok: [host1] => {
    "hostvars.host1.set_fact3": "30"
}
ok: [host2] => {
    "hostvars.host1.set_fact3": "30"
}

TASK [元play varsをset_fact] ********************************************************************************************************
ok: [host1]
ok: [host2]

TASK [元play varsもset_factによりhostvarsにおいて参照可◯  (ただし固定された為、間接参照はできない)] *********************************
ok: [host1] => {
    "hostvars.host1.play_var1": "20"
}
ok: [host2] => {
    "hostvars.host1.play_var1": "20"
}

TASK [元play varsをset_fact] ********************************************************************************************************
ok: [host1]
ok: [host2]

TASK [元play varsもset_factによりhostvarsにおいて参照可◯] ***************************************************************************
ok: [host1] => {
    "hostvars.host1.play_var2": "20"
}
ok: [host2] => {
    "hostvars.host1.play_var2": "20"
}

TASK [レジスター変数を設定] *******************************************************************************************************
changed: [host1]
changed: [host2]

TASK [Hostvarsにおいてレジスター変数は参照可◯] ************************************************************************************
ok: [host1] => {
    "hostvars.host1.r.stdout": "hMac.local"
}
ok: [host2] => {
    "hostvars.host1.r.stdout": "hMac.local"
}

TASK [Hostvarsにおいてblock varsは参照不可×] ****************************************************************************************
ok: [host1] => {
    "hostvars.host1.block_var1": "VARIABLE IS NOT DEFINED!"
}
ok: [host2] => {
    "hostvars.host1.block_var1": "VARIABLE IS NOT DEFINED!"
}

TASK [Hostvarsにおいてtask varsは参照不可×] *****************************************************************************************
ok: [host1] => {
    "hostvars.host1.task_var1": "VARIABLE IS NOT DEFINED!"
}
ok: [host2] => {
    "hostvars.host1.task_var1": "VARIABLE IS NOT DEFINED!"
}
...
```