てくなべ (tekunabe)

ansible / network / automation

[Ansible] "[WARNING]: Ignoring timeout(10) for ios_facts" の正体とタイムアウトの設定方法

はじめに

Ansible 2.9 から、ネットワークモジュールの fact 収集は、gather_fact の指定(デフォルト yes)に基づくように仕様変更されました。 有効の場合は、内部で ios_factseos_facts などの、ベンダー別の *_facts モジュールが呼ばれます。

https://tekunabe.hatenablog.jp/entry/2019/11/24/ansible29_nw_fact_default_enabled:titile

gather_fact によってネットワーク機器の fact 収集する場合、Playbook 実行ログに以下の警告が表示されます。(ここでは、Cisco IOS を対象にした場合を想定)

TASK [Gathering Facts] ******************************************************
[WARNING]: Ignoring timeout(10) for ios_facts

これは、私なりに解釈、整理すると以下のとおりです。

当初私は意味を気にしていなかったのですが、同僚に聞かれたので調べることにしました。

この記事では、この意味が分かるまでに検証したことをまとめます。

検証環境

Ansible 2.9.2


■ 検証1: 無視されるタイムアウトの設定はどこか

警告メッセージ

[WARNING]: Ignoring timeout(10) for ios_facts

(10)10 という設定値はどこからきているのでしょうか。

ためしに、ansible.cfgdefaults セクションの 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_TIMEOUTansible.cfggather_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 による 接続タイムアウトの設定が適用されたようです。


まとめ