【juniper.junosでNW工事手順自動化】
---juniper.junosを使ってNW工事を自動化---
Junosの設定は、Ansibleの公式ページのJuniperモジュールを利用する方法と、ansible-galaxyでJuniper Networksが提供しているjuniper.junos
のroles
を使う方法がある。
juniper.junos
のrole
を使えばyamlの構文を知らなくてもplaybookをほぼコピぺだけで簡単に作成できる。
juniper.junosでできること
- OSのインストールとアップグレード
- Junosのプロビジョニング
- 変更configのロード、情報の取得、管理対象デバイスのリセット、再起動、シャットダウンなど等
前回netconfを有効化時は、Ansible公式サイトのJuniperモジュールを使ってみたが、工事に必要な機能のほとんどが実装できなかった。
これだとyamlの知識がない、Ansibleのモジュール機能の知識もない、調べる時間もないという場合はハードルが高い。
今回はjuniper.junos
のrole
を使って、知識が無くても簡単に実装できることを確認する。
<<確認内容>>
- configの投入冪等性を担保できること。
- 排他的に設定できること。
- 自装置宛ての通信フィルタがが正しい順序で投入されること。
- 自装置宛てのフィルタ許可通信の疎通確認ができること。
- ログ出力設定が確認できること。
- configの保存とバックアップができること、差分確認できること
- rollbackで切戻しできること。
<<結果>>
- 設定モードかオペレーションモードのどちらでコマンドが実行されるかはモジュールにより決まっている。
juniper_junos_config
は設定を実行するモジュールでデフォルトでcommitまで実施する。juniper_junos_commands
はshow系の確認をする。
- 冪等性について。mergeでset形式のconfigをlistで指定したところ、set、insert、deactivate は設定後は何度設定してもそのままとなるが、deleteやrenameは初回実行で設定が消えた後は状態で再実行するとエラーになる。
- 排他制御について。
config_mode
でexclusive
を指定できるので、もし他で設定中のconfigがある場合はcommitせず、以下のエラーが出てfailed
終了する。
- 通信フィルタがが正しい順序かどうかは設定階層単位で比較する必要がある。自発通信と自側サービスポートの疎通確認はできる。結果NGなら
failed
となる。state
などオプションが無いように見えるのでそれ以外のハンドリングはできない。 - ログ出力設定、ほか、show系のコマンド出力結果を
when
やwait_for
で判断させたい。やり方は調査中。 - configの保存とバックアップは問題なくできる。
committed
とcandidate
のconfigをフルまたは、階層単位で取得することができる。 - rollbackで切戻しはできる。
- (補足)lineで記載しているCLIのコマンドは
netconf
ではRPC処理のためパイプでコマンドをつないだ形式では処理できない。(例) > show configuration | display set 等。
<<思ったこと>>
- ciscoと異なりcommit単位で設定前後のconfigを確認するので分かりやすい。状態確認については、サンプルがなく、show系コマンドの出力結果で変更前、変更後の状態を判断してハンドリングする方法をあれば実装する予定、調査中。
- 冪等性を担保するなら
juniper_junos_config
でsetコマンドをlineで入れるのではなく、configファイル単位または設定階層単位(system、interface、snmpなどの階層)でload replace するのがよさそう。
<<通信フィルタ追加工事手順>>
以下のエクセルの工事手順をAnsibleで自動化する
大項目 | 項番 | 項目 | 対象機器 | 設定/確認コマンド/出力確認 | |
---|---|---|---|---|---|
事前確認 | 1_1 | 設定モードuser確認 | SW | user@SW> show system users fpc0: -------------------------------------------------------------------------- 1:26PM up 185 days, 18:37, 2 users, load averages: 0.00, 0.03, 0.03 USER TTY FROM LOGIN@ IDLE WHAT |
NW機器で設定モードのユーザがいないこと |
1_2 | WEBアクセス有効化設定 無し確認 |
SW | user@SW> show configuration system services ftp; telnet; ssh; |
web-managementの出力がないこと | |
1_3 | lo向けアクセスフィルタ 設定前確認 |
SW | user@SW>show configuration firewall family inet filter JUNIPER_Lo term TELNET { from { source-address { 192.168.1.0/24; } destination-address { 10.10.10.1/32; } destination-port 23; } then accept; } |
WEBアクセス 許可フィルタ設定が無いこと |
|
設定 | 2_1 | 排他制御して設定モード移行 | SW | user@SW> configure exclusive Entering configuration mode {master:0} user@SW# |
エラーがないこと。設定モードに移行することを以下のプロンプト出力で確認 # |
2_2 | web-managemen 有効化 |
SW | set system services web-management http port 8888 | プロンプト表示のみ確認 | |
2_3 | lo向けアクセスフィルタ 設定階層へ移動 |
SW | user@SW# edit firewall family inet filter JUNIPER_Lo {master:0}[edit firewall family inet filter JUNIPER_Lo] user@SW# |
階層移動後プロンプト表示確認 | |
2_4 | lo向けアクセスフィルタ web-managemen ICMP 許可 |
SW | user@SW# ここに以下設定を貼り付け set firewall family inet filter JUN_Lo term ICMP from protocol icmp set firewall family inet filter JUN_Lo term ICMP then accept insert firewall family inet filter JUN_Lo term ICMP before term ALL_discard set firewall family inet filter JUN_Lo term WEB_MANAGE from destination-port 8888 set firewall family inet filter JUN_Lo term WEB_MANAGE then accept insert firewall family inet filter JUN_Lo term WEB_MANAGE before term ALL_discard |
階層移動後プロンプト表示に戻ること エラーがないこと |
|
事後確認 | 3_1 | 設定差分確認 | SW | user@SW# show | compare [edit firewall family inet filter JUN_Lo term ICMP] + from { + protocol icmp; + } [edit firewall family inet filter JUN_Lo] term ICMP { ... } + term WEB_MANAGE { + from { + destination-port 8888; + } + then accept; ---snip--- |
差分表示が正しいこと |
3_2 | 設定config構文確認 | SW | user@SW# commit check configuration check succeeds |
configuration check succeeds 表示確認 |
|
3_3 | commit | SW | user@SW# commit configuration check succeeds commit complete |
commit complete 表示確認 |
|
3_4 | web-managemen設定 config確認 |
SW | user@SW> show configuration system services ftp; ---snip--- web-management { http { port 8888; } } |
web-management の設定出力があること | |
3_5 | lo向けアクセスフィルタ確認 | SW | user@SW>show configuration firewall family inet filter JUN_Lo term ICMP { from { protocol icmp; } then accept; } term WEB_MANAGE { from { destination-port 8888; } then accept; ---snip--- |
許可フィルタ設定があること | |
3_6 | web-management ポート開放確認 |
SW | user@SW>show system connections ---snip--- tcp4 0 0 *.8888 *.* LISTEN |
8888コネクションがlitsen又はestablisであること | |
3_7 | ping疎通確認 | SW | user@SW> ping 192.168.3.218 PING 192.168.3.218 (192.168.3.218): 56 data bytes 64 bytes from 192.168.3.218: icmp_seq=0 ttl=64 time=1.921 ms 64 bytes from 192.168.3.218: icmp_seq=1 ttl=64 time=2.751 ms |
ping疎通可能なこと |
※本手順書は実工事とは関係なく、パラメータはすべてサンプルです。
<<playbook>>
/etc/ansible/Jjunos_command.yml
- hosts: junos gather_facts: no roles: - Juniper.junos tasks: - name: getting log but don't display out juniper_junos_command: commands: - "show version" - "show interfaces terse" - "show system uptime" - "show chassis alarms" - "show chassis environment" formats: - "text" dest_dir: "./{{ inventory_hostname }}before_log/" return_output: false # - name: Execute single "show version" command. # juniper_junos_command: # commands: "show version" # register: response # # - name: Print the sh ver command output # debug: # var: response.stdout - name: commit config juniper_junos_config: check: true diff: true commit: true config_mode: 'exclusive' load: 'merge' comment: 'merge from a config' lines: - 'set system services web-management http port 8888' - 'set firewall family inet filter JUN_Lo term ICMP from protocol icmp' - 'set firewall family inet filter JUN_Lo term ICMP then accept ' - 'insert firewall family inet filter JUN_Lo term ICMP before term ALL_discard' - 'set firewall family inet filter JUN_Lo term WEB_MANAGE from destination-port 8888' - 'set firewall family inet filter JUN_Lo term WEB_MANAGE then accept ' - 'insert firewall family inet filter JUN_Lo term WEB_MANAGE before term ALL_discard' # - 'rename firewall family inet filter JUN_Lo term SSH to term SSH2' register: resp_commit - name: Print the complete response debug: var: resp_commit - name: Ping to AnsibleController juniper_junos_ping: dest: "192.168.3.218" source: "192.168.3.39" register: response - name: Print the packet_loss debug: var: response.packet_loss - name: Checking WEB_MANAGE local connectivity wait_for: host={{ inventory_hostname }} port=8888 timeout=5 register: response - name: Checking DNS remort connectivity wait_for: host=8.8.8.8 port=53 timeout=5 register: response - name: Print the connectivity debug: var: response
<<inventory>>
/etc/ansible/inventory/junos
[junos] SW ansible_host=192.168.3.39 [junos:vars] ansible_ssh_user=hoge ansible_ssh_pass=1234 ansible_network_os=junos ansible_connection=netconf #ansible_connection=local #ansible_connection=network_cli
<<実行結果>>
[root@hoge ansible]# ansible-playbook -i inventory/junos Jjunos_command.yml PLAY [junos] *********************************************************************************************************************************************************************************** TASK [getting log but don't display out] ******************************************************************************************************************************************************* ok: [SW104] TASK [commit config] *************************************************************************************************************************************************************************** changed: [SW104] TASK [Print the complete response] ************************************************************************************************************************************************************* ok: [SW] => resp_commit: changed: true diff: |2- [edit system services] + web-management { + http { + port 8888; + } + } [edit firewall family inet filter JUN_Lo] term FTP { ... } + term ICMP { + from { + protocol icmp; + } + then accept; + } + term WEB_MANAGE { + from { + destination-port 8888; + } + then accept; + } term ALL_discard { ... } diff_lines: - '' - '[edit system services]' - + web-management { - + http { - + port 8888; - + } - + } - '[edit firewall family inet filter JUN_Lo]' - ' term FTP { ... }' - + term ICMP { - + from { - + protocol icmp; - + } - + then accept; - + } - + term WEB_MANAGE { - + from { - + destination-port 8888; - + } - + then accept; - + } - ' term ALL_discard { ... }' failed: false msg: 'Configuration has been: opened, loaded, checked, diffed, committed, closed.' TASK [Ping to AnsibleController] *************************************************************************************************************************************************************** ok: [SW] TASK [Print the packet_loss] ******************************************************************************************************************************************************************* ok: [SW] => response.packet_loss: '0' TASK [Checking WEB_MANAGE local connectivity] ************************************************************************************************************************************************** ok: [SW] TASK [Checking DNS remort connectivity] ******************************************************************************************************************************************************** ok: [SW] TASK [Print the connectivity] ****************************************************************************************************************************************************************** ok: [SW] => response: changed: false elapsed: 0 failed: false path: null port: 53 search_regex: null state: started PLAY RECAP ************************************************************************************************************************************************************************************* SW : ok=8 changed=1 unreachable=0 failed=0
<<実行時 出力logファイル>>
今回は設定前でのみ取得
[root@hoge SWbefore_log]# pwd /etc/ansible/SWbefore_log [root@hoge SWbefore_log]# ls -altr 合計 92 -rw-r--r-- 1 root root 523 5月 12 11:31 SW_show_version.text -rw-r--r-- 1 root root 4022 5月 12 11:31 SW_show_interfaces_terse.text -rw-r--r-- 1 root root 375 5月 12 11:31 SW_show_system_uptime.text -rw-r--r-- 1 root root 185 5月 12 11:31 SW_show_chassis_alarms.text -rw-r--r-- 1 root root 831 5月 12 11:31 SW_show_chassis_environment.text
実行ログは/etc/ansible/ansible.cfgで以下に指定
log_path=/etc/ansible/route_test/route.log