Ansibleのntc-ansibleモジュール群まとめ (②確認コマンドモジュール実行編)

# 1. はじめに

前回の記事で、Ansibleのサードパーティー製ネットワークモジュール群である`ntc-ansible`の概要とセットアップを行いました。
[Ansibleのntc-ansibleモジュール群まとめ (①概要、セットアップ編)](https://qiita.com/tech_kitara/items/422f34e1f327b0f8b7f8)

本記事では、8つあるモジュールの内、show系の確認コマンドを実行・取得するための`ntc_show_command`モジュールの動作確認結果をまとめました。

# 2. Inventoryファイル
今回の対象機器は、test3(Cisco CSR1000V)とします。
以下のInventoryファイルを作成し、`/home/user/ntc-ansible/`配下に格納します。

```text:inventory
[cisco]
192.168.100.201

[cisco:vars]
hostname=test3
ansible_username=test3
ansible_password=cisco
enable_secret=test3
```

# 3. 実行例1: show versionの結果を表示

### 3.1. Playbook
以下のPlaybookを作成し、`/home/user/ntc-ansible/`配下に格納します。
`ntc_show_command`モジュールの実行内容は、対象機器へのTelnetログイン、show versionの実行、出力結果のファイル保存になります。
また`debug`モジュールで、出力結果の表示も行っています。

```yaml:playbook1.yml
---

- hosts: cisco
  gather_facts: no
  connection: local

  tasks:
    - name: run show command on remote devices
      ntc_show_command:
        connection: telnet   # 今回はログイン方式としてtelnetを指定。デフォルト値はssh
        command: show version
        use_templates: false   # パース用のTextFSM templateの使用有無を指定。デフォルト値はtrue
        provider: "{{ cli }}"
        local_file: './{{ hostname }}_log.txt'   # 保存先のディレクトリ・ファイル名を指定
      register: result

    - name: display parsed show command
      debug:
        var: result.response

  vars:
    cli:
      host: "{{ inventory_hostname }}"
      username: "{{ ansible_username }}"
      password: "{{ ansible_password }}"
      secret: "{{ enable_secret }}"
      platform: cisco_ios   # 対象機器のOSに合わせて指定する必要あり
```

### 3.2. 実行結果
`debug`モジュール(display parsed show command)の実行結果として、show versionの結果が表示されることが確認できました。
また、記載は割愛しますが、`ntc_show_command`モジュールの結果として、指定ディレクトリに実行結果のファイルが生成されていることも確認できました。

```yaml:
[user@localhost ntc-ansible]$ ansible-playbook -i inventory playbook1.yml

PLAY [cisco] ******************************************************************************************************************

TASK [run show command on remote devices] *************************************************************************************
ok: [192.168.100.201]

TASK [display parsed show command] ********************************************************************************************
ok: [192.168.100.201] => {
    "result.response": [
        "Cisco IOS XE Software, Version 03.17.02.S - Standard Support Release\nCisco IOS Software, CSR1000V Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 15.6(1)S2, RELEASE SOFTWARE (fc1)\n(中略)"
    ]
}

PLAY RECAP ********************************************************************************************************************
192.168.100.201            : ok=2    changed=0    unreachable=0    failed=0   
```


# 4. 実行例2: TextFSMでパースしたshow versionの結果を表示

### 4.1. Playbook
次に、TextFSMのtemplateを用いて、show versionの結果をパースしてみます。
以下のPlaybookを作成し、`/home/user/ntc-ansible/`配下に格納します。
実行例1との違いは、`template_dir`オプションでtemplateファイルが格納されているディレクトリを指定する点と、`debug`モジュールで出力要素(version)を細かく指定している点です。

```yaml:playbook1.yml
---

- hosts: cisco
  gather_facts: no
  connection: local

  tasks:
    - name: run show command on remote devices
      ntc_show_command:
        connection: telnet
        command: show version
        use_templates: true
        template_dir: './ntc-templates/templates/'   # showコマンドパース用のtemplateファイルディレクトリを指定
        provider: "{{ cli }}"
        local_file: './{{ hostname }}_log.txt'   # 保存先のディレクトリ・ファイル名を指定(保存されるのはパース前の結果)
      register: result

    - name: display parsed show command
      debug:
        var: result.response   # パースした結果を表示

    - name: desplay parsed show command (partial)
      debug:
        var: result.response[0].version   # パースした結果の内、バージョン情報のみ表示

  vars:
    cli:
      host: "{{ inventory_hostname }}"
      username: "{{ ansible_username }}"
      password: "{{ ansible_password }}"
      secret: "{{ enable_secret }}"
      platform: cisco_ios
```

### 4.2. 実行結果
`debug`モジュール(display parsed show command)の実行結果として、パースされた機種、ホスト名、シリアル番号、バージョン等が表示されているのが分かります。
また、`debug`モジュール(desplay parsed show command (partial))の実行結果として、バージョンのみ表示させることもできました。

```yaml:
[user@localhost ntc-ansible]$ ansible-playbook -i inventory playbook1.yml

PLAY [cisco] ******************************************************************************************************************

TASK [run show command on remote devices] *************************************************************************************
ok: [192.168.100.201]

TASK [display parsed show command] ********************************************************************************************
ok: [192.168.100.201] => {
    "result.response": [
        {
            "config_register": "0x2102", 
            "hardware": [
                "CSR1000V"
            ], 
            "hostname": "test3", 
            "reload_reason": "<NULL>", 
            "rommon": "IOS-XE", 
            "running_image": "packages.conf", 
            "serial": [
                "9TKYHR8X0HR"
            ], 
            "uptime": "1 day, 12 hours, 2 minutes", 
            "version": "15.6(1)S2"
        }
    ]
}

TASK [desplay parsed show command (partial)] **********************************************************************************
ok: [192.168.100.201] => {
    "result.response[0].version": "15.6(1)S2"
}

PLAY RECAP ********************************************************************************************************************
192.168.100.201            : ok=3    changed=0    unreachable=0    failed=0  
```

# 5. 公式モジュールとの比較
showコマンド取得が可能なモジュールについて、各機能のサポート状況を表でまとめてみました。

| No. | モジュール名       | 分類 | オプションの豊富さ | マルチベンダー | CLIログイン方式 |
|:----|:-----------------|:-----:|:-----------:|:-----------:|:-----------:|
|  1  | ios_command | 公式 | ◎ | × | SSH |
|  2  | cli_command | 公式 | 〇 | 〇 | SSH |
|  3  | ntc_show_command | 非公式 | 〇 | 〇 | SSH/Telnet |
|  4  | telnet | 公式 | △ | 〇 | Telnet |

個人的な意見ですが、やはり`ios_command`が一番機能が豊富で、使い勝手がいいと思っています。
`cli_command`と`ntc_show_command`はオプションの豊富さは同程度かと思います。どちらにも使いたいオプションが含まれる場合は、公式サポートや開発のアクティビティの観点から前者、対象機器がSSHをサポートしていなかったり、止むに止まれぬ理由でSSH化できない場合は、後者を選択するのが良いのではないでしょうか。
`telnet`は、SSH化に使うだけだし、最低限コマンドを実行できればいいよ、といった用途であれば必要十分かと思います。

今回は、確認コマンド系のお話でした。次回、設定変更系のモジュールの調査結果も投稿したいと思います。