DevNet Weekly Challenge 1 – Configure NTP Servers Using Ansible

The weekly challenge specifically designed to improve your skills and prepare you for the Cisco Certified DevNet Expert certification. In this weeks challenge, you will use Ansible to configure NTP servers on an IOS-XE device. Dive in, solve the challenge, and once you’ve cracked it, share your solution.

Kindly forwards the link to your Github profile showcasing your solution to luca.gubler@devnet-academy.com or post a comment with the link.

Interested in becoming a Cisco Certified DevNet Expert? Check out my e-learning where I teach you all the skills you need to pass the exam.

Hi Expert

I need your help on a project I’m working on. As you know we have one office in Europe, North America and Asia. I thought the routers were configured to use a NTP server close to its geographical location. Unfortunately, the junior network engineer just copied the config template and didn’t change the default NTP server. Right now all routers use the NTP server from Europe, which is not very optimal. Can you help me solve this issue?

I think it’s best if you develop a new Ansible role so we can integrate that role later on in our existing Ansible environment. I’m not an Ansible pro, but I think there is a command to generate a new role. I don’t remember the exact name of the command, but I always think of the movie “Guardians of the Galaxy”.

Objective

Your task is to create an Ansible role to configure the NTP servers on IOS-XE devices. Your role should be dynamic so new NTP servers can be added without changing the role itself.

Requirements

  1. Create a new role “ntp”.
  2. Define ntp servers inside the group_vars.
    • Use NTP server ch.pool.ntp.org for Europe
    • Use NTP server us.pool.ntp.org for North America
    • Use NTP server jp.pool.ntp.org for Asia
  3. Use one of the following Ansible connection plugins
    • CLI
    • HTTPAPI
    • NETCONF

Sample Usage

This is how it should look like when your solution is ready.

$ ansible-playbook -i inventory ntp_playbook.yml

First create a new folder ansible-environment. In here we will save all the inventories, roles, etc.

Next create a folder roles in which we save all our roles. Inside this folder execute the CLI command ansible-galaxy init ntp to create the new role.

Your folder structure now should look like this:

$ tree roles
roles
└── ntp
    ├── README.md
    ├── defaults
    │   └── main.yml
    ├── files
    ├── handlers
    │   └── main.yml
    ├── meta
    │   └── main.yml
    ├── tasks
    │   └── main.yml
    ├── templates
    ├── tests
    │   ├── inventory
    │   └── test.yml
    └── vars
        └── main.yml

10 directories, 8 files

The most important file is roles/ntp/tasks/main.yml. This file contains all the tasks to connect to our devices and configure the NTP servers. It should look like this:

---
- name: Configure NTP server
  cisco.ios.ios_config:
    lines: ntp server {{ ntp_server }}

Now our role is ready to be used. Now we have to define all our devices inside the inventory. First create the inventory directory if it doesn’t exist yet. Inside that directory create a host_vars directory and inside the host_vars directory create another directory with the name of your device, e.g. R1. Inside that folder you create a file main.yml which holds all host specific variables like device IP address, device OS, credentials etc. This sounds quite complicated, so please use the folder structure and main.yml file content from below as a reference.

$ tree inventory
inventory
└── host_vars
    └── R1
        └── main.yml
ansible_host: 131.226.217.143
ansible_network_os: ios
ansible_password: C1sco12345
ansible_become: true
ansible_user: admin
ansible_connection: network_cli
ansible_host_key_checking: no

In theory we could also define the NTP server inside the host_vars and it would work. But imagine if we have several hundred routers in Europe and each one has the NTP server defined in its host_vars file. If you have to change the NTP server now, you have to change it in several places which is very error prone. To fix this, we create a group Europe, define the NTP servers for that group and add all required devices to that group. To do that, create a new file routers.yml inside the inventory directory and add the following content.

To make the example a little more meaningful, I have additionally created the device R2 and added it to the group north_america.

$ tree inventory
inventory
├── group_vars
├── host_vars
│   ├── R1
│   │   └── main.yml
│   └── R2
│       └── main.yml  # Add R2 to make example more meaningful
└── routers.yml

This is the content of routers.yml

---
all:
  hosts:  # Add all hosts
    R1:
    R2:
  children:
    europe:  # Define group europe
      hosts:
        R1:  # Add R1 to group europe
      vars:  # Define additional variables which apply to all devices in group europe
        ntp_server: ch.pool.ntp.org
    north_america:
      hosts:
        R2:
      vars:
        ntp_server: us.pool.ntp.org

The last step is to create a playbook ntp_playbook.yml which will execute your role. This playbook should look like this:

---
- hosts: all
  gather_facts: false

  tasks:
    - name: Include role ntp
      include_role:
        name: ntp

Now execute your playbook using the following command.

$ ansible-playbook -i inventory ntp_playbook.yml
5 1 vote
Content Rating
Subscribe
Notify of
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments