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_ipv4
はgather_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_ens192
やansible_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側で知っていなくても取得は可能。