てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] delegate_to: localhost や connection: local 指定時の ansible_host、inventory_hostname の関係

これは、Ansible Advent Calendar 2020 (Adventar版) の 25日目の記事です。

はじめに

ターゲットノードにログインするのではなく、Ansible コントロールロードからなにか処理(APIを叩くなど)をする場合、connection: localdelegate_to をあわせて指定する場合があります。

その際の変数 ansible_hostinventory_hostname がどうなるのか、意外とわかりにくかったりしまます。私だけでしょうか・・。

よく忘れるので、試した結果をまとめておきます。検証には debug モジュールを利用します。

  • 動作確認環境
    • ansible 2.9.14


前提とするインベントリファイル

以下のインベントリファイルを利用します。比較のため、sv02ansible_host 変数を明示しないでおきます。

[sv]
sv01 ansible_host=192.168.1.1
sv02


結果まとめ

先に、結果をまとめます。

パターン sv01 ansible_host sv01 inventory_hostname sv02 ansible_host sv02 inventory_hostname
Playbook1(特に指定なし) 192.168.1.1 sv01 sv02 sv02
Playbook2(connection: local) 192.168.1.1 sv01 sv02 sv02
Playbook3(delegate_to: localhost) 192.168.1.1 sv01 localhost sv02
Playbook4(connection: localdelegate_to: localhost) 192.168.1.1 sv01 localhost sv02

ポイントとしては、delegate_to: localhost を指定すると、明示的な ansible_host 変数を定義していないホストの場合は、 ansible_hostlocalhost となる点。

検証 Playbook1: 特に指定なし

とくに表題にあるような指定はしない場合です。ごく普通の Playbook です。

---
- hosts: sv
  gather_facts: false

  tasks:
    - name: debug
      debug:
        msg:
          ansible_host: "{{ ansible_host }}"
          inventory_hostname: "{{ inventory_hostname }}"

実行結果

普通の結果です。sv02 は、ansible_host を明示していなかったので inventory_hostname の値と同じになります。

ok: [sv01] => {
    "msg": {
        "ansible_host": "192.168.1.1",
        "inventory_hostname": "sv01"
    }
}
ok: [sv02] => {
    "msg": {
        "ansible_host": "sv02",
        "inventory_hostname": "sv02"
    }
}


検証 Playbook2: connection: local を指定

以下のように、Play に connection: local を指定します。

---
- hosts: sv
  gather_facts: false
  connection: local

  tasks:
    - name: debug
      debug:
        msg:
          ansible_host: "{{ ansible_host }}"
          inventory_hostname: "{{ inventory_hostname }}"

実行結果2

実行結果1 と同じですね。

ok: [sv01] => {
    "msg": {
        "ansible_host": "192.168.1.1",
        "inventory_hostname": "sv01"
    }
}
ok: [sv02] => {
    "msg": {
        "ansible_host": "sv02",
        "inventory_hostname": "sv02"
    }
}

検証 Playbook3: delegate_to: localhost を指定

以下のように、タスクに delegate_to: localhost を指定します。

---
- hosts: sv
  gather_facts: false
  
  tasks:
    - name: debug
      debug:
        msg:
          ansible_host: "{{ ansible_host }}"
          inventory_hostname: "{{ inventory_hostname }}"
      delegate_to: localhost

実行結果3

この結果が私にとってはやや変化球です。

sv02 は、ansible_host を明示していなかったのですが、delegate_to: localhost の指定によって ansible_hostlocalhost になります。少々ねじれを感じます。

ok: [sv01] => {
    "msg": {
        "ansible_host": "192.168.1.1",
        "inventory_hostname": "sv01"
    }
}
ok: [sv02] => {
    "msg": {
        "ansible_host": "localhost",
        "inventory_hostname": "sv02"
    }
}


検証 Playbook4: connection: localdelegate_to: localhost の両方を指定

以下のように、Play に connection: local を、タスクに delegate_to: localhost を指定します。

---
- hosts: sv
  gather_facts: false
  connection: local

  tasks:
    - name: debug
      debug:
        msg:
          ansible_host: "{{ ansible_host }}"
          inventory_hostname: "{{ inventory_hostname }}"
      delegate_to: localhost

実行結果4

実行結果3 と同じです。

ok: [sv01] => {
    "msg": {
        "ansible_host": "192.168.1.1",
        "inventory_hostname": "sv01"
    }
}
ok: [sv02] => {
    "msg": {
        "ansible_host": "localhost",
        "inventory_hostname": "sv02"
    }
}


おわりに

実際は ansible_host を明示的に指定することのほうが多いのでなかなか気が付きませんでしたが、指定しない場合の挙動が意外に感じました。