はじめに
2020/08/22 に、YouTube Live で「つまずき Ansible 【Part14】ネットワーク機器のshowコマンドログ収集」という配信をしました。
実際に作業しながらエラーと戦って進めるシリーズです。
今回は、Cisco のネットワーク機器に対して show コマンドを実行し、手作業風のログを生成する Playbook と Jinja2 テンプレートを作成しました。
やったことや、わかったことをふりかえります。
動画
■ やったこと
ひとまず コマンド実行結果を画面に表示する
Playbook
--- - hosts: ios gather_facts: false vars: commands: - show ip interface brief - show ip route tasks: - name: show command ios_command: commands: "{{ commands }}" register: result # uketoru - name: debug debug: var: result.stdout
ついでに、結果を yaml 形式で表示にするように変更
参考: [Ansible] callback plugin を yaml に変更して標準出力の改行を見やすくする - てくなべ (tekunabe)
export ANSIBLE_STDOUT_CALLBACK=yaml
結果
% ansible-playbook -i inventory.ini ios_log.yml
TASK [debug] **********************************************************************************************************************************************************************
ok: [rt02] =>
result.stdout:
- |-
Interface IP-Address OK? Method Status Protocol
GigabitEthernet0/0 192.168.1.12 YES TFTP up up
GigabitEthernet0/1 unassigned YES TFTP administratively down down
GigabitEthernet0/2 unassigned YES TFTP administratively down down
GigabitEthernet0/3 10.0.0.2 YES TFTP up up
Loopback0 10.255.255.2 YES TFTP up up
- |-
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
...(略)...
Gateway of last resort is 192.168.1.1 to network 0.0.0.0
S* 0.0.0.0/0 [1/0] via 192.168.1.1
10.0.0.0/8 is variably subnetted, 4 subnets, 2 masks
C 10.0.0.0/24 is directly connected, GigabitEthernet0/3
L 10.0.0.2/32 is directly connected, GigabitEthernet0/3
O 10.255.255.1/32 [110/2] via 10.0.0.1, 4w1d, GigabitEthernet0/3
C 10.255.255.2/32 is directly connected, Loopback0
192.168.1.0/24 is variably subnetted, 2 subnets, 2 masks
C 192.168.1.0/24 is directly connected, GigabitEthernet0/0
L 192.168.1.12/32 is directly connected, GigabitEthernet0/0
ファイルに書き出す
Playbook
--- - hosts: ios gather_facts: false vars: commands: - show ip interface brief - show ip route tasks: - name: show command ios_command: commands: "{{ commands }}" register: result # uketoru - name: file template: src: ios_log.j2 dest: "ios_log_{{ inventory_hostname }}"
テンプレートファイル ios_log.j2
{% for cmd in commands %}
{{ inventory_hostname }}# {{ cmd }}
{{ result.stdout[loop.index0] }}
{% endfor %}
上記では、コマンド名を定義して commands で繰り返していますが、result.stdout でも構いません。
result.stdout の場合は以下の通り。
{% for out in result.stdout %}
{{ inventory_hostname }}# {{ commands[loop.index0] }}
{{ out }}
{% endfor %}
結果
- Playbook 実行ログ
% ansible-playbook -i inventory.ini ios_log.yml PLAY [ios] ******************************************************************************************************** TASK [show command] *********************************************************************************************** ok: [rt01] ok: [rt02] TASK [file] ******************************************************************************************************* changed: [rt01] changed: [rt02] PLAY RECAP ******************************************************************************************************** rt01 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 rt02 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
- 生成されたファイル
ios_log_rt01
rt01# show ip interface brief
Interface IP-Address OK? Method Status Protocol
GigabitEthernet0/0 192.168.1.11 YES TFTP up up
GigabitEthernet0/1 unassigned YES TFTP administratively down down
GigabitEthernet0/2 unassigned YES TFTP administratively down down
GigabitEthernet0/3 10.0.0.1 YES TFTP up up
Loopback0 10.255.255.1 YES TFTP up up
rt01# show ip route
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
...(略)...
Gateway of last resort is not set
10.0.0.0/8 is variably subnetted, 4 subnets, 2 masks
C 10.0.0.0/24 is directly connected, GigabitEthernet0/3
L 10.0.0.1/32 is directly connected, GigabitEthernet0/3
C 10.255.255.1/32 is directly connected, Loopback0
O 10.255.255.2/32 [110/2] via 10.0.0.2, 4w1d, GigabitEthernet0/3
192.168.1.0/24 is variably subnetted, 2 subnets, 2 masks
C 192.168.1.0/24 is directly connected, GigabitEthernet0/0
L 192.168.1.11/32 is directly connected, GigabitEthernet0/0
ios_log_rt02
rt02# show ip interface brief
Interface IP-Address OK? Method Status Protocol
GigabitEthernet0/0 192.168.1.12 YES TFTP up up
GigabitEthernet0/1 unassigned YES TFTP administratively down down
GigabitEthernet0/2 unassigned YES TFTP administratively down down
GigabitEthernet0/3 10.0.0.2 YES TFTP up up
Loopback0 10.255.255.2 YES TFTP up up
rt02# show ip route
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
...(略)...
Gateway of last resort is 192.168.1.1 to network 0.0.0.0
S* 0.0.0.0/0 [1/0] via 192.168.1.1
10.0.0.0/8 is variably subnetted, 4 subnets, 2 masks
C 10.0.0.0/24 is directly connected, GigabitEthernet0/3
L 10.0.0.2/32 is directly connected, GigabitEthernet0/3
O 10.255.255.1/32 [110/2] via 10.0.0.1, 4w1d, GigabitEthernet0/3
C 10.255.255.2/32 is directly connected, Loopback0
192.168.1.0/24 is variably subnetted, 2 subnets, 2 masks
C 192.168.1.0/24 is directly connected, GigabitEthernet0/0
L 192.168.1.12/32 is directly connected, GigabitEthernet0/0
テンプレートファイルをカスタマイズすることでいろいろ応用できます。
例えば、now で現在時刻を表示。
{{ now(False, '%Y%m%d_%H%M%S') }}
ただし、実際のコマンド実行時刻ではなく、ログファイル生成時なので注意。(ご指摘ありがとうございます!)
now()だと、j2生成時の時間になるので、コマンド実行時とはちょっとズレるのかな?#tekunabe
— z a k i (@zaki_hmkc) 2020年8月22日
Part15 にむけて
以下のネタを検討中です。気が向いたものをやります。
- connection: local ななにか
- Ansible Toewr / AWX をコマンドがら操作する
- ansible.cfg
- Jinja2、フィルター
- Windows
- when、assert など