Chrony is a versatile implementation of the Network Time Protocol (NTP) designed for Unix-like operating systems. It consists of two main components: chronyd (a background daemon) and chronyc (a command-line interface for monitoring and performance tuning).
In enterprise server fleets and cloud infrastructures, accurate system time synchronization across distributed nodes is critical for:
yum ModuleAnsible provides the built-in ansible.builtin.yum module (or ansible.builtin.dnf on modern RHEL/CentOS systems) to manage RPM software packages on Red Hat Enterprise Linux and derivatives.
Key advantages of using Ansible’s yum module include:
changed: false.state parameter defines the target operational state:
present / installed: Ensures the package is installed (installs if missing; leaves existing version intact).latest: Ensures the package is installed and upgraded to the newest version available in enabled repositories.absent / removed: Ensures the package is completely uninstalled from the remote target node.yum package manager, automatically installing required library dependencies.Installing software packages on Linux requires root privileges. In Ansible playbooks, privilege escalation is enabled at the play level via become: yes. When validation or CI/CD pipelines run ansible-playbook -i inventory playbook.yml without passing interactive password flags (-k or -K), all target host credentials (ansible_user, ansible_ssh_pass, ansible_become_pass) must be explicitly defined in the inventory file.
graph TD
subgraph ControlNode ["Jump Host (Ansible Controller)"]
ThorUser["User: thor"]
InvFile["Inventory File<br/>/home/thor/playbook/inventory"]
PlaybookFile["Playbook File<br/>/home/thor/playbook/playbook.yml"]
AnsibleCLI["Ansible Engine<br/>ansible-playbook -i inventory playbook.yml"]
end
subgraph StratosDC ["Stratos Datacenter (Managed App Servers)"]
subgraph AppServers ["Inventory Group: [app_servers]"]
App1["stapp01<br/>User: tony"]
App2["stapp02<br/>User: steve"]
App3["stapp03<br/>User: banner"]
end
end
InvFile -->|"Supply Hosts & Auth Parameters"| AnsibleCLI
PlaybookFile -->|"Supply Play & Tasks (yum: name=chrony)"| AnsibleCLI
AnsibleCLI -->|"SSH + sudo yum install chrony"| App1
AnsibleCLI -->|"SSH + sudo yum install chrony"| App2
AnsibleCLI -->|"SSH + sudo yum install chrony"| App3
App1 -->|"Package Installed (changed: true)"| AnsibleCLI
App2 -->|"Package Installed (changed: true)"| AnsibleCLI
App3 -->|"Package Installed (changed: true)"| AnsibleCLI
playbook.yml)An Ansible playbook is written in YAML format. Key directives for package installation include:
---
- name: Install Chrony Package on All App Servers
hosts: app_servers
become: yes
tasks:
- name: Install chrony package using yum module
ansible.builtin.yum:
name: chrony
state: present
hosts: app_servers: Specifies the target group of managed nodes from the inventory file.become: yes: Instructs Ansible to execute tasks using privilege escalation (sudo root).ansible.builtin.yum: The core package management module.name: chrony: The exact RPM package name to be managed.state: present: Ensures the package is installed on the target machine.| Host Role | Hostname / Alias | SSH User | User Password | Sudo Password | Target Package |
|---|---|---|---|---|---|
| Ansible Controller | jump_host |
thor |
Native | N/A | N/A |
| App Server 1 | stapp01 |
tony |
Ir0nM@n |
Ir0nM@n |
chrony |
| App Server 2 | stapp02 |
steve |
Am3ric@ |
Am3ric@ |
chrony |
| App Server 3 | stapp03 |
banner |
BigGr33n |
BigGr33n |
chrony |
/home/thor/playbook/inventory/home/thor/playbook/playbook.ymlapp_servers containing stapp01, stapp02, and stapp03chronyansible.builtin.yum (or yum)ansible-playbook -i inventory playbook.yml
Log in to the Jump Host as user thor:
ssh thor@jump_host
Create the target directory /home/thor/playbook if it does not already exist, and change your working directory:
mkdir -p /home/thor/playbook
cd /home/thor/playbook
Create the inventory file /home/thor/playbook/inventory with all three application servers and their connection credentials:
cat << 'EOF' > /home/thor/playbook/inventory
[app_servers]
stapp01 ansible_host=stapp01 ansible_user=tony ansible_ssh_pass=Ir0nM@n ansible_become_pass=Ir0nM@n
stapp02 ansible_host=stapp02 ansible_user=steve ansible_ssh_pass=Am3ric@ ansible_become_pass=Am3ric@
stapp03 ansible_host=stapp03 ansible_user=banner ansible_ssh_pass=BigGr33n ansible_become_pass=BigGr33n
EOF
(Note: If password-less SSH authentication and password-less sudo are already configured across the cluster, simple host entries stapp01, stapp02, stapp03 under [app_servers] can be used).
Test Ansible connectivity to all app servers using the ping module:
ansible -i /home/thor/playbook/inventory app_servers -m ping
Expected Output: Each server returns "ping": "pong" with SUCCESS.
Create the /home/thor/playbook/playbook.yml file using cat or vi:
cat << 'EOF' > /home/thor/playbook/playbook.yml
---
- name: Install Chrony Package on All App Servers
hosts: app_servers
become: yes
tasks:
- name: Install chrony package using yum module
ansible.builtin.yum:
name: chrony
state: present
EOF
Before running the playbook, verify that there are no syntax or formatting errors in the YAML file:
ansible-playbook -i inventory playbook.yml --syntax-check
Expected Output:
playbook: playbook.yml
Run the playbook using the standard non-interactive command required for validation:
cd /home/thor/playbook
ansible-playbook -i inventory playbook.yml
Upon successful execution, the terminal will display the execution recap:
PLAY [Install Chrony Package on All App Servers] *************************************************
TASK [Gathering Facts] ***************************************************************************
ok: [stapp01]
ok: [stapp02]
ok: [stapp03]
TASK [Install chrony package using yum module] ***************************************************
changed: [stapp01]
changed: [stapp02]
changed: [stapp03]
PLAY RECAP ***************************************************************************************
stapp01 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
stapp02 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
stapp03 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Run an ad-hoc shell command using Ansible to confirm chrony is installed on all target servers:
ansible -i inventory app_servers -m shell -a "rpm -q chrony"
Expected Output:
stapp01 | CHANGED | rc=0 >>
chrony-3.5-3.el7.x86_64
stapp02 | CHANGED | rc=0 >>
chrony-3.5-3.el7.x86_64
stapp03 | CHANGED | rc=0 >>
chrony-3.5-3.el7.x86_64
| Issue / Error | Root Cause | Resolution |
|---|---|---|
Permission denied: /var/run/yum.pid |
The task attempted package installation without root privileges. | Add become: yes to the play header in playbook.yml. |
Missing sudo password / sudo: a password is required |
Ansible attempted become: yes but no sudo password was provided for non-passwordless sudo users. |
Add ansible_become_pass parameter to each host entry in inventory or configure NOPASSWD in /etc/sudoers. |
SyntaxError: unexpected token |
Improper YAML indentation or tabs instead of spaces. | Use 2-space indentation and check syntax with ansible-playbook -i inventory playbook.yml --syntax-check. |
No package chrony available |
YUM repository cache is outdated or repository is unreachable. | Add update_cache: yes to the yum module parameters or verify network/repo connectivity. |
ansible.builtin.yum over short yum module names to adhere to modern Ansible standards.become: yes at the play or task level when performing administrative actions like package management.ansible-playbook -i inventory playbook.yml a second time. The second run should return changed=0 for all tasks, proving idempotency.