13.4 set_fact & Cached Facts 🔄
set_fact — Runtime μεταβλητές
Το set_fact σου επιτρέπει να ορίσεις νέα facts κατά την εκτέλεση του playbook — δυναμικά, βάσει άλλων facts ή υπολογισμών.
# Βασική χρήση
- name: Ορισμός fact
ansible.builtin.set_fact:
my_fact: "my_value"
# Χρήση αργότερα
- name: Χρήση fact
ansible.builtin.debug:
msg: "{{ my_fact }}"
set_fact — Απλά παραδείγματα
tasks:
# ── Απλοί ορισμοί ─────────────────────────
- name: Ορισμός απλών facts
ansible.builtin.set_fact:
app_version: "2.1.4"
deploy_date: "{{ ansible_facts['date_time']['date'] }}"
is_production: "{{ app_env == 'production' }}"
# ── Υπολογισμοί βάσει built-in facts ──────
- name: Υπολογισμός performance facts
ansible.builtin.set_fact:
nginx_workers: "{{ ansible_facts['processor_vcpus'] | int }}"
php_memory_limit: "{{ (ansible_facts['memtotal_mb'] * 0.25) | int }}M"
db_connections: "{{ (ansible_facts['memtotal_mb'] / 10) | int | min(200) }}"
ram_gb: "{{ (ansible_facts['memtotal_mb'] / 1024) | round(1) }}"
# ── Conditional facts ─────────────────────
- name: Ορισμός service name βάσει OS
ansible.builtin.set_fact:
web_service: >-
{{ 'apache2'
if ansible_facts['os_family'] == 'Debian'
else 'httpd' }}
# ── Facts από register ────────────────────
- name: Έλεγχος nginx version
ansible.builtin.command:
cmd: nginx -v
register: nginx_output
changed_when: false
ignore_errors: true
- name: Αποθήκευση nginx version
ansible.builtin.set_fact:
nginx_version: >-
{{ nginx_output.stderr
| regex_search('nginx/([0-9.]+)', '\\1')
| first
| default('not_installed') }}
- name: Εμφάνιση version
ansible.builtin.debug:
msg: "Nginx: {{ nginx_version }}"
set_fact με cacheable
Κανονικά τα set_fact facts χάνονται όταν τελειώσει το play. Με cacheable: true αποθηκεύονται για επόμενες εκτελέσεις:
tasks:
- name: Cacheable fact
ansible.builtin.set_fact:
app_version: "2.1.4"
deploy_commit: "abc123def"
cacheable: true # ← αποθηκεύεται στο cache!
Facts Caching — Αποθήκευση Facts
Η Ansible μπορεί να αποθηκεύει facts για να τα χρησιμοποιεί αργότερα χωρίς να τρέχει ξανά το setup module:
# ansible.cfg — ρύθμιση caching
[defaults]
# ── Ενεργοποίηση cache ────────────────────────
fact_caching = jsonfile # backend
fact_caching_connection = /tmp/ansible_facts_cache
fact_caching_timeout = 3600 # seconds (1 ώρα)
Διαθέσιμα Cache Backends:
┌─────────────────────────────────────────────────────────┐
│ memory → default, χάνεται μετά την εκτέλεση │
│ jsonfile → αρχεία JSON στο δίσκο ✅ │
│ yaml → αρχεία YAML στο δίσκο │
│ redis → Redis server (για production) │
│ memcached → Memcached server │
└─────────────────────────────────────────────────────────┘
jsonfile Cache — Πρακτικό παράδειγμα
# Ρύθμιση cache directory
mkdir -p /tmp/ansible_facts_cache
chmod 700 /tmp/ansible_facts_cache
# ansible.cfg
[defaults]
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts_cache
fact_caching_timeout = 86400 # 24 ώρες
# 1η εκτέλεση — συλλέγει και αποθηκεύει facts
ansible-playbook playbooks/myplaybook.yml
# TASK [Gathering Facts] → ~2 δευτερόλεπτα
# Δες τα cached facts
ls /tmp/ansible_facts_cache/
# nextcloud ← αρχείο με facts του server
cat /tmp/ansible_facts_cache/nextcloud | python3 -m json.tool | head -20
# {
# "ansible_architecture": "x86_64",
# "ansible_distribution": "Debian",
# ...
# }
# 2η εκτέλεση — χρησιμοποιεί cache!
ansible-playbook playbooks/myplaybook.yml
# TASK [Gathering Facts] → <0.1 δευτερόλεπτα ✅
Facts Caching — Πλήρες παράδειγμα
---
# facts-caching-demo.yml
- name: Facts Caching Demo
hosts: all
become: true
gather_facts: true # ← χρησιμοποιεί cache αν υπάρχει
tasks:
# ── Υπολογισμός & caching facts ───────────
- name: Υπολογισμός performance facts
ansible.builtin.set_fact:
# Performance calculations
nginx_workers: "{{ ansible_facts['processor_vcpus'] | int }}"
php_memory: "{{ (ansible_facts['memtotal_mb'] * 0.25) | int }}M"
mysql_buffer_pool: "{{ (ansible_facts['memtotal_mb'] * 0.50) | int }}M"
redis_maxmemory: "{{ (ansible_facts['memtotal_mb'] * 0.20) | int }}mb"
# System profile
server_profile: >-
{%- if ansible_facts['memtotal_mb'] | int >= 8192 -%}
high_performance
{%- elif ansible_facts['memtotal_mb'] | int >= 4096 -%}
standard
{%- elif ansible_facts['memtotal_mb'] | int >= 2048 -%}
low_memory
{%- else -%}
minimal
{%- endif -%}
# Deploy metadata
last_configured: "{{ ansible_facts['date_time']['iso8601'] }}"
cacheable: true # ← αποθήκευσε στο cache!
# ── Εμφάνιση ──────────────────────────────
- name: Performance profile
ansible.builtin.debug:
msg:
- "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
- "Server Profile: {{ server_profile }}"
- "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
- "Nginx workers : {{ nginx_workers }}"
- "PHP memory : {{ php_memory }}"
- "MySQL buffer : {{ mysql_buffer_pool }}"
- "Redis memory : {{ redis_maxmemory }}"
- "Configured at : {{ last_configured }}"
- "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# ── Χρήση σε templates ────────────────────
- name: Deploy performance config
ansible.builtin.copy:
dest: /etc/myapp/performance.conf
mode: '0644'
content: |
# Performance Configuration
# Profile: {{ server_profile }}
# Generated: {{ last_configured }}
[nginx]
worker_processes = {{ nginx_workers }}
[php]
memory_limit = {{ php_memory }}
[mysql]
innodb_buffer_pool_size = {{ mysql_buffer_pool }}
[redis]
maxmemory = {{ redis_maxmemory }}
Χρήση Cached Facts από άλλο Play
---
# Το μεγάλο πλεονέκτημα του caching:
# Play 1 συλλέγει facts → Play 2 τα χρησιμοποιεί
# χωρίς να συνδεθεί ξανά στον server!
- name: Play 1 — Συλλογή Facts
hosts: all
gather_facts: true
tasks:
- name: Cache performance facts
ansible.builtin.set_fact:
server_profile: "high_performance"
nginx_workers: "{{ ansible_facts['processor_vcpus'] }}"
cacheable: true
# ── Αργότερα — ξεχωριστό playbook ────────────
- name: Play 2 — Χρήση Cached Facts
hosts: all
gather_facts: false # ← ΔΕΝ τρέχει setup module!
# Διαβάζει από cache! ✅
tasks:
- name: Χρησιμοποίησε cached facts
ansible.builtin.debug:
msg:
- "Profile : {{ server_profile }}"
- "Workers : {{ nginx_workers }}"
- "RAM : {{ ansible_facts['memtotal_mb'] }}"
# ↑ Από cache, όχι από live server!
Καθαρισμός Cache
# Καθαρισμός cache για συγκεκριμένο server
rm /tmp/ansible_facts_cache/nextcloud
# Καθαρισμός όλου του cache
rm -rf /tmp/ansible_facts_cache/*
# Εξαναγκασμός ανανέωσης (αγνόησε cache)
ansible-playbook playbooks/myplaybook.yml \
--flush-cache
set_fact vs vars — Διαφορές
# ── vars: → ορίζονται ΠΡΙΝ την εκτέλεση ──────
vars:
my_var: "static_value"
# ← γνωστό από την αρχή
# ── set_fact → ορίζεται ΚΑΤΑ την εκτέλεση ────
tasks:
- name: Dynamic fact
ansible.builtin.set_fact:
my_fact: "{{ register_result.stdout }}"
# ← εξαρτάται από αποτέλεσμα task!
# ── Βασική διαφορά ────────────────────────────
# vars → static, ορίζονται εκ των προτέρων
# set_fact→ dynamic, υπολογίζονται κατά εκτέλεση
# μπορούν να χρησιμοποιούν register results
# μπορούν να χρησιμοποιούν runtime data
# διαθέσιμα σε ΟΛΟΥΣ τους hosts (με hostvars)
set_fact μεταξύ Hosts
# Ειδική δυνατότητα: set_fact ενός host
# είναι προσβάσιμο από ΑΛΛΟ host μέσω hostvars!
- name: Play 1 — Server A sets fact
hosts: server_a
tasks:
- name: Set fact
ansible.builtin.set_fact:
my_ip: "{{ ansible_facts['default_ipv4']['address'] }}"
cacheable: true
- name: Play 2 — Server B χρησιμοποιεί fact του Server A
hosts: server_b
tasks:
- name: Χρήση fact από server_a
ansible.builtin.debug:
msg: "Server A IP: {{ hostvars['server_a']['my_ip'] }}"
# ↑ hostvars → πρόσβαση σε facts άλλων hosts!
Σύνοψη 13.4
set_fact & Cached Facts
├── set_fact:
│ ├── Ορισμός facts κατά εκτέλεση
│ ├── Δυναμικοί υπολογισμοί
│ ├── Βάσει register results
│ └── cacheable: true → αποθήκευση στο cache
│
├── Facts Caching:
│ ├── ansible.cfg: fact_caching = jsonfile
│ ├── fact_caching_connection = /tmp/cache
│ ├── fact_caching_timeout = 3600
│ └── --flush-cache → καθαρισμός
│
├── Cache Backends:
│ ├── memory → default (χάνεται)
│ ├── jsonfile → αρχεία JSON ✅
│ └── redis → για production
│
└── set_fact vs vars:
├── vars → static, πριν εκτέλεση
└── set_fact → dynamic, κατά εκτέλεση