■ はじめに
fact といえば、サーバー系モジュールの場合は、gather_facts: yes(デフォルト)で収集されましたが、ネットワークモジュールの場合は事情が異なりました。
具体的には、gather_facts: yes では、Ansible コントロールノード自身の fact が収集されていました。ネットワーク機器側の fact を収集するには ios_facts モジュールや、junos_facts モジュールなど、プラットフォーム個別の *_facts モジュールを使う必要がありました。
Ansible 2.9 では、gather_facts: yes(デフォルト)でネットワーク機器側の fact が収集されるようになりました。逆にAnsible コントロールノード自身の fact は収集されなくなりました。
この記事では、IOS を対象にして、簡単な例をもとに説明します。
※ ログのみやすさのため、CALLBACK PLUGIN を YAML に変更しています。
- 環境
- Ansible 2.9.0
■ デフォルトではコンフィグも収集される
デフォルトで、gather_facts: yes なので、そのまま試します。debug モジュールで、fact の名前空間である、ansible_facts をまるごと出力します。
- Playbook
- hosts: ios tasks: - name: debug facts debug: var: ansible_facts
- 実行
この場合、ios_facts モジュールでいうと gather_subset: all で fact を収集します。
つまり、下記のように コンフィグも収集 されます。
$ ansible-playbook -i ../inventory.ini fact_test.yml
PLAY [ios] ******************************************************************************
TASK [Gathering Facts] ******************************************************************
[WARNING]: Ignoring timeout(10) for ios_facts
ok: [ios1]
TASK [debug facts] **********************************************************************
ok: [ios1] =>
ansible_facts:
_facts_gathered: true
discovered_interpreter_python: /usr/bin/python
net_all_ipv4_addresses:
- 172.16.100.1
- 10.10.20.48
net_all_ipv6_addresses: []
net_api: cliconf
net_config: |-
!
! Last configuration change at 12:35:22 UTC Sun Nov 24 2019 by developer
!
version 16.11
service timestamps debug datetime msec
service timestamps log datetime msec
service call-home
platform qfp utilization monitor load 80
no platform punt-keepalive disable-kernel-core
...(略)...
end
net_filesystems:
- 'bootflash:'
net_filesystems_info:
'bootflash:':
spacefree_kb: 5793276.0
spacetotal_kb: 7712692.0
net_gather_network_resources: []
net_gather_subset:
- hardware
- default
- interfaces
- config
net_hostname: csr1000v-1
net_image: bootflash:packages.conf
net_interfaces:
GigabitEthernet1:
bandwidth: 1000000
description: MANAGEMENT INTERFACE - DON'T TOUCH ME
duplex: Full
ipv4:
- address: 10.10.20.48
subnet: '24'
lineprotocol: up
macaddress: 0050.56bb.e99c
mediatype: Virtual
mtu: 1500
operstatus: up
type: CSR vNIC
...(略)...
net_iostype: IOS-XE
net_memfree_mb: 2074004.25
net_memtotal_mb: 2378439.3125
net_model: CSR1000V
net_neighbors: {}
net_python_version: 2.7.10
net_serialnum: XXXXXXXXXXX
net_system: ios
net_version: 16.11.01a
network_resources: {}
PLAY RECAP ******************************************************************************
ios1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
■ gather_facts: yes のまま収集対象を絞るには
先ほどの例は gather_subset: all 相当だったので、不要な情報もあったかもしれません。そもそも fact 収集が不要であれば gather_facts: no にしますが、gather_facts: yes のまま収集対象を制限したいケースもあるかと思います。
module_defaultsを利用して、ios_facts モジュールの gather_subset オプションを指定することで必要な情報に制限できます。
・・・と思って試したのですが、うまく制限できませんでした。
公式ブログにも掲載されている方法ですが、微妙に試し方が誤っているのかもしれません。
うまく制限できなかったものの、ひとまずログとして残しておきます。
- Playbook
- hosts: ios module_defaults: # 暗黙的に実行される ios_facts のオプションを指定しておく ios_facts: gather_subset: "!config" # コンフィグを ! で除外 tasks: - name: debug facts debug: var: ansible_facts
- 実行
$ ansible-playbook -i ../inventory.ini fact_test.yml
PLAY [ios] ***********************************************************************
TASK [Gathering Facts] *******************************************************************
[WARNING]: Ignoring timeout(10) for ios_facts
ok: [ios1]
TASK [debug facts] **********************************************************************
ok: [ios1] =>
ansible_facts:
_facts_gathered: true
discovered_interpreter_python: /usr/bin/python
net_all_ipv4_addresses:
- 172.16.100.1
- 10.10.20.48
net_all_ipv6_addresses: []
net_api: cliconf
net_config: |-
!
! Last configuration change at 13:11:27 UTC Sun Nov 24 2019 by developer
!
version 16.11
service timestamps debug datetime msec
service timestamps log datetime msec
service call-home
platform qfp utilization monitor load 80
no platform punt-keepalive disable-kernel-core
...(略)...
end
net_filesystems:
- 'bootflash:'
net_filesystems_info:
'bootflash:':
spacefree_kb: 5793252.0
spacetotal_kb: 7712692.0
net_gather_network_resources: []
net_gather_subset:
- hardware
- default
- interfaces
- config
net_hostname: csr1000v-1
net_image: bootflash:packages.conf
net_interfaces:
GigabitEthernet1:
bandwidth: 1000000
description: MANAGEMENT INTERFACE - DON'T TOUCH ME
duplex: Full
ipv4:
- address: 10.10.20.48
subnet: '24'
lineprotocol: up
macaddress: 0050.56bb.e99c
mediatype: Virtual
mtu: 1500
operstatus: up
type: CSR vNIC
...(略)...
net_iostype: IOS-XE
net_memfree_mb: 2074004.25
net_memtotal_mb: 2378439.3125
net_model: CSR1000V
net_neighbors: {}
net_python_version: 2.7.10
net_serialnum: XXXXXXXXXXX
net_system: ios
net_version: 16.11.01a
network_resources: {}
PLAY RECAP ******************************************************************************
ios1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ということで、意図せずコンフィグも収集されてしまいました。module_defaults で指定した内容が反映されていないように見えます。なにか分かったら更新します。
[2019/11/24追記]
ansible.cfgの DEFAULT_GATHER_SUBSETに設定したら効きましが、影響範囲が広すぎますね。。
■ まとめ
- Ansible 2.8 までは
ios_factsモジュールなど、プラットフォーム個別の fact 収集モジュールで fact を収集していた - Ansible 2.9 でネットワークモジュールも
gather_facts: yes(デフォルト) で fact が収集されるようになった *_factsモジュールでいう、gather_subset: all相当なので、コンフィグも収集される- 対象を制限るには
module_defaultsを利用すれば、よい・・はず・・・だが、今回の試し方ではうまくいかなかった