てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] 他のホスト変数を参照、設定する(hostvars、delegate_to/delegate_facts)

はじめに

Ansible で他のホストのホスト変数を参照、設定したりする方法ご紹介します。


■ 他のホスト変数を参照する

他のホスト変数を参照するには hostvars を利用します。

Playbook

サンプル Playbook です。

localhostrt1 が実行対象で、rt1 のタスクの中で localhost のホスト変数 msg の値を参照します。

f:id:akira6592:20200417210311p:plain
他のホスト変数を参照する

---
- hosts:
    - rt1
    - localhost
  gather_facts: false

  tasks:
    # 各ホストが自分のインベントリ名を含む msg1 をセット
    - name: (task1) set my hostvars
      set_fact:
        msg: "I am {{ inventory_hostname }}."

    # rt1 のタスクとして localhost が持つホスト変数 msg1 の値を表示
    - name: (task2) debug other hostvars
      debug:
        msg: "{{ hostvars['localhost'].msg }}"    # I am localhost.
      when:
        - inventory_hostname == "rt1"  # rt1 でのみ実行

実行

Playbook を実行します。

$ ansible-playbook -i ../inventory.ini beyond_host_debug.yml 

PLAY [rt1,localhost] *********************************************************************************************

TASK [(task1) set my hostvars] ***********************************************************************************
ok: [localhost]
ok: [rt1]

TASK [(task2) debug other hostvars] ******************************************************************************
skipping: [localhost]
ok: [rt1] => {
    "msg": "I am localhost."
}

PLAY RECAP *******************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
rt1                        : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

(task2) debug other hostvars で、rt1localhost のホスト変数 msg の値である I am localhost. が表示されたことが分かります。他のホスト変数を参照していることになります。

もちろん、rt1 のタスクとして、普通に msg: "{{ msg }}" とした場合は、I am rt1. と表示されます。


■ 他のホスト変数を設定する

次に、他のホスト変数を設定するパターンです。delegate_todelegate_facts を利用します。

delegate_to はタスクの処理の移譲の指定、 delegate_facts: true でさらに facts の更新を許可します。

Playbook

サンプル Playbook です。

localhostrt1 が実行対象で、rt1 のタスクの中で localhost のホスト変数 msg の値を設定します。

f:id:akira6592:20200417210357p:plain
他のホスト変数を設定する

---
- hosts:
    - rt1
    - localhost
  gather_facts: false

  tasks:
    # rt1 のタスクとして localhost のホスト変数 msg セット
    - name: (task1) set other hostvars
      set_fact:
        msg: "set msg by rt1"
      delegate_to: localhost    # localhost の set_fact として実行う
      delegate_facts: true      # delegate 時の fact 更新を許可
      when:
        - inventory_hostname == "rt1"  # rt1 でのみ実行

    # localhost のタスクとして自分のホスト変数 msg の値を表示
    - name: (task2) debug other hostvars
      debug:
        msg: "{{ msg }'"    # set msg by rt1
      when:
        - inventory_hostname == "localhost"  # localhost でのみ実行

実行

Playbook を実行します。

$ ansible-playbook -i ../inventory.ini beyond_host_set.yml 

PLAY [rt1,localhost] *********************************************************************************************

TASK [(task1) set other hostvars] ********************************************************************************
ok: [rt1 -> localhost]
skipping: [localhost]

TASK [(task2) debug other hostvars] ******************************************************************************
skipping: [rt1]
ok: [localhost] => {
    "msg": "set msg by rt1"
}

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

(task2) debug other hostvars で、rt1 のタスク経由で設定された msg の値である set msg by rt1 が表示されたことが割ります。他のホスト変数を設定していることになります。


おわりに

他のホスト変数を参照、設定する方法をご紹介しました。

利用されるケースは多くはないかもしれませんが、いざというときに使えそうなテクニックかなと思います。

参考

delegate_facts は以下の記事で初めて知りました。ありがとうございました。

zaki-hmkc.hatenablog.com