Search This Blog

Sunday, 7 February 2021

Facts and Magic variables

 With Ansible you can retrieve or discover certain variables containing information about your remote systems or about Ansible itself. Variables related to remote systems are called facts. With facts, you can use the behavior or state of one system as configuration on other systems. For example, you can use the IP address of one system as a configuration value on another system. Variables related to Ansible are called magic variables

Ansible facts

Ansible facts are data related to your remote systems, including operating systems, IP addresses, attached filesystems, and more. You can access this data in the ansible_facts variable. By default, you can also access some Ansible facts as top-level variables with the ansible_ prefix. You can disable this behavior using the INJECT_FACTS_AS_VARS setting. 

To see all available facts, add this task to a play:

[osboxes@master ansible-new]$ ansible all -m setup


out put is saved at above link

[osboxes@master ansible-new]$ ansible all -m setup -a "filter=ansible_nodename"
databasehost | SUCCESS => {
    "ansible_facts": {
        "ansible_nodename": "databasehost",
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false
}

Package requirements for fact gathering

On some distros, you may see missing fact values or facts set to default values because the packages that support gathering those facts are not installed by default. You can install the necessary packages on your remote hosts using the OS package manager. Known dependencies include:

Linux Network fact gathering - Depends on the ip binary, commonly included in the iproute2 package.

Caching facts

Like registered variables, facts are stored in memory by default. However, unlike registered variables, facts can be gathered independently and cached for repeated use. With cached facts, you can refer to facts from one system when configuring a second system, even if Ansible executes the current play on the second system first. For example:

{{ hostvars['asdf.example.com']['ansible_facts']['os_family'] }}

Caching is controlled by the cache plugins. By default, Ansible uses the memory cache plugin, which stores facts in memory for the duration of the current playbook run. To retain Ansible facts for repeated use, select a different cache plugin. 

Fact caching can improve performance. If you manage thousands of hosts, you can configure fact caching to run nightly, then manage configuration on a smaller set of servers periodically throughout the day. With cached facts, you have access to variables and information about all hosts even when you are only managing a small number of servers.

Disabling facts

By default, Ansible gathers facts at the beginning of each play. If you do not need to gather facts (for example, if you know everything about your systems centrally), you can turn off fact gathering at the play level to improve scalability. Disabling facts may particularly improve performance in push mode with very large numbers of systems, or if you are using Ansible on experimental platforms. To disable fact gathering:

- hosts: whatever
  gather_facts: no

Adding Custom facts

The setup module in Ansible automatically discovers a standard set of facts about each host. If you want to add custom values to your facts, you can write a custom facts module, set temporary facts with a ansible.builtin.set_fact task, or provide permanent custom facts using the facts.d directory.

Ansible magic variables

You can access information about Ansible operations, including the python version being used, the hosts and groups in inventory, and the directories for playbooks and roles, using “magic” variables. Like connection variables, magic variables are Special Variables. Magic variable names are reserved - do not set variables with these names. The variable environment is also reserved.

The most commonly used magic variables are hostvars, groups, group_names, and inventory_hostname. With hostvars, you can access variables defined for any host in the play, at any point in a playbook. You can access Ansible facts using the hostvars variable too, but only after you have gathered (or cached) facts.

If you want to configure your database server using the value of a ‘fact’ from another node, or the value of an inventory variable assigned to another node, you can use hostvars in a template or on an action line:

{{ hostvars['test.example.com']['ansible_facts']['distribution'] }}

With groups, a list of all the groups (and hosts) in the inventory, you can enumerate all hosts within a group. For example:

{% for host in groups['app_servers'] %}

   # something that applies to all app servers.

{% endfor %}

You can use groups and hostvars together to find all the IP addresses in a group.

{% for host in groups['app_servers'] %}

   {{ hostvars[host]['ansible_facts']['eth0']['ipv4']['address'] }}

{% endfor %}

 You can use this approach to point a frontend proxy server to all the hosts in your app servers group, to set up the correct firewall rules between servers, and so on. You must either cache facts or gather facts for those hosts before the task that fills out the template.

With group_names, a list (array) of all the groups the current host is in, you can create templated files that vary based on the group membership (or role) of the host:

{% if 'webserver' in group_names %}

   # some part of a configuration file that only applies to webservers

{% endif %}

You can use the magic variable inventory_hostname, the name of the host as configured in your inventory, as an alternative to ansible_hostname when fact-gathering is disabled. If you have a long FQDN, you can use inventory_hostname_short, which contains the part up to the first period, without the rest of the domain.