1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ansible-playbook set_factをdelegate_toで全てのホストに適用する

Posted at

ansible.builtin.set_fact – Set host variable(s) and fact(s). — Ansible Documentation

ansible-playbookにはset_factモジュールというものがあり、新しい変数を設定する事ができます。

モジュールの概要は以下になります。

・このモジュールでは、新しい変数を設定できます。
・変数は、セットアップモジュールによって検出されたファクトと同じように、ホストごとに設定されます。
・これらの変数は、ansible-playbookの実行中に後続の再生で使用できます。
・ファクトキャッシュを使用して実行間で変数を保存するには、cacheableをyesに設定します。
・set_factで作成された変数は、キャッシュされているかどうかによって優先順位が異なります。
・標準のAnsible変数の優先順位ルールに従って、他の多くのタイプの変数の優先順位が高いため、この値はオーバーライドされる可能性があります。
・このモジュールは、Windowsターゲットでもサポートされています。

ansible実行中に取得した出力を、後から変数にしたい時に使う場面が多いかと思います。

概要にもある通り、これらの変数はホスト毎に設定されます。

特定のホストに設定されたset_factを別のホストに使用したい場合は、delegate_toを指定して、他のホストに引き渡す必要があります。

delegate_toとは

Controlling where tasks run: delegation and local actions — Ansible Documentation

delegated_toを使うと、指定したタスクを別ホストで実行できます。本来、Playbookではhostsに一致するものに対して実行されますが、これを使用する事でhosts以外や特定のホストのみtaskが実行できます。

Playbookの例

ubuntuグループに属した、ubuntu01とubuntu02にset_factを試してみます。

  • ホストがubuntu01 → ubuntu01: definedのみ
  • ホストがubuntu02 → ubuntu02: definedのみ

と設定します。

Inventory

inventory.yml
all:
  children:
    ubuntu:
      hosts:
        ubuntu01:
        ubuntu02:

Playbook(delegate_toを使わない場合)

set_factで定義された変数はdefined、定義されていない変数はundefinedとなるようなPlaybookを作成します。

set_fact.yml
---
- hosts: ubuntu
  tasks:
    - name: set_fact to ubuntu01
      set_fact:
        ubuntu01: defined
      when: inventory_hostname == "ubuntu01"
    - name: set_fact to ubuntu02
      set_fact:
        ubuntu02: defined
      when: inventory_hostname == "ubuntu02"
    - name: debug set_fact
      debug:
        msg: |
          "ubuntu01 is {{ ubuntu01 | default('undefined') }}"
          "ubuntu02 is {{ ubuntu02 | default('undefined') }}"

実行結果

$ ansible-playbook set_fact.yml -i inventory.yml -v

PLAY [ubuntu] *******************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************
ok: [ubuntu02]
ok: [ubuntu01]

TASK [set_fact to ubuntu01] *****************************************************************************************************************
ok: [ubuntu01] => {"ansible_facts": {"ubuntu01": "defined"}, "changed": false}
skipping: [ubuntu02] => {"changed": false, "skip_reason": "Conditional result was False"}

TASK [set_fact to ubuntu02] *****************************************************************************************************************
skipping: [ubuntu01] => {"changed": false, "skip_reason": "Conditional result was False"}
ok: [ubuntu02] => {"ansible_facts": {"ubuntu02": "defined"}, "changed": false}

TASK [debug set_fact] **************************************************************************************************************
ok: [ubuntu01] => {
    "msg": "\"ubuntu01 is defined\"\n\"ubuntu02 is undefined\"\n"
}
ok: [ubuntu02] => {
    "msg": "\"ubuntu01 is undefined\"\n\"ubuntu02 is defined\"\n"
}

PLAY RECAP **********************************************************************************************************************************
ubuntu01                   : ok=3    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
ubuntu02                   : ok=3    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

ubuntu01では以下である事がわかりました。(ubuntu02はその逆です)

  • ubuntu01: defined
  • ubuntu02: undefined

Playbook(delegate_toを使う場合)

delegate_toを使用して、全てのホストに変数を受け渡してみます。

:set_fact.yml
---
- hosts: ubuntu
  tasks:
    - name: set_fact to ubuntu01
      set_fact:
        ubuntu01: defined
      delegate_to: "{{ item }}" # 変数を渡すホスト
      delegate_facts: true # fact変数の更新する場合trueにする必要がある
      with_items: "{{ groups['all'] }}" # 全ホストに受け渡す
      when: inventory_hostname == "ubuntu01"
    - name: set_fact to ubuntu02
      set_fact:
        ubuntu02: defined
      delegate_to: "{{ item }}" # 
      delegate_facts: true
      with_items: "{{ groups['all'] }}"
      when: inventory_hostname == "ubuntu02"
    - name: debug set_fact
      debug:
        msg: |
          "ubuntu01 is {{ ubuntu01 | default('undefined') }}"
          "ubuntu02 is {{ ubuntu02 | default('undefined') }}"

実行結果

ansible-playbook set_fact.yml -i inventory.yml -v
Using /Users/yukihisa/.ghq/github.com/ymmmtym/terraform-cloud-oci/ansible.cfg as config file

PLAY [ubuntu] *******************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************
ok: [ubuntu02]
ok: [ubuntu01]

TASK [set_fact to ubuntu01] *****************************************************************************************************************
ok: [ubuntu01 -> ubuntu01] => (item=ubuntu01) => {"ansible_facts": {"ubuntu01": "defined"}, "ansible_loop_var": "item", "changed": false, "item": "ubuntu01"}
ok: [ubuntu01 -> ubuntu02] => (item=ubuntu02) => {"ansible_facts": {"ubuntu01": "defined"}, "ansible_loop_var": "item", "changed": false, "item": "ubuntu02"}
skipping: [ubuntu02] => (item=ubuntu01)  => {"ansible_loop_var": "item", "changed": false, "item": "ubuntu01", "skip_reason": "Conditional result was False"}
skipping: [ubuntu02] => (item=ubuntu02)  => {"ansible_loop_var": "item", "changed": false, "item": "ubuntu02", "skip_reason": "Conditional result was False"}

TASK [set_fact to ubuntu02] *****************************************************************************************************************
skipping: [ubuntu01] => (item=ubuntu01)  => {"ansible_loop_var": "item", "changed": false, "item": "ubuntu01", "skip_reason": "Conditional result was False"}
skipping: [ubuntu01] => (item=ubuntu02)  => {"ansible_loop_var": "item", "changed": false, "item": "ubuntu02", "skip_reason": "Conditional result was False"}
ok: [ubuntu02 -> ubuntu01] => (item=ubuntu01) => {"ansible_facts": {"ubuntu02": "defined"}, "ansible_loop_var": "item", "changed": false, "item": "ubuntu01"}
ok: [ubuntu02 -> ubuntu02] => (item=ubuntu02) => {"ansible_facts": {"ubuntu02": "defined"}, "ansible_loop_var": "item", "changed": false, "item": "ubuntu02"}

TASK [debug set_fact] ***********************************************************************************************************************
ok: [ubuntu01] => {
    "msg": "\"ubuntu01 is defined\"\n\"ubuntu02 is defined\"\n"
}
ok: [ubuntu02] => {
    "msg": "\"ubuntu01 is defined\"\n\"ubuntu02 is defined\"\n"
}

PLAY RECAP **********************************************************************************************************************************
ubuntu01                   : ok=3    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
ubuntu02                   : ok=3    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

set_factのtaskから分かる通り、ubuntu01,02とも両方の変数がdefinedになっている事が分かりました。

今回はgroup['all']で全てのホストに引き渡しましたが、単一ホストをIP(ホスト名)で指定できます。
またset_factだけではなく、もちろん他のモジュールにも使用する事ができます。

Reference

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?