1. はじめに
以下2つの機能を組み合わせて、Ansible実行時、Cisco IOS機器に対しどのような操作が行われているか、試した結果をメモしておきます。
- ターミナルサーバを利用すると、対象機器へSSH経由でコンソール接続可能
- コンソール接続の場合、他のコンソール接続ユーザの実行内容が画面表示される
2. 検証構成
Ansibleは2.10.0、NW機器はCisco 1812Jを使用しています。
3. Inventoryファイル
以下の通り作成しました。Ansible2.9以降でサポートされているAnsible Collectionの記法(FQCN)に従っています。
Connectionプラグインはnetwork_cli
を使用。ユーザ名/パスワードは通常のSSH接続と異なりターミナルサーバ側を指定しています。
[cisco]
Router ansible_host=192.168.100.33 ansible_port=3001
[cisco:vars]
ansible_connection=ansible.netcommon.network_cli
ansible_network_os=cisco.ios.ios
ansible_user=(ターミナルサーバのユーザ名)
ansible_password=(ターミナルサーバのパスワード)
ansible_become=yes
ansible_become_method=ansible.netcommon.enable
ansible_become_pass=(ルータのenableパスワード)
4. showコマンド取得(ios_commandモジュール)
4-1. Playbook
Routerに対し、show users
コマンドを2回実行してみます。
---
- hosts: cisco
gather_facts: no
tasks:
- name: run show command 1
cisco.ios.ios_command:
commands:
- show users
- name: run show command 2
cisco.ios.ios_command:
commands:
- show users
4-2. 実行結果(Ansible)
2つのタスクが問題なく完了しています。
$ ansible-playbook -i inventory_con.ini playbook_shuser.yml
PLAY [cisco] **********************************************************************************************************************************
TASK [run show command 1] *********************************************************************************************************************
ok: [Router]
TASK [run show command 2] *********************************************************************************************************************
ok: [Router]
PLAY RECAP ************************************************************************************************************************************
Router : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
4-3. 実行結果(NW機器)
タスクrun show command 1
実行時
- ログイン、
teminal lengh/width
コマンドで出力行/幅の制限を外す -
show version
コマンド実行 -
show users
コマンド実行
タスクrun show command 2
実行時
-
show version
コマンド実行 -
show users
コマンド実行
タスクrun show command 2
実行時は、Persistent Connections機能(SSH接続が一定時間保持され、タスク毎のログインが不要になる。デフォルトは30秒)により、1点目の処理が省略されていました。
******************************** [run show command 1 実行時] ********************************
Router>enable
Password:
Router#terminal length 0
Router#terminal width 512
Router#terminal width 0
Router#show version
(省略)
Router#show users
Line User Host(s) Idle Location
* 0 con 0 idle 00:00:00
Interface User Mode Idle Peer Address
******************************** [run show command 2 実行時] ********************************
Router#show version
(省略)
Router#show users
Line User Host(s) Idle Location
* 0 con 0 idle 00:00:00
Interface User Mode Idle Peer Address
ちなみにpause
モジュールで2つのタスクの実行間隔を開けたところ、1点目の処理が実行されました。
5. Facts取得(gather_facts、ios_factsモジュール)
5-1. Playbook
gather_facts
ディレクティブをyes
(デフォルト設定)に指定し、各種システム情報を事前に収集します。
後続のタスクで、ios_facts
モジュールも実行してみます。本Playbookのようにgather_subset
オプションを指定しない場合は、デフォルトで!config
が選択され、Configを除くハードウェア、インターフェース情報が取得されます。
参考:Ansible Documentation - cisco.ios.ios_facts
---
- hosts: cisco
gather_facts: yes
tasks:
- name: collect facts
cisco.ios.ios_facts:
# gather_subset:
# - all
# - min
# - hardware
# - config
# - interfaces
register: facts
- name: debug
debug:
msg: "{{ facts }}"
5-2. 実行結果(Ansible)
gather_facts
は、一つのタスクGathering Facts
として最初に実行されています。
その後タスクcollect facts
が実行され、結果がタスクdebug
で出力されています。
実行結果
$ ansible-playbook -i inventory_con.ini playbook_facts.yml
PLAY [cisco] **********************************************************************************************************************************
TASK [Gathering Facts] ************************************************************************************************************************
[WARNING]: Ignoring timeout(10) for cisco.ios.ios_facts
ok: [Router]
TASK [collect facts] **************************************************************************************************************************
ok: [Router]
TASK [debug] **********************************************************************************************************************************
ok: [Router] => {
"msg": {
"ansible_facts": {
"ansible_net_all_ipv4_addresses": [
"XX.XX.XX.XX",
"XX.XX.XX.XX"
],
"ansible_net_all_ipv6_addresses": [],
"ansible_net_api": "cliconf",
"ansible_net_filesystems": [
"flash:"
],
"ansible_net_filesystems_info": {
"flash:": {
"spacefree_kb": 12152.0,
"spacetotal_kb": 31192.0
}
},
"ansible_net_gather_network_resources": [],
"ansible_net_gather_subset": [
"hardware",
"interfaces",
"default"
],
"ansible_net_hostname": "Router",
"ansible_net_image": "flash:c181x-advipservicesk9-mz.XX.XX.bin",
"ansible_net_interfaces": {
"FastEthernet0": {
"bandwidth": 100000,
"description": "<< To Router >>",
"duplex": null,
"ipv4": [
{
"address": "10.1.1.1",
"subnet": "30"
}
],
"lineprotocol": "down",
"macaddress": "0022.55XX.XXXX",
"mediatype": null,
"mtu": 1500,
"operstatus": "up",
"type": "PQ3_TSEC"
},
(省略)
},
"ansible_net_iostype": "IOS",
"ansible_net_memfree_mb": 45478.98828125,
"ansible_net_memtotal_mb": 63340.53515625,
"ansible_net_model": "1812-J",
"ansible_net_neighbors": {},
"ansible_net_python_version": "3.6.8",
"ansible_net_serialnum": "FHKXXXXXXXX,",
"ansible_net_system": "ios",
"ansible_net_version": "XX.XX",
"ansible_network_resources": {}
},
"changed": false,
"failed": false
}
}
PLAY RECAP ************************************************************************************************************************************
Router : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
5-3. 実行結果(NW機器)
以下の通り、タスクGathering Facts
とタスクcollect facts
で同じshowコマンドが実行されました。
******************************** [Gathering Facts 実行時] ********************************
Router>enable
Password:
Router#terminal length 0
Router#terminal width 512
Router#terminal width 0
Router#show version
(省略)
Router#show version
(省略)
Router#dir
(省略)
Router#show memory statistics
(省略)
Router#show interfaces
(省略)
Router#show ip interface
(省略)
Router#show ipv6 interface
(省略)
Router#show lldp
(省略)
Router#show cdp
(省略)
Router#show cdp neighbors detail
(省略)
Router#show version
(省略)
******************************** [collect facts 実行時] ********************************
Router#show version
(省略)
Router#show version
(省略)
Router#dir
(省略)
Router#show memory statistics
(省略)
Router#show interfaces
(省略)
Router#show ip interface
(省略)
Router#show ipv6 interface
(省略)
Router#show lldp
(省略)
Router#show cdp
(省略)
Router#show cdp neighbors detail
(省略)
Router#show version
(省略)
ios_facts
モジュールのgather_subset
オプションを変えた結果も記載しておきます。
gather_subset | 取得コマンド |
---|---|
指定なし (!config) | show version, dir, show memory statistics, show interfaces, show ip interface, show ipv6 interface, show lldp, show cdp, show cdp neighbors detail |
all | 指定なし + show running-config |
min | show version |
hardware | show version, dir, show memory statistics |
config | show version, show running-config |
interfaces | show version, show interfaces, show ip interface, show ipv6 interface, show lldp, show cdp, show cdp neighbors detail |
6. NTPサーバ設定追加(ios_configモジュール)
6-1. Playbook
冪等性が担保されているか確認するため、NTPサーバ1.1.1.1
(設定済み)とNTPサーバ9.9.9.9
(未設定)を追加してみます。save_when
オプションで、設定変更後にwriteも行います。
---
- hosts: cisco
gather_facts: no
tasks:
- name: add ntp server
cisco.ios.ios_config:
lines:
- ntp server 1.1.1.1
- ntp server 9.9.9.9
match: line
save_when: modified
6-2. 実行結果(Ansible)
changed=1
となり、設定変更が行われました。
$ ansible-playbook -i inventory_con.ini playbook_ntp.yml
PLAY [cisco] **********************************************************************************************************************************
TASK [add ntp server] *************************************************************************************************************************
changed: [Router]
PLAY RECAP ************************************************************************************************************************************
Router : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
6-3. 実行結果(NW機器)
大まかな流れは以下の通りでした。
- 設定変更前のRunning Configを取得(おそらく設定しようとしているコマンドとの差分比較のため)
- 未設定のコマンド
ntp server 9.9.9.9
のみ適用 - 設定変更後のRunning ConfigとStartup Configを取得
- コマンド
copy running-config startup-config
で設定保存
Router>enable
Password:
Router#terminal length 0
Router#terminal width 512
Router#terminal width 0
Router#show version
(省略)
Router#show running-config
(省略)
ntp server 1.1.1.1
(省略)
Router#configure terminal
Enter configuration commands, one per line. End with CNTL/Z.
Router(config)#ntp server 9.9.9.9
Router(config)#end
******************************** [save_when: modified 指定時] ********************************
Router#show running-config
(省略)
ntp server 1.1.1.1
ntp server 9.9.9.9
(省略)
Router#show startup-config
(省略)
ntp server 1.1.1.1
(省略)
Router#copy running-config startup-config
Destination filename [startup-config]?
Building configuration...
[OK]
別パターンで、Running Configにntp server 9.9.9.9
はないものの、Startup Configには既に設定がある場合(=設定変更後にRunning ConfigとStartup Configが同じになる場合)、4点目の設定保存は行われませんでした。2つのConfigを比較して、保存が必要か判定しているようです。