Ansibleのnetwork moduleを使ってCisco IOS機器を制御する

ansible-thumbnail

複数台のCisco IOSルータから定期的にコマンドを取得する必要があったので、せっかくなのでAnsibleを使って制御してみました。

Ansibleは標準で多くのネットワーク機器をサポート

Ansible 2.0から多くのNetwork Moduleに対応しています。

Network Modules — Ansible Documentation

CiscoはもちろんJuniperやArista、F5などなど一般的なベンダーは一通りサポートしています。

数台の機器であれば、がんばって1台ずつ設定するのもアリですが、数十台、数百台の設定となるとこれはもう機械的にやった方が楽ですし間違いも起きないので、コードを書くことが苦手なインフラエンジニアも覚えておいて損はないと思います。

実行環境

  • mac OSX
    10.11.x
  • Ansible
    2.1.0.0

Ansibleのインストールはbrew installを使います。
まず、brew infoコマンドでパッケージのバージョン情報を確認します。

% brew info ansible  
ansible: stable 2.1.0.0 (bottled), HEAD

Ansibleのバージョンは1.xではなく、2.xを使いたいので、ここでもし1.xが表示された場合はHomebrewを更新します。

% brew update

再度brew infoコマンドでバージョンが更新されたことを確認して、Ansibleをインストールします。

% brew install ansible

インストールが完了したらバージョンを確認します。

% ansible --version  
ansible 2.1.0.0

Config収集用サンプルコード

hosts

[cisco]
10.0.0.1 name=cisco1

[cisco:vars]
enable_secret=cisco
user=itbook
password=cisco

[arista]
192.168.56.100 name=arista1

[arista:vars]
enable_secret=arista
user=itbook
password=arista

hostsには対象ノードのホストをグループごとに記載します。実行結果を保存するファイル名には機器のホスト名にしたいので、「name」変数を定義してホスト名を記載しています。また、併せてログインするための情報(ホスト名、パスワード)も変数varsとして記載します。

show_cmd.yml

---
- hosts: cisco
  gather_facts: no
  tasks:
   - name: cisco show command run
     local_action:
       module:   ios_command
       commands:
         - show run
         - show int des
         - show ip ro
         - show logg
         - show version
       host:     "{{ inventory_hostname }}"
       username: "{{ user }}"
       password: "{{ password }}"
       authorize: true
       auth_pass: "{{ enable_secret }}"
     register: result

     #- debug: msg="{{ result.stdout }}"

   - name: log write out
     local_action: template src=./cmd.j2 dest=./{{ name }}.log

- hosts: arista
  gather_facts: no
  tasks:
   - name: arista show command run
     local_action:
       module:   eos_command
       commands:
         - show run
         - show int des
         - show ip ro
         - show logg
         - show version
       host:     "{{ inventory_hostname }}"
       username: "{{ user }}"
       password: "{{ password }}"
       authorize: true
       auth_pass: "{{ enable_secret }}"
     register: result

   - name: log write out
     local_action: template src=./cmd.j2 dest=./{{ name }}.log

moduleでそれぞれのベンダーのモジュールを呼び出します。今回はciscoとAristaのshowコマンドを使用するため、ios_command/eos_commandを使いましたが、設定変更を行いたい場合は、xxx_configモジュールを使用します。他のベンダーの場合も同様にmodule変数でモジュールを呼び出します。

実際に実行したいコマンドは、commands内に列挙していきます。

ログの保存はtemplete機能を使って、外部ファイル(cmd.j2)経由で吐き出すようにしています。

cmd.j2

{% for id in range(0,4) %}
    {{ result.stdout[id] }}
{% endfor %}

実行結果は「result.stdout」に配列として保存されています。今回は5つのコマンドを実行しましたので配列の要素数0~4までを吐き出すようにしています。ただし、この方法は美しくないのでもっとシンプルに吐き出す方法をご存じの方はぜひ教えてください。

上記のコードはGithubにも上げていますので、興味があれば使ってみてください。

itbook/ansible_show-cmd

実行結果

 % ansible-playbook -i hosts show_cmd.yml

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

TASK [cisco show command run module] **************************************
ok: [10.0.0.1 -> localhost]

TASK [log write out] ***********************************************************
changed: [10.0.0.1 -> localhost]

PLAY [arista] ******************************************************************

TASK [arista show command run module] **************************************
ok: [192.168.56.100 -> localhost]

TASK [log write out] ***********************************************************
changed: [192.168.56.100 -> localhost]

PLAY RECAP *********************************************************************
10.0.0.1                   : ok=2    changed=1    unreachable=0    failed=0
192.168.56.100             : ok=2    changed=1    unreachable=0    failed=0

まとめ

前回はAnsibleのrowを使ってネットワーク機器を制御する記事を書きましたが、今回はnetwork moduleを使ってネットワーク機器を制御してみました。

showコマンド程度であれば、rowでもnetwork moduleでも変わらないですが、Ansibleを使って設定変更を行いたい場合は、network moduleを使った方が格段に効率が良くなります。次回はios_configモジュールを使った設定変更を試してみたいと思います。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)