---
- name: Calculate time drift from reference
set_fact:
time_drift_seconds: |
{% if time_reference is defined %}
{% set ref_time = time_reference | to_datetime('%Y-%m-%dT%H:%M:%SZ') %}
{% set node_time = node_result.current_time | to_datetime('%Y-%m-%dT%H:%M:%SZ') %}
{{ (node_time - ref_time).total_seconds() }}
{% else %}
0
{% endif %}
- name: Determine time correction strategy
set_fact:
time_correction_needed: "{{ (time_drift_seconds | float | abs) > max_time_drift_seconds }}"
drift_level: |
{% set drift = time_drift_seconds | float | abs %}
{% if drift > 300 %}
CRITICAL
{% elif drift > 60 %}
HIGH
{% elif drift > 30 %}
MODERATE
{% else %}
MINOR
{% endif %}
- name: Display time analysis
debug:
msg: |
🕐 TIME DRIFT ANALYSIS - {{ inventory_hostname }}
================================================
Current Time: {{ node_result.current_time }}
Reference Time: {{ time_reference | default('N/A') }}
Time Drift: {{ time_drift_seconds | float | round(2) }}s
Drift Level: {{ drift_level }}
Correction Needed: {{ time_correction_needed }}
NTP Synchronized: {{ node_result.ntp.ntp_synchronized }}
Active NTP Service: {{ node_result.ntp.active_service }}
- name: Fix NTP synchronization issues
block:
- name: Install chrony if no time service is available
package:
name: chrony
state: present
when: node_result.ntp.active_service == 'none'
register: chrony_installed
- name: Configure chrony with reliable NTP servers
copy:
content: |
# Chrony configuration
# Generated by Ansible on {{ ansible_date_time.iso8601 }}
# Host: {{ inventory_hostname }}
pool {{ ntp_server_pool | default('pool.ntp.org') }} iburst
pool 0.pool.ntp.org iburst
pool 1.pool.ntp.org iburst
pool 2.pool.ntp.org iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
minsources 2
{% if ansible_default_ipv4.network is defined %}
allow {{ ansible_default_ipv4.network }}/{{ ansible_default_ipv4.netmask }}
{% endif %}
allow 127.0.0.1
local stratum 10
leapsectz right/UTC
logdir /var/log/chrony
dest: /etc/chrony.conf
backup: yes
when: node_result.ntp.chronyd_exists or chrony_installed.changed | default(false)
register: chrony_config_changed
- name: Start and enable chronyd
systemd:
name: chronyd
state: started
enabled: yes
daemon_reload: yes
when: node_result.ntp.chronyd_exists or chrony_installed.changed | default(false)
register: chronyd_started
- name: Restart chronyd if config changed
systemd:
name: chronyd
state: restarted
when: chrony_config_changed is defined and chrony_config_changed.changed
- name: Force immediate time synchronization (gradual)
command: chrony -q 'server {{ ntp_server_pool }} iburst'
when: time_correction_needed and drift_level in ['MINOR', 'MODERATE']
register: gradual_sync_result
failed_when: false
- name: Force immediate time synchronization (step for critical drift)
block:
- name: Stop chronyd for manual time step
systemd:
name: chronyd
state: stopped
- name: Force time step with chronyd
command: chronyd -q 'server {{ ntp_server_pool }} iburst'
register: step_sync_result
- name: Start chronyd after manual sync
systemd:
name: chronyd
state: started
when: time_correction_needed and drift_level == 'CRITICAL'
- name: Wait for synchronization to stabilize
wait_for:
timeout: 30
when: chronyd_started is changed or gradual_sync_result is defined or step_sync_result is defined
- name: Verify time synchronization after correction
command: timedatectl status
register: time_verify_result
- name: Get updated chrony status
command: chronyc tracking
register: chrony_tracking_updated
failed_when: false
when: node_result.ntp.chronyd_exists or chrony_installed.changed | default(false)
- name: Display time correction results
debug:
msg: |
✅ TIME SYNCHRONIZATION CORRECTION COMPLETED
================================================
Previous Drift: {{ time_drift_seconds | float | round(2) }}s
Correction Method: {{ 'Step' if drift_level == 'CRITICAL' else 'Gradual' }}
Updated Status:
{{ time_verify_result.stdout }}
{% if chrony_tracking_updated.stdout is defined %}
Chrony Tracking:
{{ chrony_tracking_updated.stdout }}
{% endif %}
when: time_correction_needed or not node_result.ntp.ntp_synchronized
- name: Setup time synchronization monitoring
block:
- name: Create time sync monitoring script
copy:
content: |
#!/bin/bash
# Time synchronization monitoring script
# Generated by Ansible on {{ ansible_date_time.iso8601 }}
LOG_FILE="/var/log/time_sync_monitor.log"
MAX_DRIFT=30
TIMEDATECTL_OUTPUT=$(timedatectl status)
NTP_SYNC=$(echo "$TIMEDATECTL_OUTPUT" | grep "NTP synchronized" | awk '{print $3}')
if [[ "$NTP_SYNC" != "yes" ]]; then
echo "$(date): WARNING - NTP not synchronized" >> $LOG_FILE
systemctl restart chronyd
fi
if command -v chronyc &> /dev/null; then
CHRONY_TRACKING=$(chronyc tracking)
OFFSET=$(echo "$CHRONY_TRACKING" | grep "Last offset" | awk '{print $4}')
if [[ $(echo "$OFFSET > $MAX_DRIFT" | bc -l) -eq 1 ]] 2>/dev/null; then
echo "$(date): WARNING - Time offset too large: ${OFFSET}s" >> $LOG_FILE
chrony -q 'server {{ ntp_server_pool }} iburst'
fi
fi
dest: /usr/local/bin/time_sync_monitor.sh
mode: '0755'
- name: Create cron job for time sync monitoring
cron:
name: "Time synchronization monitoring"
minute: "*/15"
job: "/usr/local/bin/time_sync_monitor.sh"
user: root
- name: Create systemd timer for time sync monitoring (alternative)
copy:
content: |
[Unit]
Description=Time Sync Monitor Timer
[Timer]
OnCalendar=*:0/15
Persistent=true
[Install]
WantedBy=timers.target
dest: /etc/systemd/system/time-sync-monitor.timer
- name: Create systemd service for time sync monitoring
copy:
content: |
[Unit]
Description=Time Sync Monitor Service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/time_sync_monitor.sh
User=root
dest: /etc/systemd/system/time-sync-monitor.service
- name: Enable time sync monitoring timer
systemd:
name: time-sync-monitor.timer
enabled: yes
state: started
daemon_reload: yes
when: time_correction_needed or (node_result.ntp.ntp_synchronized | default(false)) == false
- name: Generate time sync recommendations
set_fact:
time_recommendations: |
{% set drift = time_drift_seconds | float | abs %}
{% if drift > 300 %}
CRITICAL TIME DRIFT ({{ drift | round(2) }}s):
1. 즉시 수동 시간 동기화 수행
2. NTP 서버 연결 상태 확인
3. 방화벽 설정 점검 (UDP 123 포트)
4. 네트워크 연결성 확인
5. 시스템 클럭 하드웨어 점검 권장
{% elif drift > 60 %}
HIGH TIME DRIFT ({{ drift | round(2) }}s):
1. NTP 서비스 재시작 수행
2. 더 가까운 NTP 서버로 변경 고려
3. 정기적인 시간 동기화 모니터링 설정
{% elif drift > 30 %}
MODERATE TIME DRIFT ({{ drift | round(2) }}s):
1. NTP 동기화 강제 수행
2. 시간 동기화 빈도 증가
{% else %}
MINOR TIME DRIFT ({{ drift | round(2) }}s):
1. 정상 범위 내 차이
2. 정기 모니터링 유지
{% endif %}
- name: Display time sync recommendations
debug:
msg: |
================================================
🔧 TIME SYNCHRONIZATION RECOMMENDATIONS
================================================
Host: {{ inventory_hostname }}
{{ time_recommendations }}
추가 점검 사항:
- 네트워크 지연: ping {{ ntp_server_pool }}
- NTP 포트 확인: netstat -ulnp | grep :123
- 시스템 로그: journalctl -u chronyd -f
- 하드웨어 클럭: hwclock --show
when: time_correction_needed