てくなべ (tekunabe)

ansible / network / automation

[Ansible] 「つまずき Ansible 【Part14】ネットワーク機器のshowコマンドログ収集」ふりかえり

はじめに

2020/08/22 に、YouTube Live で「つまずき Ansible 【Part14】ネットワーク機器のshowコマンドログ収集」という配信をしました。

実際に作業しながらエラーと戦って進めるシリーズです。

tekunabe.connpass.com

今回は、Cisco のネットワーク機器に対して show コマンドを実行し、手作業風のログを生成する Playbook と Jinja2 テンプレートを作成しました。

やったことや、わかったことをふりかえります。

動画

www.youtube.com


■ やったこと

ひとまず コマンド実行結果を画面に表示する

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') }}

ただし、実際のコマンド実行時刻ではなく、ログファイル生成時なので注意。(ご指摘ありがとうございます!)


Part15 にむけて

以下のネタを検討中です。気が向いたものをやります。

  • connection: local ななにか
  • Ansible Toewr / AWX をコマンドがら操作する
  • ansible.cfg
  • Jinja2、フィルター
  • Windows
  • when、assert など