はじめに
Ansible 2.9 から、ネットワークモジュールの fact 収集は、gather_fact
の指定(デフォルト yes
)に基づくように仕様変更されました。
有効の場合は、内部で ios_facts
、eos_facts
などの、ベンダー別の *_facts
モジュールが呼ばれます。
gather_fact
によってネットワーク機器の fact 収集する場合、Playbook 実行ログに以下の警告が表示されます。(ここでは、Cisco IOS を対象にした場合を想定)
TASK [Gathering Facts] ****************************************************** [WARNING]: Ignoring timeout(10) for ios_facts
これは、私なりに解釈、整理すると以下のとおりです。
DEFAULT_GATHER_TIMEOUT
で設定された 10秒(デフォルト)は設定は無視するios_facts
モジュールが呼ばれる- なので、タイムアウトの設定は
ios_facts
モジュール(厳密にはnetwork_cli
コネクションプラグイン)が利用するpersistent_connect_timeout
(デフォルト 30秒)や、persistent_command_timeout
などの各種タイムアウト値が適用される - 警告メッセージの生成コードはこのあたり (Ansible 2.9.2 の場合)
当初私は意味を気にしていなかったのですが、同僚に聞かれたので調べることにしました。
この記事では、この意味が分かるまでに検証したことをまとめます。
検証環境
Ansible 2.9.2
■ 検証1: 無視されるタイムアウトの設定はどこか
警告メッセージ
[WARNING]: Ignoring timeout(10) for ios_facts
の (10)
の 10
という設定値はどこからきているのでしょうか。
ためしに、ansible.cfg
の defaults
セクションの gather_timeout
の値をデフォルトの 10
から 20
に変更します。
[defaults] gather_timeout = 20
設定変更が反映されているか確認します。
$ ansible-config dump --only-changed DEFAULT_GATHER_TIMEOUT(/home/ansible/ansible.cfg) = 20
実行する Playbook を準備します。
- hosts: ios gather_facts: yes # デフオルト vars: ansible_network_os: ios ansible_network_connection: network_cli tasks: - name: show command test ios_command: commands: - show version
Playbook を実行します。
$ ansible-playbook -i ../inventory.ini ios_show_test.yml PLAY [ios] *********************************************************************************************** TASK [Gathering Facts] ******************************************************************************************* [WARNING]: Ignoring timeout(20) for ios_facts ok: [ios1] ...(略)...
狙い通り、timeout(20)
というメッセージに変わりました。これにより、無視されるタイムアウト値は、DEFAULT_GATHER_TIMEOUT(ansible.cfg
の gather_timeout
などで設定可)であることが分かりました。
ansible.cfg
の設定は元に戻して、次の検証にいきます。
■ 検証2: 適用されるタイムアウトの設定はどこか
それでは、どのタイムアウト値が適用されるのでしょうか。
前述の Playbook では、コネクションプラグインとして、network_cli
を利用しています。そのため、公式ドキュメントの network_cli
のページを確認してみます。
いくつかタイムアウト関連の設定があります。ここでは 2つの設定を検証します。
設定名 | 変数名 | 概要 |
---|---|---|
persistent_connect_timeout |
ansible_connect_timeout |
接続タイムアウト |
persistent_command_timeout |
ansible_command_timeout |
コマンド実行タイムアウト |
接続 timeout
先ほどの Playbook に、接続タイムアウトの変数である ansible_connect_timeout
の指定を追加します。検証のため、極端に 1秒にします。
- hosts: ios gather_facts: yes # デフオルト vars: ansible_network_os: ios ansible_network_connection: network_cli ansible_connect_timeout: 1 # point tasks: - name: show command test ios_command: commands: - show version
Playbook を実行します。
$ ansible-playbook -i ../inventory.ini ios_show_test.yml PLAY [ios] *********************************************************************************************** TASK [Gathering Facts] ******************************************************************************************* [WARNING]: Ignoring timeout(10) for ios_facts fatal: [ios1]: FAILED! => {"ansible_facts": {}, "changed": false, "failed_modules": {"ios_facts": {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "failed": true, "invocation": {"module_args": {"auth_pass": null, "authorize": null, "gather_network_resources": null, "gather_subset": ["all"], "host": null, "password": null, "port": null, "provider": null, "ssh_keyfile": null, "timeout": null, "username": null}}, "msg": "socket_path does not exist or cannot be found.\nSee the socket_path issue category in Network Debug and Troubleshooting Guide", "warnings": ["Platform darwin on host ios1 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change this. See https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information."]}}, "msg": "The following modules failed to execute: ios_facts\n"}
エラーになりました。変数 ansible_connect_timeout
による 接続タイムアウトの設定が適用されたようです。
コマンド実行 timeout
今度は、コマンド実行タイムアウトの変数である ansible_command_timeout
の指定を追加します。検証のため、極端に 1秒にします。
- hosts: ios gather_facts: yes # デフオルト vars: ansible_network_os: ios ansible_network_connection: network_cli ansible_command_timeout: 1 # point tasks: - name: show command test ios_command: commands: - show version
Playbook を実行します。
$ ansible-playbook -i ../inventory.ini ios_show_test.yml PLAY [ios] *********************************************************************************************** TASK [Gathering Facts] ******************************************************************************************* [WARNING]: Ignoring timeout(10) for ios_facts fatal: [ios1]: FAILED! => {"ansible_facts": {}, "changed": false, "failed_modules": {"ios_facts": {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "failed": true, "invocation": {"module_args": {"auth_pass": null, "authorize": null, "gather_network_resources": null, "gather_subset": ["all"], "host": null, "password": null, "port": null, "provider": null, "ssh_keyfile": null, "timeout": null, "username": null}}, "msg": "command timeout triggered, timeout value is 1 secs.\nSee the timeout setting options in the Network Debug and Troubleshooting Guide.", "warnings": ["Platform darwin on host ios1 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change this. See https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information."]}}, "msg": "The following modules failed to execute: ios_facts\n"}
エラーになりました。エラーメッセージを見ると
command timeout triggered, timeout value is 1 secs
とあります。変数 ansible_command_timeout
による 接続タイムアウトの設定が適用されたようです。
まとめ
- Ansible 2.9 から ネットワークモジュールの fact 収集は
gather_facts
経由で行われるようになった - 内部的には
ios_facts
のようなベンダー個別の fact 収集モジュールが呼ばれる - そのため、タイムアウトの設定はそのジュールが利用するコネクションプラグインに依存する
network_cli
コネクションプラグイン)の場合はpersistent_connect_timeout
や、persistent_command_timeout
など