てくなべ (tekunabe)

ansible / network / automation / StackStorm

[Ansible] ネットワークプラットフォームのバージョンとサポートの関係

はじめに

Ansible は、Ansible 2.8 現在 50以上のネットワークプラットフォームに対応しています。

プラットフォームごとに、どのバージョンでテスト、サポートされているかの情報が、探すのにやや手間取ってしまうので、こちらにリンクまとめておきます。

Ansible Network Team でメンテナンスされているネットワークモジュール

docs.ansible.com

Ansible のバージョンとネットワークプラットフォームのバージョンのマトリックス

access.redhat.com

その他 参考

www.redhat.com

[Ansible] 小ネタ: Playbook は JSON で書ける

はじめに

※あくまで小ネタの話なので実運用で利用するのはおすすめしません。

YAML は JSON のほぼスーパーセットなのであれば、JSON で Playbook を書けるのでは?と思ったことがあったので試してみました。

Playbook

$ cat test.yml 
[
  {
    "gather_facts": false, 
    "connection": "local", 
    "tasks": [
      {
        "debug": {
          "msg": "hello!"
        }
      }
    ], 
    "hosts": "localhost"
  }
]
  • (参考) 上記 Playbook を通常通り YAML で書いた場合
- hosts: localhost
  gather_facts: false
  connection: local
  
  tasks:
    - debug:
        msg: "hello!"

YAML から JSON への変換を試すには、このようなサービスを利用するとお手軽です。

実行

$ ansible-playbook -i localhost, test.yml 

PLAY [localhost] ******************************************************************************

TASK [debug] **********************************************************************************
ok: [localhost] => {
    "msg": "hello!"
}

PLAY RECAP ************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0   

できました。(Ansible 2.7)

Playbook のリストやディクショナリの関係がよく分からなくなったりした場合、JSONで書いたり眺めたりすると良い練習になるかも知れません。

補足

Ansible では YAML 1.1 を扱いますが、YAML 1.2 の仕様には

The primary objective of this revision is to bring YAML into compliance with JSON as an official subset.

という記載があります。

[Ansible] エラー「paramiko is not installed: No module named 'paramiko'」の原因と対策

■ エラーの原因と対策

Ansible コントールノードに paramiko (PythonSSHクライアント実装ライブラリ)がインストールされていない環境で、Ansible を実行すると、以下のようなエラーが表示されて異常終了してしまいます。

fatal: [iosao1]: FAILED! => {"msg": "paramiko is not installed: No module named 'paramiko'"}

対策としては、paramiko をインストールします。

pip install paramiko


■ 補足

Ansible 2.8 以降でネットワークモジュール利用時に注意

Ansible 2.7 台までは、 paramiko も一緒にインストールされる構成でしたが、Ansible 2.8 から一緒にインストールされない構成になりました。

2.8 からのドキュメントにも関連の記述が追記されました。

In order to use the paramiko connection plugin or modules that require paramiko, install the required module

paramiko was included in Ansible’s requirements.txt prior to 2.8.

これでも、例えばサーバーに対して ssh コネクションプラグインで接続する場合は問題ありません。paramiko を利用しないためです。 一方で、ネットワークモジュールとセットで利用する network_cli コネクションプラグインで接続する場合は、内部で paramiko を利用するため paramiko がないと前述のようなエラーになってしまいます。

例えば以下のような Playbook です。

- hosts: iosal
  gather_facts: no
  connection: network_cli

  tasks:
    - name: show version
      ios_command:
        commands:
          - show version

2.7 からのアップデートの場合は paramiko が残る

Ansible 2.7 までのバージョンから 2.8 にアップデートすると、paramiko は残ります。 そのため、「Ansible 2.8 の環境なのに、paramiko がないエラーが出る環境と出ない環境がある」という現象が起こりえます。

  • Ansible 2.7.10 から pip install -U ansible して 2.8.0 にアップデートした場合
$ pip list
Package      Version
------------ -------
ansible      2.8.0  
asn1crypto   0.24.0 
bcrypt       3.1.6  
cffi         1.12.3 
cryptography 2.6.1  
Jinja2       2.10.1 
MarkupSafe   1.1.1  
paramiko     2.4.2    <--
pip          10.0.1 
pyasn1       0.4.5  
pycparser    2.19   
PyNaCl       1.3.0  
PyYAML       5.1    
setuptools   39.0.1 
six          1.12.0 
  • Ansible 2.8 を新規インストールした場合の pip list
$ pip list
Package      Version
------------ -------
ansible      2.8.0  
asn1crypto   0.24.0 
cffi         1.12.3 
cryptography 2.6.1  
Jinja2       2.10.1 
MarkupSafe   1.1.1  
pip          10.0.1 
pycparser    2.19   
PyYAML       5.1    
setuptools   39.0.1 
six          1.12.0 

ncclient インストールで一緒に paramiko もインストールされる

Junos モジュールなどではnetconf コネクションプラグインで接続します。そのため、NETCONF 接続 Python ライブラリである ncclient を別途インストールします。 この際、paramiko も一緒にインストールされる構成になっています。

[Ansible] Ansible 2.8 リリース、便利機能や注意点まとめ

f:id:akira6592:20190517162018p:plain

■ はじめに

2019/05/16 に Ansible 2.8.0 がリリースされました。多数のモジュールの追加や、機能追加、バグ修正機能削除機能の非推奨化、仕様変更が含まれています。

大きめなトピックとしては以下のものがあります。

この記事では、CHANGELOGPorting Guide を中心に、気になった点と関連URLをまとめます。 特性が分かるように、主観ですが「便利」「地味に便利」「ちょっと注意」というタグのようなものをつけています。

また、★ 印があるものは、2019/05/31 開催予定の Ansible Night in Osaka 2019.05でもご紹介する予定です。リモート参加枠もありますので、よろしければご参加ください。

[2019/06/01追記] 当日の発表資料です。

www.slideshare.net

特に CHANGELOG は、それでだけ見てもどういったことが分かりにくいものもありますので、関連URLも参考にしていただくと良いかと思います。Ansible 2.8 へのアップデート判断の材料になれば幸いです。

■ 変更

全体

権限昇格

ansible-galaxy

制御 / jinja2 / 変数

インベントリ

環境

ファイル

システム

Windows

ネットワーク


■ 新規プラグイン

コネクションプラグイン

インベントリプラグイン


■ 新規モジュール

Cloud

Files

Monitoring

Net Tools

Network

Notification

Source Control

System


■ まとめ

Ansible 2.8.0 、CHANGELOGPorting Guide を中心に、気になった点と関連URLをまとめました。

基本的には便利になりますが、非推奨として残しておいたものの削除や、paramiko の非同梱化など、ちょっとした注意点もありました。

[Ansible] RESTCONF モジュールで Cisco IOS のインターフェース情報を取得してみる

■ はじめに

Ansible 2.8 では、RESTCONF でネットワーク機器の情報を取得したり、設定を変更したりできる RESTCONF モジュールが導入されます。(本記事執筆時現在 RC段階)

この記事では restconf_get モジュールを利用して、IOS-XE へ RESTCONF でアクセスしてインターフェース情報の取得を試してみます。(後述しますが、そのままではうまくいかなかったので、暫定対処として一部コードの修正をして試しました)


■ 環境

  • Cisco IOS-XE (16.8)
    • Cisco DevNet SandBox
      • NETCONF-YANG and RESTCONF Always-On
      • netconf-yangrestconf コマンド有効
  • Ansible 2.8.0rc1
    • 本記事執筆時現在 RC段階のため、pip install ansible==2.8.0rc1 でインストール

■ 準備

Playook 実行に必要なファイルや Playbook を作成していきます。

インベントリファイル

ホスト情報を示すインベントリファイルを作成します。

  • inventory
[ios]
iosao1 ansible_host=ios-xe-mgmt.cisco.com

変数定義ファイル

インベントリファイルで定義したグループ ios が利用する変数を定義するファイルを作成します。

  • group_vars/ios.yml
ansible_connection: httpapi
ansible_httpapi_port: 9443
ansible_network_os: restconf
ansible_user: root
ansible_password: p@ss9999
ansible_httpapi_use_ssl: yes
ansible_httpapi_validate_certs: no

変数の説明

変数が多数登場しますのでそれぞれ説明します。

  • ansible_connection
  • ansible_httpapi_port
    • 利用するポートを指定します。SSH 接続では ansible_portansible_ssh_port 変数でポート番号を指定しますが、ansible_httpapi_port であることにご注意ください。
    • デフォルトは、変数 ansible_httpapi_use_ssl の値によって変わります。yes の場合は 443no の場合は 80 です。
    • ここでは、環境の都合により 9443 を指定しています。
  • ansible_network_os
    • ネットワークOSを指定します。
    • ios_configjunos_config モジュールなどのベンダー個別モジュールを利用する場合はこの変数は iosjunos といった値を指定しますが、RESTCONF モジュールを利用する場合は、このように restconf を利用します。こうすることで、restconf という httpapi プラグインが利用されます。
    • もし、例えば ios を指定した場合は unable to load API plugin for network_os ios というエラーが表示されます。
  • ansible_user
    • ユーザー名を指定します。
  • ansible_password
    • パスワードを指定します。ここではダミーの値を記載しています。必要に応じて ansible-vault で暗号化します。
  • ansible_httpapi_use_ssl
  • ansible_httpapi_validate_certs
    • SSL/TLS 接続する場合に証明書をかどうかを指定します。デフォルトは yes です。
    • ここでは、環境の都合により no を指定しています。

Playbook

処理内容を記載する Playbook を作成します。

  • restconf.yml
- hosts: ios
  gather_facts: no

  tasks:
    - name: restconf test
      restconf_get:
        path: /data/ietf-interfaces:interfaces
      register: result

    - name: debug result
      debug:
        msg: "{{ result }}"

path は Cisco DevNet Learning Labs の「Exploring IOS XE YANG Data Models with RESTCONF」や、こちらのサンプルに出てきたものを利用します。

restconf モジュールでは、root_path としてデフォルトで /restconf が定義されているため、実際には、/restconf 以降を path に指定します。


■ 実行(失敗)

それでは、Playbook を実行します。が、エラーになってしまいます。

$ ansible-playbook -i inventory restconf.yml

(...略...)
fatal: [iosao1]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "code": 406, "msg": "HTTP Error 406: Not Acceptable"}
(...略...)

HTTP Error 406: Not Acceptable とのことなので、HTTP の Acceppt フィールドまわりを調査しました。

原因調査と暫定対処

Ansible ではなく Postman で同様の GET を試すと以下の結果になりました。

  • Accept: application/yang-data+json では正常に json で情報が取得できた
  • Accept: では 406: Not Acceptable になった
  • Accept フィールド自体を指定しない場合は、XML で情報が取得できた

また、lib/ansible/module_utils/network/restconf/restconf.py を見ると、以下のようになっていました。

    accept = None
    if output == 'xml':
        accept = 'application/yang.data+xml'

    connection = Connection(module._socket_path)
    return connection.send_request(None, path=path, method='GET', accept=accept)

どうやら、Accept フィールドが空になってしまっていたようです。

暫定対処として、

    accept = None

の箇所を

    accept = 'application/yang-data+json'

に修正しました。


■ 再実行(成功)

暫定対処したところで、再度同じ Playbook を実行します。

$ ansible-playbook -i inventory restconf.yml 

PLAY [ios] ***********************************************************************************************************************

TASK [restconf test] *************************************************************************************************************
 [WARNING]: Platform darwin on host iosao1 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.8/reference_appendices/interpreter_discovery.html for more information.

ok: [iosao1]

TASK [debug result] **************************************************************************************************************
ok: [iosao1] => {
    "msg": {
        "ansible_facts": {
            "discovered_interpreter_python": "/usr/bin/python"
        }, 
        "changed": false, 
        "failed": false, 
        "response": {
            "ietf-interfaces:interfaces": {
                "interface": [
                    {
                        "description": "DON'T TOUCH ME", 
                        "enabled": true, 
                        "ietf-ip:ipv4": {
                            "address": [
                                {
                                    "ip": "10.10.20.48", 
                                    "netmask": "255.255.255.0"
                                }
                            ]
                        }, 
                        "ietf-ip:ipv6": {}, 
                        "name": "GigabitEthernet1", 
                        "type": "iana-if-type:ethernetCsmacd"
                    }, 
                    {
                        "enabled": true, 
                        "ietf-ip:ipv4": {}, 
                        "ietf-ip:ipv6": {}, 
                        "name": "GigabitEthernet2", 
                        "type": "iana-if-type:ethernetCsmacd"
                    }, 
                    {
                        "enabled": false, 
                        "ietf-ip:ipv4": {}, 
                        "ietf-ip:ipv6": {}, 
                        "name": "GigabitEthernet3", 
                        "type": "iana-if-type:ethernetCsmacd"
                    }
                ]
            }
        }, 
        "warnings": [
            "Platform darwin on host iosao1 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.8/reference_appendices/interpreter_discovery.html for more information."
        ]
    }
}

PLAY RECAP ***********************************************************************************************************************
iosao1                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

こんどは正常にインターフェース情報を取得できました。

※ちらっと表示されている Python interpreter についての WARNING の詳細は こちらをご参照ください。


■ まとめ

Ansible 2.8 で導入される restconf_get モジュールで、Cisco IOS-XE のインターフェース情報を取得してみました。 (一部コード修正が必要だった点は、他の対応方法があるのかなどの点は現時点では不明です。)

RESTCONF が有効であれば、他のベンダーの機器にも使える雰囲気がします。ベンダーごとにモジュールを使い分けなくて良い点は便利そうだと感じました。

また、Cisco IOS-XE では、RESTCONF が使えるようになってきているようなので、今後 RESTCONF は自動化の手段の選択肢になり得るのではないかと思います。

[2019/05/27 追記] 少しに気なる issue を見つけました。

github.com

[Batfish] JANOG43.5 で「ネットワークコンフィグ分析ツール Batfish との付き合い方」という発表をしてきました

■ はじめに

2019/04/26 に開催された JANOG43.5 Interim Meeting で「ネットワークコンフィグ分析ツール Batfish との付き合い方」という発表をさせていただきました。

janog.connpass.com

togetter.com

Batfish は、ネットワーク機器のコンフィグのさまざまな分析、検証ができるオープンソースのツールです。たとえば、経路やACL、NTP設定などの妥当性を確認できます。 コンフィグファイルを読み込んで処理するため、実機に接続する必要はありません。本発表では Batfish の概要と、ツール調査の中で見えてきた使いどころなど、Batfish との付き合い方をお伝えします。

JANOG と Batfish という点では、JANOG 43 で「Batfishというconfigテストツールの可能性」という発表がありました。今回私からは、少し違う視点でお話させていただきました。


■ 発表内容

前半で、Batfish はネットワーク機器のコンフィグの さまざまな分析、検証ができるツールであることをお伝えしました。検証のサンプルとして、ルーターのスタティックルートを削除する前後で、どのような到達性差分がでるかを検出数する例を取り上げました。

https://image.slidesharecdn.com/20190426janog43-190426053145/95/batfish-11-638.jpg?cb=1556284514

後半では、学習の仕方、バグと思った時の調べ方、使い所をお伝えしました。 使い所としては「特定の機能を、事前に、網羅的に」検証するという3つの観点でご紹介しました。

こちらのブログの内容からもヒントをいただきました。 www.intentionet.com

資料

発表に使用した資料はこちらです。

www.slideshare.net

togetter は 2019-04-26 15:18:06 から(ツイートありがとうございます!) togetter.com

動画

アーカイブ動画はこちら(1ヶ月程度の公開予定)です。私の発表は 20:15 頃からです。

www.youtube.com

いただいたフィードバック

発表直後の質疑応答の際に、以下のコメントをいただきました。(ありがとうございます!)

L2のコンフィグは試したことがなかったのでありがいコメントでした。

確かに、デフォルトだと各ノードのコンフィグのIFのL3情報をもとにして暗黙的な接続をしてトポロジを作るので、L2が入ると確かにどうなるんだろう、という思いがありました。 試せていませんが、layer1_topology.json という定義で明示的にトポロジを定義できるかも知れません。

tiwtter での反応 (ありがとうございます!)


■ 他の発表

他の方の発表も興味深いものばかりでした。

「RESTで休めない話!」にあった、自動化のユーザーインターフェースとして Google フォームを使っていて、GAS などでさまざまなことをキックする仕組みが印象てきでした。


JANOG 44は神戸

次回 JANOG 44 は、2019/07/24-2 に神戸で開催されます。次回も何かしらのかたちで参加する予定です。

https://www.janog.gr.jp/meeting/janog44/


参考: 私と JANOG

[Batfish] question で利用するノードやインターフェースなどの指定方法

question とは

ネットワークコンフィギュレーション分析ツール「Batfish」の Python ライブラリである pybatfishでは、question という形で、コンフィグに対してさまざまな検証を行います。question は Available questions というページにまとめられています。

公式チュートリアルJupyter Notebookを見ていくと、たとえば以下のような指定があります。

ert = bfq.traceroute(startLocation="as3core1[Loopback0]", headers=headers).answer().frame()

startLocation の指定は、雰囲気では、ノード as3core1 の インターフェース Loopback0 であろう、ということが読み取れますが、実際にどのような指定ができるのかは分かりません。 pybatfish のドキュメント(上記例の場合は、traceroute)を見ても、詳細は記載されていません。

Grammar for rich parameter types

これらの情報は、以下のページにまとめられています。

batfish/Parameters.md at master · batfish/batfish · GitHub

前述の例の startLocation の場合、Location Specifierを見ると、どのような指定ができるのかを確認できます。

参考

tekunabe.hatenablog.jp