ansible: difference between a variable and a fact

6,576

Solution 1

Ansible facts are data collected about the (target) systems on which Ansible takes actions. They are variables, but set by Ansible (in a way like system defined variables). They are collected during Gathering Facts stage of a playbook run, and it is controlled by the gather_facts setting. Ansible calls this variables discovered from systems. That said, it is possible to set custom facts also.

Some examples are:

  • ansible_hostname - the FQDN of the target system
  • ansible_os_family - the Operating System family of target system (RedHat, Debian, etc.)

The other variables are the ones we can set as per our requirement (in a way like user defined variables).

Some examples are:

  • my_fav_fruits: [ 'orange', 'apple', 'banana' ] - yours might differ.
  • config_dir: '/etc/my_app/conf.d' - for my application configuration files.

Update:

Updating answer to make it relevant to the edit(s) made in question.

As @Bruce Becker's answer rightly pointed out, there is a difference in the precedence of variables set with set_fact. Also variables that need to be set at "run time" can be set this way. Without further explanation, taking your example variables, if I create a play like below:

- hosts: localhost
  vars:
    nginx_ssl: '/etc/nginx/ssl'
    nginx_conf_file: '/etc/nginx/nginx.conf'

  tasks:
  - name: set nginx path to /opt when running on Debian
    set_fact:
      nginx_ssl: '/opt/nginx/ssl'
      nginx_conf_file: '/opt/nginx/nginx.conf'
    when: ansible_distribution == 'Debian'
  - debug:
      msg: 'ssl: {{ nginx_ssl }} and conf: {{ nginx_conf_file }}'

Then the set_fact variables will take precedence (on Debian) and output will be:

"msg": "ssl: /opt/nginx/ssl and conf: /opt/nginx/nginx.conf"

On other distributions, it will be what was declared in vars:.

Solution 2

Not to contradict anything written in @Ceshadri_C's answer, but to focus more on the difference between facts and variables - perhaps the variable precedence page could be of greater insight.

The difference between facts and variables set is defined by their precedence, i.e. all variables are important, but some variables are more important than others. In your case, the same variable set as a fact (priority 19) would take precedence declared as a variable in a task (priority 17) or play (priority 12).

Share:
6,576
Baptiste Mille-Mathias
Author by

Baptiste Mille-Mathias

I'm a versatile Kubernetes / Linux / Automation Engineer by day. I automate stuff, run production services, monitor them, correct, improve and sometimes I also break things. And so forth. I've a strong experience in operations, having managed critical systems with important traffic. I try to upvote as much as I can answers and questions. I do some fields mapping in Openstreetmap and Mapillary -- jack of all trades, master of none

Updated on September 18, 2022

Comments

  • Baptiste Mille-Mathias
    Baptiste Mille-Mathias over 1 year

    While I'm using Ansible for quite some time, I'm not sure I really understand the differences between a variable and a fact.

    Would it be any difference doing

    - set_fact:
        nginx_ssl: /etc/nginx/ssl
        nginx_conf_file: /etc/nginx/nginx.conf
    

    or

      vars:
        nginx_ssl: /etc/nginx/ssl
        nginx_conf_file: /etc/nginx/nginx.conf
    

    Could someone explain me, possibly with an example where it really make a difference ?

  • seshadri_c
    seshadri_c over 3 years
    Understood the context now. I updated my answer too.
  • Pozinux
    Pozinux about 2 years
    "On other distributions, it will be what was declared in vars:." I don't understand this statement. Why whould it be different on other distributions like Redhat for example?
  • seshadri_c
    seshadri_c about 2 years
    The vars declared in the vars: section of the play have lower precedence than set_fact, so it will be what was declared under vars:, unless it is overridden with set_fact again for Redhat,