LoginSignup
43

More than 5 years have passed since last update.

【Ansible】AnsibleでCisco機器を制御してみる(サンプルコード1 config収集編)

Last updated at Posted at 2016-04-14

1. はじめに

前回と同じです。
こんなこととかそんなこと
というわけで、Ansibleのcoreのnetwork moduleが充実したみたいです。
# 取り上げるの遅いですよね…

http://docs.ansible.com/ansible/list_of_network_modules.html
Ios(Cisco), Eos(Arista), Junos(Juniper), はてはopen switchまで。

数千台のswitchを前に、expectかteraterm macroでウニウニやっていた
ぼくらには朗報、此れは使はずばいらいでかということで使ってみました。
使ったのは

  • ios_command.py
  • ios_config.py

の各モジュールです。

動作環境などは2016年3月時点の状況です。

2. 実行環境

items version notes
mac OSX 10.10.x 母艦OS
Oracle Virtualbox 5.0.16 r105871 HV用途
CentOS 7.2 Ansible machine
Ansible 2.0.1.0 ここからげっと
Catalyst 3560E IOS12.2 弄れるのがこれしかなかた

構成

下記留意点のため、CentOS7上でAnsibleを動かしました。

3. 留意点

  • RedHat印のAnsibleでのみ動作可
    • mac OSXのbrew installで入るversionにはNW関連のupdateが含まれない(version 1.9.4)
    • yum installで入れるAnsibleにも同じくupdateが含まれない
      • ※2016年6月現在は含まれる
    • githubにはあるのでcloneしても可

4. Config収集するサンプルコード

inventory_file
[cisco]
192.168.199.2
192.168.199.3

[cisco:vars]
ansible_ssh_user=operator
ansible_ssh_pass=operators_password
enable_pass=enable
playbook_config_crawl.yml
---

- hosts: all
  gather_facts: no

  tasks:
   - name: crawl config file
     local_action:
       module: ios_command
       authorize: yes
       auth_pass: "{{ enable_pass }}"
       username: "{{ ansible_ssh_user }}"
       password: "{{ ansible_ssh_pass }}"
       host: "{{ inventory_hostname }}"
       commands:
         - show run
     register: result

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

   - name: parse config
     local_action: shell cat {{ inventory_hostname }}.log | sed -e 's/        \"//g' | sed -e 's/",//g' | sed -e "1,2d" | sed -e '$d' | sed -e '$d' > {{ inventory_hostname }}.conf

   - name: remove logfile
     local_action: file path=./{{ inventory_hostname }}.log state=absent

5. playbook解説

  1. 基本的な組み立て
    手でやるなら以下です。

    $ enable
    Password:
    # show run
    

    terminalのloggingをオンにして、
    特権モードに移行して(term len 0とか要るかもしれんが)sh run叩いて
    configをfileに吐く、というやつです。
      

  2. crawl config file タスク
    local_action module内で、cisco moduleを呼びます。
    中身は以下の通り。

    playbook_detail
      local_action:
       module: ios_command                //使いたいモジュールを宣言
       authorize: yes                     //特権モードに移行する
       auth_pass: "{{ enable_pass }}"     //特権モードのパスワード
       username: "{{ ansible_ssh_user }}" //初回ログイン時ユーザ
       password: "{{ ansible_ssh_pass }}" //初回ログイン時ユーザのパスワード
       host: "{{ inventory_hostname }}"   //ループ用(複数台やっても大丈夫)
       commands:                          //ここから実際の発行コマンド
         - show run                       //config表示
     register: result                     //resultに表示結果を格納
    

    ちなみに、「configじゃなくてsh intとsh ip routeを採取したいんだよね!」
    などという2つのタスクを吐きたい欲張りさん向けには、
    同僚の書いているこの記事のノウハウがオススメです。
      

  3. log write out タスク
    ansible実行マシンに中間fileを吐いています。
    conf.j2の中身は以下のようになっています。

    conf.j2
    {{ result.stdout_lines | to_nice_json }}
    

    前のタスクでresultに格納した内容をjson形式で表示し
    ホストのIPアドレス.logというファイルに書き出しています。
      

  4. parse config タスク
    json形式でfile生成したので、sedで無理矢理整形してリダイレクトしています。
    全然エレガントじゃないです。

    • jsonに入っている複数の半角スペースを消す
    • jsonに入っている「",」文字列を消す
    • 1行目2行目を消す
    • 最終行の閉じ括弧を2回消す

  
5. remove logfile タスク
  中間ファイルの~.logを消してます。

6. コツ

local_action module内でnetwork moduleを使う、ということがコツだと思います。

Ansibleは、超シンプルにいうと
管理対象(操作対象といったほうが分かりが良いかもしれないが)のホストに対して
ssh接続して内部のpythonを操作してお仕事をするヒトです。

大半のNW機器にはpythonなんて入っていないので、
普通にAnsibleのplaybookを書くと上記の動きに当てはまらないことを想定すると、
local_actionで機器用のcommandを送りつける構図が思いつくと思います。

7. さらにつづく

肝心の実行方法を書き忘れていましたが、
サンプルコード一式を同じフォルダに入れて、以下です。

ansible-playbook -i inventory_file playbook_config_crawl.yml

このサンプルコードをうまく使えば、複数台からのconfig採取が
コマンド1行で可能になります。

次は機器の設定変更をAnsibleからやるべく、ポートの設定変更のサンプルを示したいと思います。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
43