はじめに
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など