zaki work log

作業ログやら生活ログやらなんやら

[Ansible] ターゲットホストのIPアドレスの参照とデフォルトゲートウェイの設定についてのメモ

Ansibleの実行の際に、設定ファイルを作ったりしたい場合に使えると便利なターゲットホストのIPアドレスの参照方法について。
内容は「動かしてみてその内容をまとめたもの」なので、ドキュメントやソースコードを追ったりまでは確認できていないです。

playbook

- hosts: gateway-test
  gather_facts: true
  gather_subset:
    - network

  tasks:
  - name: print ansible_host
    debug:
      msg:
        - "{{ ansible_host }}"
        - "{{ inventory_hostname }}"
        - "{{ ansible_facts.default_ipv4 }}"  # <- gather_facts: false だと参照不可

インベントリファイルは以下の通り

inventory_hostnameは、インベントリファイルに記載しているホスト名がセットされる。
ansible_hostは、インベントリファイルのホスト名に対してansible_host=でアドレスを明記しているとその値がセットされる。指定が無い場合はinventory_hostnameと同じホスト名がセットされる。

ansible_facts.default_ipv4gather_factsが有効の場合にセットされる。オフの場合は(ansible_facts自体はあるがdefault_ipv4が)undefinedとなる。

なお、factsの取得はネットワーク関連のみで良い場合は、

  gather_subset:
    - network

を追加することで対象情報を絞ることができる。
(詳しくは、Red Hat 齊藤秀喜さんの「はじめてのAnsibleトラブルシューティング」スライド46ページ参照)

www.slideshare.net


以下は、default_ipv4には何がセットされるのかについてのメモ。

ターゲットホストのOS設定

アドレス設定

処理対象のターゲットホストはCentOS 7でNICが2つ。
設定は以下の通り。

[zaki@vm-example ~]$ nmcli c s "System ens192" | grep ipv4
ipv4.method:                            manual
ipv4.dns:                               192.168.0.19
ipv4.dns-search:                        --
ipv4.dns-options:                       ""
ipv4.dns-priority:                      0
ipv4.addresses:                         192.168.0.37/24
ipv4.gateway:                           192.168.0.1
ipv4.routes:                            --
ipv4.route-metric:                      -1
ipv4.route-table:                       0 (unspec)
ipv4.routing-rules:                     --
ipv4.ignore-auto-routes:                いいえ
ipv4.ignore-auto-dns:                   いいえ
ipv4.dhcp-client-id:                    --
ipv4.dhcp-timeout:                      0 (default)
ipv4.dhcp-send-hostname:                はい
ipv4.dhcp-hostname:                     --
ipv4.dhcp-fqdn:                         --
ipv4.never-default:                     いいえ
ipv4.may-fail:                          はい
ipv4.dad-timeout:                       -1 (default)
[zaki@vm-example ~]$ nmcli c s "System ens224" | grep ipv4
ipv4.method:                            manual
ipv4.dns:                               172.16.1.0
ipv4.dns-search:                        --
ipv4.dns-options:                       ""
ipv4.dns-priority:                      0
ipv4.addresses:                         172.16.0.37/23
ipv4.gateway:                           --
ipv4.routes:                            --
ipv4.route-metric:                      -1
ipv4.route-table:                       0 (unspec)
ipv4.routing-rules:                     --
ipv4.ignore-auto-routes:                いいえ
ipv4.ignore-auto-dns:                   いいえ
ipv4.dhcp-client-id:                    --
ipv4.dhcp-timeout:                      0 (default)
ipv4.dhcp-send-hostname:                はい
ipv4.dhcp-hostname:                     --
ipv4.dhcp-fqdn:                         --
ipv4.never-default:                     いいえ
ipv4.may-fail:                          はい
ipv4.dad-timeout:                       -1 (default)

default gatewayが設定されているのはens192のみ。

ens192のみgateway設定

前述の設定の状態でansible_facts.default_ipv4の値を参照してみる。

[zaki@vm-example ~]$ nmcli c s "System ens192" | grep ipv4.gateway
ipv4.gateway:                           192.168.0.1
[zaki@vm-example ~]$ nmcli c s "System ens224" | grep ipv4.gateway
ipv4.gateway:                           --
TASK [print ansible_host] ****************************************************************************
ok: [192.168.0.37] => 
  msg:
  - 192.168.0.37
  - 192.168.0.37
  - address: 192.168.0.37
    alias: ens192
    broadcast: 192.168.0.255
    gateway: 192.168.0.1
    interface: ens192
    macaddress: 00:50:56:01:23:45
    mtu: 1500
    netmask: 255.255.255.0
    network: 192.168.0.0
    type: ether

デフォルトゲートウェイが設定されているens192のネットワーク情報が取れている。

ens226のみgateway設定

デフォルトゲートウェイの設定をens192からens224に設定し直す。

[zaki@vm-example ~]$ sudo nmcli c m "System ens192" ipv4.gateway ""
[zaki@vm-example ~]$ sudo nmcli c m "System ens224" ipv4.gateway 172.16.1.0
[zaki@vm-example ~]$ nmcli c s "System ens192" | grep ipv4.gateway
ipv4.gateway:                           --
[zaki@vm-example ~]$ nmcli c s "System ens224" | grep ipv4.gateway
ipv4.gateway:                           172.16.1.0
[zaki@vm-example ~]$ sudo systemctl restart network
TASK [print ansible_host] ****************************************************************************
ok: [192.168.0.37] => 
  msg:
  - 192.168.0.37
  - 192.168.0.37
  - address: 172.16.0.37
    alias: ens224
    broadcast: 172.16.1.255
    gateway: 172.16.1.0
    interface: ens224
    macaddress: 00:0c:29:f0:53:1f
    mtu: 1500
    netmask: 255.255.254.0
    network: 172.16.0.0
    type: ether

デフォルトゲートウェイ設定を削除したens192ではなく、新たに設定したens224のネットワーク情報が取れている。

gateway設定無し

デフォルトゲートウェイの設定を全て削除してみる。

[zaki@vm-example ~]$ sudo nmcli c m "System ens192" ipv4.gateway ""
[zaki@vm-example ~]$ sudo nmcli c m "System ens224" ipv4.gateway ""
[zaki@vm-example ~]$ nmcli c s "System ens224" | grep ipv4.gateway
ipv4.gateway:                           --
[zaki@vm-example ~]$ nmcli c s "System ens192" | grep ipv4.gateway
ipv4.gateway:                           --
[zaki@vm-example ~]$ sudo systemctl restart network
TASK [print ansible_host] ****************************************************************************
ok: [192.168.0.37] => 
  msg:
  - 192.168.0.37
  - 192.168.0.37
  - {}

値が入ってない。
(ansible_facts.default_ipv4という変数自体はあるが中身が空)

両方にgateway設定

そもそもこの設定はアリなのか?というのは置いておいて…

[zaki@vm-example ~]$ sudo nmcli c m "System ens192" ipv4.gateway "192.168.0.1"
[zaki@vm-example ~]$ sudo nmcli c m "System ens224" ipv4.gateway 172.16.1.0
[zaki@vm-example ~]$ nmcli c s "System ens192" | grep ipv4.gateway
ipv4.gateway:                           192.168.0.1
[zaki@vm-example ~]$ nmcli c s "System ens224" | grep ipv4.gateway
ipv4.gateway:                           172.16.1.0
[zaki@vm-example ~]$ sudo systemctl restart network
TASK [print ansible_host] ****************************************************************************
ok: [192.168.0.37] => 
  msg:
  - 192.168.0.37
  - 192.168.0.37
  - address: 192.168.0.37
    alias: ens192
    broadcast: 192.168.0.255
    gateway: 192.168.0.1
    interface: ens192
    macaddress: 00:50:56:01:23:45
    mtu: 1500
    netmask: 255.255.255.0
    network: 192.168.0.0
    type: ether

ens192の値が取れてる。1番目のNICかな?
(でも、そもそもNICに順番ってあったっけ)

この辺りの仕様について書かれたドキュメントはちょっと見つけられず。

インタフェースを指定して参照

setupなどを使って収集したfactsの値を見ていると、ansible_default_ipv4以外にansible_ens192ansible_ens224はあるので、これを参照すれば良い。
システムによってはインタフェース名はens192でなくeth0などになるかもしれない。
(手元の環境はVMware ESXi上のVM)

インタフェース名を指定

  tasks:
  - name: print ens224.ipv4
    debug:
      msg: "{{ ansible_facts.ens224.ipv4 }}"

ens224を直接指定(ハードコーディング)してPlaybookを実行すると、

ok: [192.168.0.37] => 
  msg:
    address: 172.16.0.37
    broadcast: 172.16.1.255
    netmask: 255.255.254.0
    network: 172.16.0.0

この通り取得できる。
このときデフォルトゲートウェイの設定に関係なくIPアドレス情報は取得できるが、デフォルトゲートウェイの設定は.ipv4の中には含まれない。

インタフェースリスト名も取得

インタフェースの一覧はansible_facts.interfacesで取得できる。

  - name: print interfaces
    debug:
      msg: "{{ ansible_facts.interfaces }}"

これで実行すると

ok: [192.168.0.37] => 
  msg:
  - lo
  - ens192
  - ens224

なのでこのリストからインタフェース名をピックアップし、それを使って ansible_fact[〇〇].ipv4とすれば動的に取得することもできる。

  - name: print ipv4 address (nic1)
    vars:
      nic: "{{ ansible_facts.interfaces[1] }}"
    debug:
      msg: "{{ ansible_facts[nic].ipv4 }}"

一度varsでインタフェース名リストの2番の項目(ens192)を変数nicにセットし、そのipv4アドレスを取得。

ok: [192.168.0.37] => 
  msg:
    address: 192.168.0.37
    broadcast: 192.168.0.255
    netmask: 255.255.255.0
    network: 192.168.0.0

このようにens192というインタフェース名をplaybook側で知っていなくても取得は可能。