Ansible沉浸式工作坊 2018年12月 网络篇

image.png

我参加了在A.P. Communications举办的Ansible技术交流会2018年12月网络篇,以博客的形式。

这次我一直在专注地进行这个事情的内容。

第一部分 – 使用Ansible从网络设备中收集数据
练习1.0 – 探索实验环境
练习1.1 – 编写您的第一个playbook
练习1.2 – 模块文档、注册输出和标签
第二部分 – 使用Ansible进行配置、备份和恢复
练习2.0 – 使用Ansible更新路由器配置
练习2.1 – 备份路由器配置
练习2.2 – 使用Ansible恢复备份的配置
第三部分 – 使用Ansible解析信息进行报告
练习3.0 – 介绍使用Jinja2模板
练习3.1 – 使用命令解析器构建动态文档

我能够进行到Exercise 2.0的部分。

以下是从Exercise 1.0开始进行的结果记录。

练习1.0 – 检查Anisble的实验环境

第一步,进入准备好的文件目录,并查看Ansible的版本。

[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)]

第三步,查看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]$

第四步:检查清单文件的内容。

[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]$

第5步,对清单文件进行解释。

练习1.0到此结束。

练习 1.1 – 尝试写首个playbook

第一步:创建gather_ios_data.yml文件。

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

步骤2:将以下内容复制并粘贴。

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

步骤3:添加任务的3行。

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

  tasks:
    - name: GATHER ROUTER FACTS
      ios_facts:

第四步:现在让我们来执行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: [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]$

第五步- 添加“-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]$

第6步–尝试使用限制条件进行执行。

我将尝试使用 “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]$

第七步:调试模块

在Playbook的任务中添加debug。

---
- 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]$

在这两个添加的任务中,输出了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]$

我已经获取到两台路由器的信息。

在这里,习题1.1就结束了。

练习1.2 – 如何查看模块文档、注册输出结果的方法、以及使用标签的方式

第一步:查看文档

$ ansible-doc debug

当你输入”って打つと”时

image.png

可以在主机上检查文档!
不能说总是在浏览器上看www

第二步,iOS指令模块。

在Playbook中添加ios_command。由于commands的内容是一个数组,所以会执行两个命令吗?

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

第三步:添加标签

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

第四步- 加上–tags选项来执行playbook。

只有被标记的任务会被执行。
显示iOS版本和序列号的任务被跳过了。

[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]$

第五步-尝试添加-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]$

第六步,添加注册功能

我已经补充了以下一行代码:
我定义了一个用来存储输出结果的变量。

      tags: show
      register: show_output

第七步:使用调试模块将show_output变量输出

      tags: show
      register: show_output

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

步骤8:执行完成的Playbook。

在第5步中,命令的执行结果原先是通过stdout_lines变量进行输出,现在通过任务中的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]$

第9步:展示 show_output 的语法解析

从show_output的输出中获取stdout数组的第一个元素。

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

第十步:重新执行 Playbook

终于,在最后一个任务中,只提取主机名并输出。

[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]$

实验1.2现在结束了。

运动2.0 – 尝试更新路由器的配置

到目前为止,这是一个涉及信息获取的练习,但从这里开始似乎是关于配置的。

第一步,创建router_configs.yml文件。

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

在Step2中,通过ios_config添加任务。

添加任务以确保同时存在SNMP字符串ansible-public和ansible-private。

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

执行第三步操作手册

由于设置已经被输入,所以返回了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]$

第四步:确认幂等性

我会再次运行 Playbook。
返回了 changed=0。由于在第3步已经添加了设置,所以再次运行也不会添加任何设置或进行任何更改。

[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]$

第五步:试着添加一行任务。

          - snmp-server community ansible-test RO

第六步,尝试执行。

我会尝试加上 `–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] *******************************************************************
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]$

第八步 配置投入

不使用Playbook进行设置,而是直接将配置文件导入。
将以下内容写入并保存在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

第九步:添加Play.

我要追加以下内容。

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

添加步骤10的任务

我要添加ios_config模块的任务。

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

第11步执行Playbook。
第11步开始执行Playbook。
进行第11步,执行Playbook。
进行第11步骤,运行Playbook。
执行第11步,运行Playbook。
开始执行第11步骤,运行Playbook。

在执行之前,我使用“-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采取了这种形式。

---
- 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
---
- 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中的配置文件

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

成果报告

使用Ansible的Zabbix模块来尝试。
尝试使用Ansible操作nginx。

听说有第二个人被塔环绕的情景迷住了。
我也想更多地尝试一下AWX呢。

非常感谢RedHat方面和会场的AP Communications团队的支持。今天我又学到了很多东西。

广告
将在 10 秒后关闭
bannerAds