Ansible
Cisco

Ansibleもくもく会 2018.12 ネットワーク編

image.png

エーピーコミュニケーションズ さんで行われたAnsibleもくもく会 2018.12 ネットワーク編にブログ枠で参加してきましたー:runner_tone4: :runner_tone3: :runner_tone2:

今回自分はこちらの内容をもくもくしてました。

https://github.com/network-automation/linklight/tree/master/exercises/networking_v2

Section 01 - Using Ansible to gather data from network devices

 Exercise 1.0 - Exploring the lab environment

 Exercise 1.1 - Writing your first playbook

 Exercise 1.2 - Module documentation, Registering output & tags

Section 02 - Using Ansible to configure, backup and restore

 Exercise 2.0 - Updating the router configurations using Ansible

 Exercise 2.1 - Backing up the router configuration

 Exercise 2.2 - Using Ansible to restore the backed up configuration

Section 03 - Using Ansible to parse information for reporting

 Exercise 3.0 - An introduction to templating with Jinja2

 Exercise 3.1 - Building dynamic documentation using the command parser

Exercise 2.0 のとこまで進めることができました。

以下にExercise 1.0から進めていた結果を記載します。


Exercise 1.0 - Anisbleのlab環境を確認してみよう

Step1,2 ファイルが用意されたディレクトリに移動してAnsibleのVersionを確認します。

[student39@ansible ~]$ cd networking-workshop/

[student39@ansible networking-workshop]$ ansible --version
ansible 2.7.4
config file = /home/student39/.ansible.cfg
configured module search path = [u'/home/student39/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, May 3 2017, 07:55:04) [GCC 4.8.5 20150623 (Red Hat 4.8.5-14)]

Step3 ansible.cfgの中身を確認します。

[student39@ansible networking-workshop]$ cat ~/.ansible.cfg

[defaults]
connection = smart
timeout = 60
deprecation_warnings = False
inventory = /home/student39/networking-workshop/lab_inventory/hosts
host_key_checking = False
private_key_file = /home/student39/.ssh/aws-private.pem
[student39@ansible networking-workshop]$

Step4 インベントリファイルの中身を確認します。

[student39@ansible networking-workshop]$ cat ~/networking-workshop/lab_inventory/hosts

[all:vars]
ansible_user=student39
ansible_ssh_pass=red123hat
ansible_port=22

[routers:children]
cisco

[cisco]
rtr1 ansible_host=3.0.21.49 ansible_ssh_user=ec2-user private_ip=172.16.196.235 ansible_network_os=ios
rtr2 ansible_host=54.254.176.206 ansible_ssh_user=ec2-user private_ip=172.17.47.68 ansible_network_os=ios

[cisco:vars]
ansible_ssh_user=ec2-user
ansible_network_os=ios

[dc1]
rtr1

[dc2]
rtr2

[hosts]
host1 ansible_host=54.169.252.113 ansible_ssh_user=ec2-user private_ip=172.17.231.78

[control]
ansible ansible_host=13.250.95.1 ansible_ssh_user=ec2-user private_ip=172.16.85.1
[student39@ansible networking-workshop]$

Step5 インベントリファイルの解説でした。

Exercise 1.0はここまででした。


Exercise 1.1 - 初めてのplaybookを書いてみよう

Step 1:gather_ios_data.ymlファイルを作成します。

[student39@ansible networking-workshop]$ vim gather_ios_data.yml

Step2: 以下をコピペして貼り付けます。


gather_ios_data.yml

---

- name: GATHER INFORMATION FROM ROUTERS
hosts: cisco
connection: network_cli
gather_facts: no

Step3: taskの3行を追加します。


gather_ios_data.yml

---

- name: GATHER INFORMATION FROM ROUTERS
hosts: cisco
connection: network_cli
gather_facts: no

tasks:
- name: GATHER ROUTER FACTS
ios_facts:


Step4: いざPlaybookを実行してみます

ルータ2台に実行されました。

[student39@ansible networking-workshop]$ ansible-playbook -i lab_inventory/hosts gather_ios_data.yml

PLAY [GATHER INFORMATION FROM ROUTERS] ************************************************************************************

TASK [GATHER ROUTER FACTS] ************************************************************************************************
ok: [rtr2]
ok: [rtr1]

PLAY RECAP ****************************************************************************************************************
rtr1 : ok=1 changed=0 unreachable=0 failed=0
rtr2 : ok=1 changed=0 unreachable=0 failed=0

[student39@ansible networking-workshop]$

Step 5 -vを付けて実行せよ

-vを付けることでStep4では出力されなかったルータの情報が出力されました。

[student39@ansible networking-workshop]$ ansible-playbook -i lab_inventory/hosts gather_ios_data.yml -v

Using /home/student39/.ansible.cfg as config file
/home/student39/networking-workshop/lab_inventory/hosts did not meet host_list requirements, check plugin documentation if this is unexpected
/home/student39/networking-workshop/lab_inventory/hosts did not meet script requirements, check plugin documentation if this is unexpected

PLAY [GATHER INFORMATION FROM ROUTERS] ************************************************************************************

TASK [GATHER ROUTER FACTS] ************************************************************************************************
ok: [rtr2] => {"ansible_facts": {"ansible_net_all_ipv4_addresses": ["172.17.47.68", "192.168.35.101"], "ansible_net_all_ipv6_addresses": [], "ansible_net_filesystems": ["bootflash:"], "ansible_net_filesystems_info": {"bootflash:": {"spacefree_kb": 6897200, "spacetotal_kb": 7712284}}, "ansible_net_gather_subset": ["hardware", "default", "interfaces"], "ansible_net_hostname": "ip-172-17-47-68", "ansible_net_image": "boot:packages.conf", "ansible_net_interfaces": {"GigabitEthernet1": {"bandwidth": 1000000, "description": null, "duplex": "Full", "ipv4": [{"address": "172.17.47.68", "subnet": "16"}], "lineprotocol": "up ", "macaddress": "02a7.ffec.4580", "mediatype": "Virtual", "mtu": 1500, "operstatus": "up", "type": "CSR vNIC"}, "VirtualPortGroup0": {"bandwidth": 750000, "description": null, "duplex": null, "ipv4": [{"address": "192.168.35.101", "subnet": "24"}], "lineprotocol": "up ", "macaddress": "001e.e660.d5bd", "mediatype": null, "mtu": 1500, "operstatus": "up", "type": "Virtual Port Group"}}, "ansible_net_memfree_mb": 1861626, "ansible_net_memtotal_mb": 2180876, "ansible_net_model": "CSR1000V", "ansible_net_serialnum": "9IFB49JH8S0", "ansible_net_version": "16.09.01"}, "changed": false}
ok: [rtr1] => {"ansible_facts": {"ansible_net_all_ipv4_addresses": ["172.16.196.235", "192.168.35.101"], "ansible_net_all_ipv6_addresses": [], "ansible_net_filesystems": ["bootflash:"], "ansible_net_filesystems_info": {"bootflash:": {"spacefree_kb": 6897212, "spacetotal_kb": 7712284}}, "ansible_net_gather_subset": ["hardware", "default", "interfaces"], "ansible_net_hostname": "ip-172-16-196-235", "ansible_net_image": "boot:packages.conf", "ansible_net_interfaces": {"GigabitEthernet1": {"bandwidth": 1000000, "description": null, "duplex": "Full", "ipv4": [{"address": "172.16.196.235", "subnet": "16"}], "lineprotocol": "up ", "macaddress": "0222.3397.7018", "mediatype": "Virtual", "mtu": 1500, "operstatus": "up", "type": "CSR vNIC"}, "VirtualPortGroup0": {"bandwidth": 750000, "description": null, "duplex": null, "ipv4": [{"address": "192.168.35.101", "subnet": "24"}], "lineprotocol": "up ", "macaddress": "001e.145b.93bd", "mediatype": null, "mtu": 1500, "operstatus": "up", "type": "Virtual Port Group"}}, "ansible_net_memfree_mb": 1861634, "ansible_net_memtotal_mb": 2180876, "ansible_net_model": "CSR1000V", "ansible_net_serialnum": "9C71LWD4NJ9", "ansible_net_version": "16.09.01"}, "changed": false}

PLAY RECAP ****************************************************************************************************************
rtr1 : ok=1 changed=0 unreachable=0 failed=0
rtr2 : ok=1 changed=0 unreachable=0 failed=0

[student39@ansible networking-workshop]$

Step 6 --limitを付けて実行してみる

--limit rtr1 を指定して実行してみます。

Step5 の結果と見比べてみると、rtr1にだけ実行されていることがわかります。

[student39@ansible networking-workshop]$ ansible-playbook -i lab_inventory/hosts gather_ios_data.yml -v --limit rtr1

Using /home/student39/.ansible.cfg as config file
/home/student39/networking-workshop/lab_inventory/hosts did not meet host_list requirements, check plugin documentation if this is unexpected
/home/student39/networking-workshop/lab_inventory/hosts did not meet script requirements, check plugin documentation if this is unexpected

PLAY [GATHER INFORMATION FROM ROUTERS] ************************************************************************************

TASK [GATHER ROUTER FACTS] ************************************************************************************************
ok: [rtr1] => {"ansible_facts": {"ansible_net_all_ipv4_addresses": ["172.16.196.235", "192.168.35.101"], "ansible_net_all_ipv6_addresses": [], "ansible_net_filesystems": ["bootflash:"], "ansible_net_filesystems_info": {"bootflash:": {"spacefree_kb": 6897212, "spacetotal_kb": 7712284}}, "ansible_net_gather_subset": ["hardware", "default", "interfaces"], "ansible_net_hostname": "ip-172-16-196-235", "ansible_net_image": "boot:packages.conf", "ansible_net_interfaces": {"GigabitEthernet1": {"bandwidth": 1000000, "description": null, "duplex": "Full", "ipv4": [{"address": "172.16.196.235", "subnet": "16"}], "lineprotocol": "up ", "macaddress": "0222.3397.7018", "mediatype": "Virtual", "mtu": 1500, "operstatus": "up", "type": "CSR vNIC"}, "VirtualPortGroup0": {"bandwidth": 750000, "description": null, "duplex": null, "ipv4": [{"address": "192.168.35.101", "subnet": "24"}], "lineprotocol": "up ", "macaddress": "001e.145b.93bd", "mediatype": null, "mtu": 1500, "operstatus": "up", "type": "Virtual Port Group"}}, "ansible_net_memfree_mb": 1861634, "ansible_net_memtotal_mb": 2180876, "ansible_net_model": "CSR1000V", "ansible_net_serialnum": "9C71LWD4NJ9", "ansible_net_version": "16.09.01"}, "changed": false}

PLAY RECAP ****************************************************************************************************************
rtr1 : ok=1 changed=0 unreachable=0 failed=0

[student39@ansible networking-workshop]$

Step7 debugモジュール

Playbookのtaskにdebugを追加します。


gather_ios_data.yml

---

- name: GATHER INFORMATION FROM ROUTERS
hosts: cisco
connection: network_cli
gather_facts: no

tasks:
- name: GATHER ROUTER FACTS
ios_facts:

- name: DISPLAY VERSION
debug:
msg: "The IOS version is: {{ ansible_net_version }}"

- name: DISPLAY SERIAL NUMBER
debug:
msg: "The serial number is:{{ ansible_net_serialnum }}"


実行してみます。

[student39@ansible networking-workshop]$ ansible-playbook -i lab_inventory/hosts gather_ios_data.yml -v --limit rtr1

Using /home/student39/.ansible.cfg as config file
/home/student39/networking-workshop/lab_inventory/hosts did not meet host_list requirements, check plugin documentation if this is unexpected
/home/student39/networking-workshop/lab_inventory/hosts did not meet script requirements, check plugin documentation if this is unexpected

PLAY [GATHER INFORMATION FROM ROUTERS] ************************************************************************************

TASK [GATHER ROUTER FACTS] ************************************************************************************************
ok: [rtr1] => {"ansible_facts": {"ansible_net_all_ipv4_addresses": ["172.16.196.235", "192.168.35.101"], "ansible_net_all_ipv6_addresses": [], "ansible_net_filesystems": ["bootflash:"], "ansible_net_filesystems_info": {"bootflash:": {"spacefree_kb": 6897212, "spacetotal_kb": 7712284}}, "ansible_net_gather_subset": ["hardware", "default", "interfaces"], "ansible_net_hostname": "ip-172-16-196-235", "ansible_net_image": "boot:packages.conf", "ansible_net_interfaces": {"GigabitEthernet1": {"bandwidth": 1000000, "description": null, "duplex": "Full", "ipv4": [{"address": "172.16.196.235", "subnet": "16"}], "lineprotocol": "up ", "macaddress": "0222.3397.7018", "mediatype": "Virtual", "mtu": 1500, "operstatus": "up", "type": "CSR vNIC"}, "VirtualPortGroup0": {"bandwidth": 750000, "description": null, "duplex": null, "ipv4": [{"address": "192.168.35.101", "subnet": "24"}], "lineprotocol": "up ", "macaddress": "001e.145b.93bd", "mediatype": null, "mtu": 1500, "operstatus": "up", "type": "Virtual Port Group"}}, "ansible_net_memfree_mb": 1861634, "ansible_net_memtotal_mb": 2180876, "ansible_net_model": "CSR1000V", "ansible_net_serialnum": "9C71LWD4NJ9", "ansible_net_version": "16.09.01"}, "changed": false}

TASK [DISPLAY VERSION] ****************************************************************************************************
ok: [rtr1] => {
"msg": "The IOS version is: 16.09.01"
}

TASK [DISPLAY SERIAL NUMBER] **********************************************************************************************
ok: [rtr1] => {
"msg": "The serial number is:9C71LWD4NJ9"
}

PLAY RECAP ****************************************************************************************************************
rtr1 : ok=3 changed=0 unreachable=0 failed=0

[student39@ansible networking-workshop]$

追加された2つのタスクでiosのバージョンとシリアルナンバーが出力されました。

Step8 playbookを再実行

ここまで出来上がったPlaybookを再実行してみます。

[student39@ansible networking-workshop]$ ansible-playbook -i lab_inventory/hosts gather_ios_data.yml

PLAY [GATHER INFORMATION FROM ROUTERS] ************************************************************************************

TASK [GATHER ROUTER FACTS] ************************************************************************************************
ok: [rtr1]
ok: [rtr2]

TASK [DISPLAY VERSION] ****************************************************************************************************
ok: [rtr1] => {
"msg": "The IOS version is: 16.09.01"
}
ok: [rtr2] => {
"msg": "The IOS version is: 16.09.01"
}

TASK [DISPLAY SERIAL NUMBER] **********************************************************************************************
ok: [rtr1] => {
"msg": "The serial number is:9C71LWD4NJ9"
}
ok: [rtr2] => {
"msg": "The serial number is:9IFB49JH8S0"
}

PLAY RECAP ****************************************************************************************************************
rtr1 : ok=3 changed=0 unreachable=0 failed=0
rtr2 : ok=3 changed=0 unreachable=0 failed=0

[student39@ansible networking-workshop]$

2台のルータの情報が取れました。

exercise 1.1はここまででした。


Exercise 1.2 - Moduleのドキュメントの確認方法、 出力結果の登録方法、 tagの使い方

Step 1 docの確認

$ ansible-doc debug

って打つと

image.png

ホスト上でドキュメントが確認できる!

いつもブラウザで見てたとは言えないwww

Step 2 ios_commandモジュール

Playbookにios_commandを追記。commandsの内容が配列になっているので2個実行されるのかな?


gather_ios_data.yml

    - name: COLLECT OUTPUT OF SHOW COMMANDS

ios_command:
commands:
- show run | i hostname
- show ip interface brief

Step 3 tagを追加


gather_ios_data.yml

    - name: COLLECT OUTPUT OF SHOW COMMANDS

ios_command:
commands:
- show run | i hostname
- show ip interface brief
tags: show

Step4 --tagsオプションをつけてplaybookを実行

tagを付けたtaskだけ実行されます。

iosのVersionとシリアルナンバーを表示するtaskがスキップされました。

[student39@ansible networking-workshop]$ ansible-playbook -i lab_inventory/hosts gather_ios_data.yml --tags=show

PLAY [GATHER INFORMATION FROM ROUTERS] ************************************************************************************

TASK [COLLECT OUTPUT OF SHOW COMMANDS] ************************************************************************************
ok: [rtr1]
ok: [rtr2]

PLAY RECAP ****************************************************************************************************************
rtr1 : ok=1 changed=0 unreachable=0 failed=0
rtr2 : ok=1 changed=0 unreachable=0 failed=0

[student39@ansible networking-workshop]$

Step 5 -vを付けて実行してみます。

コマンドの実行結果がJSONで返ってきます。

[student39@ansible networking-workshop]$ ansible-playbook -i lab_inventory/hosts gather_ios_data.yml --tags=show -v

Using /home/student39/.ansible.cfg as config file
/home/student39/networking-workshop/lab_inventory/hosts did not meet host_list requirements, check plugin documentation if this is unexpected
/home/student39/networking-workshop/lab_inventory/hosts did not meet script requirements, check plugin documentation if this is unexpected

PLAY [GATHER INFORMATION FROM ROUTERS] ************************************************************************************

TASK [COLLECT OUTPUT OF SHOW COMMANDS] ************************************************************************************
ok: [rtr1] => {"changed": false, "stdout": ["hostname ip-172-16-196-235", "Interface IP-Address OK? Method Status Protocol\nGigabitEthernet1 172.16.196.235 YES DHCP up up \nVirtualPortGroup0 192.168.35.101 YES TFTP up up"], "stdout_lines": [["hostname ip-172-16-196-235"], ["Interface IP-Address OK? Method Status Protocol", "GigabitEthernet1 172.16.196.235 YES DHCP up up ", "VirtualPortGroup0 192.168.35.101 YES TFTP up up"]]}
ok: [rtr2] => {"changed": false, "stdout": ["hostname ip-172-17-47-68", "Interface IP-Address OK? Method Status Protocol\nGigabitEthernet1 172.17.47.68 YES DHCP up up \nVirtualPortGroup0 192.168.35.101 YES TFTP up up"], "stdout_lines": [["hostname ip-172-17-47-68"], ["Interface IP-Address OK? Method Status Protocol", "GigabitEthernet1 172.17.47.68 YES DHCP up up ", "VirtualPortGroup0 192.168.35.101 YES TFTP up up"]]}

PLAY RECAP ****************************************************************************************************************
rtr1 : ok=1 changed=0 unreachable=0 failed=0
rtr2 : ok=1 changed=0 unreachable=0 failed=0

[student39@ansible networking-workshop]$

Step6 registerを追加

以下の1行を追記します。

出力結果を格納する用の変数を定義しました。


gather_ios_data.yml

      tags: show

register: show_output

Step 7 show_output変数をdebugモジュールで出力


gather_ios_data.yml

      tags: show

register: show_output

- name: DISPLAY THE COMMAND OUTPUT
debug:
var: show_output
tags: show


Step8 出来上がったPlaybookを実行します

Step5ではstdout_lines変数で出力されていたコマンドの実行結果が、taskのshow_output変数で出力されるようになりました。

[student39@ansible networking-workshop]$ ansible-playbook -i lab_inventory/hosts gather_ios_data.yml --tags=show

PLAY [GATHER INFORMATION FROM ROUTERS] ************************************************************************************

TASK [COLLECT OUTPUT OF SHOW COMMANDS] ************************************************************************************
ok: [rtr2]
ok: [rtr1]

TASK [DISPLAY THE COMMAND OUTPUT] *****************************************************************************************
ok: [rtr1] => {
"show_output": {
"changed": false,
"failed": false,
"stdout": [
"hostname ip-172-16-196-235",
"Interface IP-Address OK? Method Status Protocol\nGigabitEthernet1 172.16.196.235 YES DHCP up up \nVirtualPortGroup0 192.168.35.101 YES TFTP up up"
],
"stdout_lines": [
[
"hostname ip-172-16-196-235"
],
[
"Interface IP-Address OK? Method Status Protocol",
"GigabitEthernet1 172.16.196.235 YES DHCP up up ",
"VirtualPortGroup0 192.168.35.101 YES TFTP up up"
]
]
}
}
ok: [rtr2] => {
"show_output": {
"changed": false,
"failed": false,
"stdout": [
"hostname ip-172-17-47-68",
"Interface IP-Address OK? Method Status Protocol\nGigabitEthernet1 172.17.47.68 YES DHCP up up \nVirtualPortGroup0 192.168.35.101 YES TFTP up up"
],
"stdout_lines": [
[
"hostname ip-172-17-47-68"
],
[
"Interface IP-Address OK? Method Status Protocol",
"GigabitEthernet1 172.17.47.68 YES DHCP up up ",
"VirtualPortGroup0 192.168.35.101 YES TFTP up up"
]
]
}
}

PLAY RECAP ****************************************************************************************************************
rtr1 : ok=2 changed=0 unreachable=0 failed=0
rtr2 : ok=2 changed=0 unreachable=0 failed=0

[student39@ansible networking-workshop]$

Step 9 show_outputの構文解析

以下を追記します。

show_outputの出力から、stdoutの配列の0番目を取ってくる形ですね。


gather_ios_data.yml

    - name: DISPLAY THE HOSTNAME

debug:
msg: "The hostname is {{ show_output.stdout[0] }}"
tags: show

Step10 Playbookを再実行します

最後のtaskでホスト名だけ取り出して出力されるようになりました。

[student39@ansible networking-workshop]$ ansible-playbook -i lab_inventory/hosts gather_ios_data.yml --tags=show

PLAY [GATHER INFORMATION FROM ROUTERS] ************************************************************************************

TASK [COLLECT OUTPUT OF SHOW COMMANDS] ************************************************************************************
ok: [rtr1]
ok: [rtr2]

TASK [DISPLAY THE COMMAND OUTPUT] *****************************************************************************************
ok: [rtr1] => {
"show_output": {
"changed": false,
"failed": false,
"stdout": [
"hostname ip-172-16-196-235",
"Interface IP-Address OK? Method Status Protocol\nGigabitEthernet1 172.16.196.235 YES DHCP up up \nVirtualPortGroup0 192.168.35.101 YES TFTP up up"
],
"stdout_lines": [
[
"hostname ip-172-16-196-235"
],
[
"Interface IP-Address OK? Method Status Protocol",
"GigabitEthernet1 172.16.196.235 YES DHCP up up ",
"VirtualPortGroup0 192.168.35.101 YES TFTP up up"
]
]
}
}
ok: [rtr2] => {
"show_output": {
"changed": false,
"failed": false,
"stdout": [
"hostname ip-172-17-47-68",
"Interface IP-Address OK? Method Status Protocol\nGigabitEthernet1 172.17.47.68 YES DHCP up up \nVirtualPortGroup0 192.168.35.101 YES TFTP up up"
],
"stdout_lines": [
[
"hostname ip-172-17-47-68"
],
[
"Interface IP-Address OK? Method Status Protocol",
"GigabitEthernet1 172.17.47.68 YES DHCP up up ",
"VirtualPortGroup0 192.168.35.101 YES TFTP up up"
]
]
}
}

TASK [DISPLAY THE HOSTNAME] ***********************************************************************************************
ok: [rtr1] => {
"msg": "The hostname is hostname ip-172-16-196-235"
}
ok: [rtr2] => {
"msg": "The hostname is hostname ip-172-17-47-68"
}

PLAY RECAP ****************************************************************************************************************
rtr1 : ok=3 changed=0 unreachable=0 failed=0
rtr2 : ok=3 changed=0 unreachable=0 failed=0

[student39@ansible networking-workshop]$

以上でlab exercise 1.2 は終了です。


Exercise 2.0 - Routerのコンフィグを更新してみよう

ここまでは情報取得系のExerciseでしたが、ここからは設定系のようです。

Step 1 router_configs.ymlを作成します。


router_configs.yml

---

- name: SNMP RO/RW STRING CONFIGURATION
hosts: cisco
gather_facts: no
connection: network_cli


Step2 ios_configによるtaskを追加します。

SNMP strings ansible-public と ansible-private の両方が存在するようにタスクを追加します


router_configs.yml

    - name: ENSURE THAT THE DESIRED SNMP STRINGS ARE PRESENT

ios_config:
commands:
- snmp-server community ansible-public RO
- snmp-server community ansible-private RW

Step3 Playbookを実行します

設定が投入されたのでchanged=1が返ってきてますね。

[student39@ansible networking-workshop]$ ansible-playbook -i lab_inventory/hosts routers_config.yml

PLAY [SNMP RO/RW STRING CONFIGURATION] ************************************************************************************

TASK [ENSURE THAT THE DESIRED SNMP STRINGS ARE PRESENT] *******************************************************************
changed: [rtr2]
changed: [rtr1]

PLAY RECAP ****************************************************************************************************************
rtr1 : ok=1 changed=1 unreachable=0 failed=0
rtr2 : ok=1 changed=1 unreachable=0 failed=0

[student39@ansible networking-workshop]$

Step 4 冪等性の確認

Playbookを再度実行してみます。

changed=0が返ってきています。Step3ですでに設定が投入されているので再度実行しても、設定は投入されず何も変更されません。

[student39@ansible networking-workshop]$ ansible-playbook -i lab_inventory/hosts routers_config.yml

PLAY [SNMP RO/RW STRING CONFIGURATION] ************************************************************************************

TASK [ENSURE THAT THE DESIRED SNMP STRINGS ARE PRESENT] *******************************************************************
ok: [rtr1]
ok: [rtr2]

PLAY RECAP ****************************************************************************************************************
rtr1 : ok=1 changed=0 unreachable=0 failed=0
rtr2 : ok=1 changed=0 unreachable=0 failed=0

[student39@ansible networking-workshop]$

Step 5 タスクを1行追加してみます


router_configs.yml

          - snmp-server community ansible-test RO


Step 6 実行してみます

--check と -v を付けて実行してみます。

これを付けることで設定を投入する機器の変更する箇所を知ることができます。

dry-runの実行ですね。

[student39@ansible networking-workshop]$ ansible-playbook -i lab_inventory/hosts routers_config.yml --check -v

Using /home/student39/.ansible.cfg as config file
/home/student39/networking-workshop/lab_inventory/hosts did not meet host_list requirements, check plugin documentation if this is unexpected
/home/student39/networking-workshop/lab_inventory/hosts did not meet script requirements, check plugin documentation if this is unexpected

PLAY [SNMP RO/RW STRING CONFIGURATION] ************************************************************************************

TASK [ENSURE THAT THE DESIRED SNMP STRINGS ARE PRESENT] *******************************************************************
changed: [rtr2] => {"banners": {}, "changed": true, "commands": ["snmp-server community ansible-test RO"], "updates": ["snmp-server community ansible-test RO"]}
changed: [rtr1] => {"banners": {}, "changed": true, "commands": ["snmp-server community ansible-test RO"], "updates": ["snmp-server community ansible-test RO"]}

PLAY RECAP ****************************************************************************************************************
rtr1 : ok=1 changed=1 unreachable=0 failed=0
rtr2 : ok=1 changed=1 unreachable=0 failed=0

[student39@ansible networking-workshop]$

Step7 Playbookを実行してみます

--check と -v を付けないでそのまま実行してみます。

設定が投入されました。

[student39@ansible networking-workshop]$ ansible-playbook -i lab_inventory/hosts routers_config.yml

PLAY [SNMP RO/RW STRING CONFIGURATION] ************************************************************************************

TASK [ENSURE THAT THE DESIRED SNMP STRINGS ARE PRESENT] *******************************************************************
changed: [rtr2]
changed: [rtr1]

PLAY RECAP ****************************************************************************************************************
rtr1 : ok=1 changed=1 unreachable=0 failed=0
rtr2 : ok=1 changed=1 unreachable=0 failed=0

[student39@ansible networking-workshop]$

Step 8 Config投入

Playbookで設定をするのではなく、configファイルをそのまま投入します。

secure_router.cfgといファイルに以下を記載して保存します。


secure_router.cfg

line con 0

exec-timeout 5 0
line vty 0 4
exec-timeout 5 0
transport input ssh
ip ssh time-out 60
ip ssh authentication-retries 5
service password-encryption
service tcp-keepalives-in
service tcp-keepalives-out

Step 9 Playを追加します

以下を追記します。


router_configs.yml

- name: HARDEN IOS ROUTERS

hosts: cisco
gather_facts: no
connection: network_cli

Step 10 taskを追加します

ios_configモジュールのtaskを追加します。


router_configs.yml

  tasks:

- name: ENSURE THAT ROUTERS ARE SECURE
ios_config:
src: secure_router.cfg

Step 11 Playbookを実行します

--check -v で変更点を確認してから実行してみました。

[student39@ansible networking-workshop]$ ansible-playbook -i lab_inventory/hosts routers_config.yml --check -v

Using /home/student39/.ansible.cfg as config file
/home/student39/networking-workshop/lab_inventory/hosts did not meet host_list requirements, check plugin documentation if this is unexpected
/home/student39/networking-workshop/lab_inventory/hosts did not meet script requirements, check plugin documentation if this is unexpected

PLAY [SNMP RO/RW STRING CONFIGURATION] ************************************************************************************

TASK [ENSURE THAT THE DESIRED SNMP STRINGS ARE PRESENT] *******************************************************************
ok: [rtr2] => {"changed": false}
ok: [rtr1] => {"changed": false}

PLAY [HARDEN IOS ROUTERS] *************************************************************************************************

TASK [ENSURE THAT ROUTERS ARE SECURE] *************************************************************************************
changed: [rtr2] => {"banners": {}, "changed": true, "commands": ["line con 0", "exec-timeout 5 0", "line vty 0 4", "exec-timeout 5 0", "ip ssh time-out 60", "ip ssh authentication-retries 5", "service password-encryption", "service tcp-keepalives-in", "service tcp-keepalives-out"], "updates": ["line con 0", "exec-timeout 5 0", "line vty 0 4", "exec-timeout 5 0", "ip ssh time-out 60", "ip ssh authentication-retries 5", "service password-encryption", "service tcp-keepalives-in", "service tcp-keepalives-out"]}
changed: [rtr1] => {"banners": {}, "changed": true, "commands": ["line con 0", "exec-timeout 5 0", "line vty 0 4", "exec-timeout 5 0", "ip ssh time-out 60", "ip ssh authentication-retries 5", "service password-encryption", "service tcp-keepalives-in", "service tcp-keepalives-out"], "updates": ["line con 0", "exec-timeout 5 0", "line vty 0 4", "exec-timeout 5 0", "ip ssh time-out 60", "ip ssh authentication-retries 5", "service password-encryption", "service tcp-keepalives-in", "service tcp-keepalives-out"]}

PLAY RECAP ****************************************************************************************************************
rtr1 : ok=2 changed=1 unreachable=0 failed=0
rtr2 : ok=2 changed=1 unreachable=0 failed=0

[student39@ansible networking-workshop]$ ansible-playbook -i lab_inventory/hosts routers_config.yml

PLAY [SNMP RO/RW STRING CONFIGURATION] ************************************************************************************

TASK [ENSURE THAT THE DESIRED SNMP STRINGS ARE PRESENT] *******************************************************************
ok: [rtr1]
ok: [rtr2]

PLAY [HARDEN IOS ROUTERS] *************************************************************************************************

TASK [ENSURE THAT ROUTERS ARE SECURE] *************************************************************************************
changed: [rtr2]
changed: [rtr1]

PLAY RECAP ****************************************************************************************************************
rtr1 : ok=2 changed=1 unreachable=0 failed=0
rtr2 : ok=2 changed=1 unreachable=0 failed=0

[student39@ansible networking-workshop]$

ここまででExercise 2.0は終了してちょうど時間となりました。

最終的に今回使用したPlaybookはこんな形となりました。


gather_ios_data.yml

---

- name: GATHER INFORMATION FROM ROUTERS
hosts: cisco
connection: network_cli
gather_facts: no

tasks:
- name: GATHER ROUTER FACTS
ios_facts:

- name: DISPLAY VERSION
debug:
msg: "The IOS version is: {{ ansible_net_version }}"

- name: DISPLAY SERIAL NUMBER
debug:
msg: "The serial number is:{{ ansible_net_serialnum }}"

- name: COLLECT OUTPUT OF SHOW COMMANDS
ios_command:
commands:
- show run | i hostname
- show ip interface brief
- show version
tags: show
register: show_output

- name: DISPLAY THE COMMAND OUTPUT
debug:
var: show_output
tags: show

- name: DISPLAY THE HOSTNAME
debug:
msg: "The hostname is {{ show_output.stdout[0] }}"
tags: show



routers_config.yml

---

- name: SNMP RO/RW STRING CONFIGURATION
hosts: cisco
gather_facts: no
connection: network_cli

tasks:

- name: ENSURE THAT THE DESIRED SNMP STRINGS ARE PRESENT
ios_config:
commands:
- snmp-server community ansible-public RO
- snmp-server community ansible-private RW
- snmp-server community ansible-test RO

- name: HARDEN IOS ROUTERS
hosts: cisco
gather_facts: no
connection: network_cli

tasks:

- name: ENSURE THAT ROUTERS ARE SECURE
ios_config:
src: secure_router.cfg


ios_configで投入したConfigファイル

line con 0

exec-timeout 5 0
line vty 0 4
exec-timeout 5 0
transport input ssh
ip ssh time-out 60
ip ssh authentication-retries 5
service password-encryption
service tcp-keepalives-in
service tcp-keepalives-out


成果発表

1人目の方

AnsibleのZabbixモジュールを使用してみた。

Ansibleからnginxを操作してみた。

2人目の方

Towerまわりでハマったとのことでした。

自分ももっとAWX触ってみたいなー

というわけでRedHatの方と会場のエーピーコミュニケーションズの方々ありがとうございましたー

今日も勉強になりましたー:bow: :grinning: :stuck_out_tongue_closed_eyes: