Skip to content
Home » Blog » Ansible Lab 04 Automating Server Configuration and Routers NTP

Ansible Lab 04 Automating Server Configuration and Routers NTP

image showing automating server configuration within the ansible lab

lets have a blast with automating server configuration

YouTube player

In this post, we’ll cover the fourth lab in the Ansible series, focusing our routers and automating server configuration for NTP (Network Time Protocol). This lab introduces the integration of an Ubuntu server as an NTP server, aligning with real-world scenarios where network engineers often handle both networking and server tasks. We’ll walk through adding the server to the inventory, configuring the server as an NTP source, and updating router configurations for accurate time synchronisation.

Scenario Overview

Your manager has tasked you with setting up basic NTP functionality for your lab. This includes:

  • Adding the Ubuntu application server to your Ansible host file.
  • Configuring the server to act as an NTP server.
  • Updating router configurations to use the newly added server for time synchronisation.
  • Verifying that NTP is working correctly across all devices.

Step 1: Updating the Ansible Host File

Add the Ubuntu server to your Ansible inventory. The inventory file should already contain your routers and edge devices, so this step simply adds the app server details:

[routers]
London ansible_host=192.168.47.194
Manchester ansible_host=192.168.47.132
Asia ansible_host=192.168.47.226
America ansible_host=192.168.47.217
[routers:vars]
ansible_user=YouTube
ansible_ssh_pass=YouTube1
ansible_port=22
ansible_connection=network_cli
ansible_network_os=cisco.ios.ios

[edge]
R1 ansible_host=192.168.47.21
R2 ansible_host=192.168.47.22
R3 ansible_host=192.168.47.23
R4 ansible_host=192.168.47.24

[edge:vars]
ansible_user=YouTube
ansible_ssh_pass=YouTube1
ansible_port=22
ansible_connection=network_cli
ansible_network_os=cisco.ios.ios

[servers]
app-server ansible_host=192.168.47.200

[servers:vars]
ansible_user=sysadmin
ansible_ssh_pass=sysadmin123
ansibe-become=yes
ansible_become_method=sudo
ansible_become_password=sysadmin123

Step 2: Creating the NTP Server Playbook

Next, create a playbook to set up the Ubuntu server as an NTP server. This playbook installs the chrony package, configures the server to allow connections from your subnet, and ensures the necessary firewall rules are applied:

Playbook Name: ntp_server.yml

---
- name: NTP Server Setup
  hosts: servers
  become: yes
  tasks:
    - name: Install NTP server
      apt:
        name: chrony
        state: present
        update_cache: yes

    - name: Configure chrony as an NTP server
      lineinfile:
        path: /etc/chrony/chrony.conf
        regexp: '^pool '
        line: "# Commented by Ansible"
        state: present

    - name: Add local server configuration
      lineinfile:
        path: /etc/chrony/chrony.conf
        line: "allow 192.168.47.0/24"
        create: yes

    - name: Restart the chrony service
      systemd:
        name: chrony
        enabled: yes
        state: restarted

    - name: Allow NTP through the firewall
      ufw:
        rule: allow
        port: 123
        proto: udp
        comment: "Allow NTP traffic"

What It Does:

  1. Installs the NTP Package (chrony):

    The first task installs the chrony package, which is the preferred NTP daemon on most modern Linux distributions. Unlike the older ntpd, chrony is better at maintaining accurate time in environments with varying network conditions.

    update_cache: yes ensures the package lists are up to date, avoiding issues if the server hasn’t updated its repositories recently.

    state: present guarantees that the package is installed, whether or not it was previously missing.
  2. Configures the NTP Server (chrony.conf):

    This task modifies the chrony.conf file to prevent external pool servers from being used, which can introduce unwanted time offsets. It also adds a line to permit local clients on the 192.168.47.0/24 subnet to use this server for NTP.

    The lineinfile module is ideal here because it allows precise editing of configuration files without overwriting the entire file.

    The regexp option targets specific lines, ensuring you don’t accidentally duplicate settings.
  3. Adds Local Network Configuration:

    This task adds a line to the configuration file, permitting devices on the 192.168.47.0/24 subnet to use the server as a time source.
    This is essential for lab environments where the NTP server is on the same subnet as the devices.

    Without this line, the server would reject NTP requests from your routers, breaking the time sync setup.
  4. Restarts the NTP Service:
    Modifying the configuration, the service must be restarted to apply the changes.

    This ensures the chrony service is not only restarted but also enabled to start automatically on reboot, maintaining time sync reliability.
  5. Updates Firewall Rules:
    Ensures that UDP traffic on port 123 (the NTP port) is allowed through the server’s firewal.

    Without this step, NTP traffic would be blocked, making the server unreachable for time sync.

Running the Ansible Playbook

You run this playbook with ansible-playbook ntp_server.yml which is the last part of the section for automating server configuration and you should see the below

PLAY [NTP Server Setup] **************************
TASK [Install NTP server] ***********************
changed: [app-server]
TASK [Configure chrony as an NTP server] ********
changed: [app-server]
TASK [Add local server configuration] ***********
changed: [app-server]
TASK [Restart the chrony service] ***************
changed: [app-server]
TASK [Allow NTP through the firewall] ***********
changed: [app-server]
PLAY RECAP **************************************
app-server : ok=5 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Step 3: Configuring Routers to Use the NTP Server

playbook is used to push the NTP server configuration to all routers and edge devices in your lab.

Playbook Name: ntp_clients.yml

---
- name: Configure NTP
  hosts: edge,routers
  gather_facts: no
  connection: network_cli
  tasks:
    - name: Add NTP server
      cisco.ios.ios_config:
        lines:
          - ntp server 192.168.47.200 prefer minpoll 4 maxpoll 4

Running this playbook with ansible-playbook ntp_clients.yml will produce

PLAY [Configure NTP] *****************************
TASK [Add NTP server] ***************************
changed: [R1]
changed: [R2]
changed: [R3]
changed: [R4]
changed: [London]
changed: [Manchester]
changed: [Asia]
changed: [America]
PLAY RECAP **************************************
R1 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
R2 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
R3 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
R4 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
London : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Manchester : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Asia : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
America : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Step 4: Verifying the NTP Configuration

This playbook is designed to verify that your routers are correctly configured for NTP, It runs a set of show commands to check the status of NTP associations and ensure that time synchronisation is working as expected.

Playbook Name: ntp_verify.yml

---
- name: Check NTP
  hosts: edge,routers
  gather_facts: no
  connection: network_cli
  tasks:
    - name: Check routers for NTP
      cisco.ios.ios_command:
        commands:
          - show ntp associations
          - show ntp status
      register: output

    - name: Display output of commands
      debug:
        msg: "{{ output.stdout_lines }}"

Running the playbook with the following ansible-playbook ntp_verify.yml will display the NTP status for each device:

ok: [America] => {
    "msg": [
        [
            "address         ref clock       st   when   poll reach  delay  offset   disp",
            " ~192.168.47.200  .TIME.          16     27     16     0  0.000   0.000 16000.",
            " * sys.peer, # selected, + candidate, - outlyer, x falseticker, ~ configured"
        ]
    ]
}

PLAY RECAP **************************************************************************************************************************************************
America                    : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
Asia                       : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
London                     : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
Manchester                 : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
R1                         : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
R2                         : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
R3                         : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
R4                         : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Next Steps

With this lab complete, we are well on our way to mastering network automation with Ansible. In the next lessons, we’ll add users and device hardening, building a robust, automated network environment and you can always follow the IP addressing and Loopback post incase you missed it.

1 thought on “Ansible Lab 04 Automating Server Configuration and Routers NTP”

  1. Pingback: Workbook 05 Ansible Configuration for Cisco and Juniper Loops and With Statements - RichardKilleen

Leave a Reply

Your email address will not be published. Required fields are marked *