Ansibleを使ってネットワーク機器を制御してみる

ネットワークの運用管理は自動化が進まないという話が話題になっていますね。

なぜネットワーク運用自動化が進まないのか Why is it difficult to automate network opera…

構成管理ツールはかなり整備されてきていて、代表的なところだとChefやPuppet、そしてAnsibleあたりでしょうか。

今回はAnsibleを使ってネットワーク機器の構成管理を試してみます。

Ansibleとは

Ansibleとは、ソフトウェアのインストールや設定、サービスの起動/停止といった操作を事前にスクリプト化して、そのスクリプトを複数のマシンに一括で投入出来るツールです。

Ansibleに関する解説はこちらのサイトが分かりやすいです。

エージェントレスでシンプルな構成管理ツール「Ansible」入門 – さくらのナレッジ

検証環境準備

実環境を準備するのが面倒くさかったので、今回はCisco onePKを試したときに使ったAll-in-one VMの環境を使います。

All-in-one VMについては、以下のリンクで説明していますので今回は割愛。

今回は、SSH接続を使ってAnsibleで制御する場合と、SNMPを使ってAnsibleで制御する場合の2パターンを試してみます。

Ansibleのインストール

まずは、以下のコマンドでAnsibleをインストールします。

sudo apt-get install python-pip  
sudo apt-get install sshpass  
sudo pip install ansible

SSH接続を使ってAnsibleで制御

CiscoルータにSSH接続用の設定追加

AnsibleからSSH接続する必要があるため、CiscoルータにSSHのローカル認証設定を行います。

Router1#conf t  
Router1(config)#line vty 0 4  
Router1(config-line)#login local  
Router1(config-line)#end  
Router1#

Ansible用のhostsファイル作成

Ansibleからアクセスするhostsファイルを作成します。今回は3台のCiscoルータにアクセスするので、3台分のIPアドレスを記載します。

cisco@onepk:~/ansible$ vi hosts  
[cisco]  
10.10.10.110  
10.10.10.120  
10.10.10.130

Ansibleのplaybookファイルの設定

今回は各ルータのshow runを取得するスクリプトを書いてみます。

cisco@onepk:~/ansible$ vi show-run.yml  
---  
- hosts: cisco  
  gather_facts: no  
  sudo: false

  tasks:  
  - name: sh run  
    raw : "show run"  
    register: show_run  
  - name: sh run output  
    local_action: shell /bin/echo "{{ show_run.stdout }}" > /home/cisco/ansible/sh_run_{{ inventory_hostname }}.txt

注意点として、gather_facts は no にすることと、実行するコマンドは raw を使って記述します。

Ansibleの実行

cisco@onepk:~/ansible$ ansible-playbook -i hosts show-run.yml -k  
SSH password: cisco

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

TASK: [sh run] ****************************************************************  
ok: [10.10.10.110]  
ok: [10.10.10.130]  
ok: [10.10.10.120]

TASK: [sh run output] *********************************************************  
changed: [10.10.10.130 -> 127.0.0.1]  
changed: [10.10.10.110 -> 127.0.0.1]  
changed: [10.10.10.120 -> 127.0.0.1]

PLAY RECAP ********************************************************************  
10.10.10.110               : ok=2    changed=1    unreachable=0    failed=0  
10.10.10.120               : ok=2    changed=1    unreachable=0    failed=0  
10.10.10.130               : ok=2    changed=1    unreachable=0    failed=0   

無事にファイルに保存されているのを確認します。

cisco@onepk:~/ansible$ ll  
drwxrwxr-x  6 cisco cisco 4096 May 16 07:35 ./  
drwxr-xr-x 40 cisco cisco 4096 May 16 06:44 ../  
-rw-rw-r--  1 cisco cisco   47 May 16 07:34 hosts  
-rw-rw-r--  1 cisco cisco  263 May 16 07:33 show-run.yml  
-rw-rw-r--  1 cisco cisco 9978 May 16 07:34 sh_run_10.10.10.110.txt  
-rw-rw-r--  1 cisco cisco 9935 May 16 07:34 sh_run_10.10.10.120.txt  
-rw-rw-r--  1 cisco cisco 9935 May 16 07:34 sh_run_10.10.10.130.txt

SNMPを使ってAnsibleで制御

続いて、SNMPモジュールを使ってCiscoルータの設定を変更してみます。

ansible-cisco-snmpというモジュールがGitHubに上がっていましたので、それを使ってみます。

必要なモジュール類をインストール

sudo pip install nelsnmp  
sudo apt-get install git  
git clone https://github.com/networklore/ansible-cisco-snmp.git  
cd ansible-cisco-snmp

Ansibleの設定ファイルにライブラリを設定

sudo mkdir -p /etc/ansible  
sudo vi /etc/ansible/ansible.cfg  
[defaults]

library = /home/patrick/ansible-cisco-snmp/library

CiscoルータにSNMPの設定を行う

GitHubに記載されているとおり、SNMPを設定する。今回はローカルでの検証なので、ACLは省略。

snmp-server community private rw  
snmp-server view V3ISO iso included  
snmp-server group ANSIBLEGRP v3 priv write V3ISO  
snmp-server user ansible ANSIBLEGRP v3 auth sha AuthPassword123 priv aes 128 PrivPassword123 access

GitHubにはサンプルのplaybookファイルがあるので試してみます。

設定の保存

「examples-save_config.yml」というファイルは、各機器の設定を保存するplaybookファイルですので実行してみます。

実行結果

cisco@onepk:~/ansible$ ansible-playbook -i hosts ansible-cisco-snmp/example-playbooks/how-to/examples-save_config.yml -k  
SSH password: 

PLAY [all] ******************************************************************** 

TASK: [Save the running configuration to startup] *****************************  
changed: [10.10.10.110]  
changed: [10.10.10.130]  
changed: [10.10.10.120]

PLAY RECAP ********************************************************************  
10.10.10.110               : ok=1    changed=1    unreachable=0    failed=0  
10.10.10.120               : ok=1    changed=1    unreachable=0    failed=0  
10.10.10.130               : ok=1    changed=1    unreachable=0    failed=0   

CDPの設定変更

「examples-cdp.yml」はCDP設定をグローバルで有効にして、インタフェースで無効にする設定ファイルです。
まず、サンプルファイルのインタフェースが「Fast Ethernet」だったので「Gigabit Ethernet」に変更します。

cisco@onepk:~/ansible$ vi ansible-cisco-snmp/example-playbooks/how-to/examples-cdp.yml 

---  
-  hosts: all  
   connection: local  
   gather_facts: no

   tasks:  
     - name: Globally enable CDP  
       cisco_snmp_cdp:  
         host={{ inventory_hostname }}  
         version=2c  
         community=private  
         cdp_global=enabled

     - name: Disable CDP on gigabitethernet 0/0  
       cisco_snmp_cdp:  
         host={{ inventory_hostname }}  
         version=2c  
         community=private  
         cdp_interface=disabled  
         interface_name="GigabitEthernet0/0"

実行結果

cisco@onepk:~/ansible$ ansible-playbook -i hosts ansible-cisco-snmp/example-playbooks/how-to/examples-cdp.yml -k  
SSH password: 

PLAY [all] ******************************************************************** 

TASK: [Globally enable CDP] ***************************************************  
ok: [10.10.10.120]  
ok: [10.10.10.110]  
ok: [10.10.10.130]

TASK: [Disable CDP on gigabitethernet 0/0] ************************************  
ok: [10.10.10.110]  
ok: [10.10.10.130]  
ok: [10.10.10.120]

PLAY RECAP ********************************************************************  
10.10.10.110               : ok=2    changed=0    unreachable=0    failed=0  
10.10.10.120               : ok=2    changed=0    unreachable=0    failed=0  
10.10.10.130               : ok=2    changed=0    unreachable=0    failed=0 

設定を確認してみると、interface GigabitEthernet0/0だけ、「no cdp enable」が設定されています。

Router1#sh running-config  
〜省略〜  
interface GigabitEthernet0/0  
 ip address 10.10.20.110 255.255.255.0  
 duplex auto  
 speed auto  
 media-type rj45  
 no cdp enable  
!
interface GigabitEthernet0/1  
 ip address 10.10.30.110 255.255.255.0  
 duplex auto  
 speed auto  
 media-type rj45  
!

ちなみに、Router2とRouter3のSNMP設定を外してAnsibleを実行してみると以下のようなエラーが出力されます。

cisco@onepk:~/ansible$ ansible-playbook -i hosts ansible-cisco-snmp/example-playbooks/how-to/examples-cdp.yml -k  
SSH password: 

PLAY [all] ******************************************************************** 

TASK: [Globally enable CDP] ***************************************************  
ok: [10.10.10.110]  
failed: [10.10.10.120] => {"failed": true}  
msg: 'No SNMP response received before timeout'  
failed: [10.10.10.130] => {"failed": true}  
msg: 'No SNMP response received before timeout'

TASK: [Disable CDP on gigabitethernet 0/0] ************************************  
ok: [10.10.10.110]

PLAY RECAP ********************************************************************  
           to retry, use: --limit @/home/cisco/examples-cdp.retry

10.10.10.110               : ok=2    changed=0    unreachable=0    failed=0  
10.10.10.120               : ok=0    changed=0    unreachable=0    failed=1  
10.10.10.130               : ok=0    changed=0    unreachable=0    failed=1   

まとめ

以上、Ansibleを使ってCiscoルータの制御を試してみました。
設定変更となると、少しリスクはありますが、構成情報の取得であれば複数台のルータから一括で取得できるので、かなり使いやすいんじゃないでしょうか。

インストールも簡単ですし、playbookの記述も割と分かりやすいです。興味のある方はぜひ試してみて下さい。

コメントを残す

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

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

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください