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については、以下のリンクで説明していますので今回は割愛。
- cisco onePKを試してみました。 | ネットワークエンジニアを目指して – ブログ
- Cisco onePKを使って遊んでみました。 | ネットワークエンジニアを目指して – ブログ
- Cisco onePKで遊ぶ(実行編2) | ネットワークエンジニアを目指して – ブログ
今回は、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の記述も割と分かりやすいです。興味のある方はぜひ試してみて下さい。