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

![image.png](https://qiita-image-store.s3.amazonaws.com/0/146663/f1673079-2299-4887-1d8b-96abf42aac39.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: 以下をコピペして貼り付けます。

```yml:gather_ios_data.yml
---
- name: GATHER INFORMATION FROM ROUTERS
  hosts: cisco
  connection: network_cli
  gather_facts: no
```

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

```yml: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を追加します。

```yml: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](https://qiita-image-store.s3.amazonaws.com/0/146663/307937d1-88fe-f768-4929-ee899edc31a9.png)

ホスト上でドキュメントが確認できる！
~~いつもブラウザで見てたとは言えないwww~~

Step 2 ios_commandモジュール

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

```yml:gather_ios_data.yml
    - name: COLLECT OUTPUT OF SHOW COMMANDS
      ios_command:
        commands:
          - show run | i hostname
          - show ip interface brief
```

Step 3 tagを追加

```yml: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行を追記します。
出力結果を格納する用の変数を定義しました。

```yml:gather_ios_data.yml
      tags: show
      register: show_output
```

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

```yml: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番目を取ってくる形ですね。

```yml: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を作成します。

```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 の両方が存在するようにタスクを追加します

```yml: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行追加してみます

```yml: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を追加します

以下を追記します。

```yml:router_configs.yml
- name: HARDEN IOS ROUTERS
  hosts: cisco
  gather_facts: no
  connection: network_cli
```

Step 10 taskを追加します

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

```yml: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はこんな形となりました。

```yml: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
```

```yml: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: