I did not intend to create a new blog on Ansible so fast, but here it comes.
My previous blog
on that topic was a first step in Ansible world. Now, it is time to use some of the advanced features.
Context
We recently had an issue at a customer site, where some of the servers were having time synchronization issues. I discovered that ntp configuration was not the same across all servers which, from my experience. can lead to time drifts. For most of the web application, time is not so important constraint, unless your application used SAML2 Single Sign On mechanism.
My goal, here, is to check ntp status on all servers in one shot.
First playbook
My first attempt was a very basic playbook:
- name: NTP Check
hosts: all
gather_facts: no
tasks:
- name: Run ntpdc -p
shell: /usr/sbin/ntpdc -p
register: output
- name: Display output
debug:
var: output.stdout_lines
I use a variable named output (which is created with
register
option) and display content for each servers of the inventory (
output.stdout_lines
).
I faced an issue on two hosts of my list:
ok: [server-123456] => {
"output.stdout_lines": "VARIABLE IS NOT DEFINED!"
This was due a difference in ntp client. These two hosts run chrony instead of ntpd, which means I have to run different commands depending on the time synchronization client.
Second attempt
I took the easiest way: If /etc/ntp.conf exists, I run ntpdc command. If not, I used the chronyc command. And, finally, display merged result whatever the ntp client.
Playbook becomes:
- name: NTP Check
hosts: all
gather_facts: no
tasks:
- name: Determine ntp client
stat:
path: /etc/ntp.conf
register: ntpd
- name: Run ntpdc -p
shell: /usr/sbin/ntpdc -p
register: output
when: ntpd.stat.exists
- name: Run chronyc
shell: /usr/bin/chronyc sources
register: output
when: not ntpd.stat.exists
- name: Display output
debug:
var: output.stdout_lines
From this playbook, I learn that even if “when” condition is not met, and task will be skipped, output register will be erased for these hosts (and “VARIABLE IS NOT DEFINED!” will be displayed). Which means that output will be populated for my two hosts that use chrony client. Unfortunately, as per
Ansible documentation
, this is the expected behavior:
“If a task fails or is skipped, Ansible still registers a variable with a failure or skipped status, unless the task is skipped based on tags. See Tags for information on adding and using tags.”
tags will not help me here as I want to have all results in same output and in one command.
Third try
As Ansible can manage errors via exception, I wondered if it would be possible to simply run chrony command if ntpdc command fails.
- name: NTP Check
hosts: all
gather_facts: no
tasks:
- name: Run ntpdc -p (block)
block:
- name: Run ntpdc -p
command: /usr/sbin/ntpdc -p
register: output
rescue:
- name: Run chronyc (block)
block:
- name: Run chronyc
command: /usr/bin/chronyc sources
register: output
always:
- name: Display output
debug:
var: output.stdout_lines
If first task block “Run ntpdc” fails, it will jump to
rescue
block and run chronyc block. Then, whatever ntpdc or chronyc block was run,
always
will be run with output always defined.
All servers will have similar output as below:
For a ntp client:
ok: [server-123456] => {
"output.stdout_lines": [
" remote local st poll reach delay offset disp",
"=======================================================================",
"*ntp01 10.10.10.10 1 512 377 0.00047 -0.730333 0.11720",
"=ntp02 10.10.10.11 1 512 377 0.00087 -0.733377 0.11292"
For a chrony client:
ok: [server-456789] => {
"output.stdout_lines": [
"210 Number of sources = 5",
"MS Name/IP address Stratum Poll Reach LastRx Last sample ",
"===============================================================================",
"^* ntp04 1 6 377 38 -14us[ -46us] +/- 233us",
"^- ntp05 3 10 377 388 +7566us[+7585us] +/- 116ms",
"^? ntp06 2 6 377 43 +2947ms[+2947ms] +/- 11.0s",
"^- ntp07 3 10 377 191 -8696us[-8716us] +/- 120ms",
"^? ntp08 2 10 377 999 +2953ms[+2953ms] +/- 11.0s"
Note that for these examples, servers were using different ntp client but also different ntp sources which is what I wanted to check.
What next ?
These are still basic playbooks, but I wrote them in few minutes and they fill a need. It is from needs that come ideas.
Post Views: 2,242
DevOps, Kubernetes
Investigative look into cloud-native hyper-converged infrastructure with Harvester
dbi services is a company specialized in IT consulting and services.
We are experts in innovative and efficient data infrastructures and platforms.
Tailor-made solutions is what we offer to our customers thanks to our consultants, whose skills and knowledge are constantly evolving thanks to continuous training.
We use cookies on our website to provide you with the most relevant experience by remembering your preferences. No personal data is stored. By clicking on "Accept All", you consent to the use of ALL cookies. However, you can visit "Cookie Settings" to provide controlled consent.
Read MoreManage consent