How to Use Ansible set_fact to Define and Modify Facts

Ansible set_fact

Table of Contents

Get up to 50% off now

Become a partner with CyberPanel and gain access to an incredible offer of up to 50% off on CyberPanel add-ons. Plus, as a partner, you’ll also benefit from comprehensive marketing support and a whole lot more. Join us on this journey today!

In Ansible, facts are automatically gathered information pieces about the system that you are managing. These details generally include IP addresses, OS types, memory, disk size, and more. Facts act as the foundation for writing dynamic and responsive automation codes. 

But instead of hardcoding values, you can make these variable decisions based on facts, enabling the playbooks to adapt to different environments, operating systems, and the infrastructure configurations. 

There are two main types of facts in Ansible:

  • Automatically gathered facts: Collected by the setup module when a playbook runs.
  • User-defined facts: Created manually using tools like Ansible set_fact to store custom data during playbook execution.

In this guide, we shall walk through the basics of Ansible set_fact!

What Is Ansible set_fact

Ansible set_fact is a module that allows you to define variables, called facts, dynamically during playbook execution. Unlike variables defined in inventory files or playbooks, Ansible set_fact lets you assign values based on development conditions, task outputs, or other logic as the playbook runs. 

These user-defined Ansible set_fact are stored temporarily for the duration of the playbook and are used like other regular variables. They are especially helpful for: 

Tech Delivered to Your Inbox!

Get exclusive access to all things tech-savvy, and be the first to receive 

the latest updates directly in your inbox.

  • Storing intermediate results between tasks
  • Creating conditional logic
  • Simplifying complex expressions or control structures

For example:

– name: Set a dynamic fact

  ansible.builtin.set_fact:

    deploy_path: “/var/www/{{ inventory_hostname }}”

The above example, shows the deploy_path variable generated on the fly, allowing more flexible automation tailored to each host.

Basic Syntax of Ansible set_fact

The Ansible set_fact is used in a task within your playbook and follows a straightforward syntax. Here’s the basic structure:

– name: Set a fact

  ansible.builtin.set_fact:

    variable_name: value

Enhance Your CyerPanel Experience Today!
Discover a world of enhanced features and show your support for our ongoing development with CyberPanel add-ons. Elevate your experience today!

  • Example 1: Set a simple key-value pair

– name: Set custom greeting

  ansible.builtin.set_fact:

    greeting: “Hello, Ansible!”

This creates a variable named greeting with the value “Hello, Ansible!” that can be used in later tasks.

  • Example 2: Use Jinja2 expressions

– name: Create a path using inventory hostname

  ansible.builtin.set_fact:

    full_path: “/opt/apps/{{ inventory_hostname }}”

Here, the fact is calculated dynamically using a Jinja2 expression.

  • Example 3: Set multiple facts at once

– name: Set multiple facts

  ansible.builtin.set_fact:

    user_name: “admin”

    user_shell: “/bin/bash”

Understanding the Difference: set_fact vs. ansible_facts

Featureset_factansible_facts
DefinitionModule used to define custom variables dynamicallyDictionary that stores automatically gathered facts
ScopeRuntime-specific, per hostAutomatically collected and host-specific
PersistenceTemporary (during playbook execution)Temporary unless manually saved
How It’s CreatedExplicitly with set_factCollected via the setup module
CustomizationFully user-definedMostly system-generated
ModifiableYesNot directly editable (without override methods)
Use CaseStore task output, conditional values, custom logicReference system info like IP, OS, CPU, etc.
Syntax Exampleset_fact: my_var: “value”Accessed as ansible_facts[‘default_ipv4’]

Using Ansible set_fact in Playbooks

The Ansible set_fact module is one of the most commonly used playbooks to define dynamic values and store intermediate results. Here is how you can integrate Ansible set_fact effectively within your playbooks. 

Basic Usage in a Playbook

– name: Example Playbook Using set_fact

  hosts: all

  tasks:

   – name: Set a static custom fact

      ansible.builtin.set_fact:

        app_path: “/opt/myapp”

    – name: Display the custom fact

      debug:

        msg: “The application path is {{ app_path }}”

Using Output from a Previous Task

Using the output from the previous task, you can register it and then use Ansible set_fact to extract and process the value. 

– name: Get system uptime

  command: uptime

  register: uptime_result

– name: Save the uptime output as a fact

  ansible.builtin.set_fact:

    system_uptime: “{{ uptime_result.stdout }}”

Conditionally Set a Fact

– name: Set fact only if a condition is met

  ansible.builtin.set_fact:

    status: “active”

  when: ansible_os_family == “Debian”

Using set_fact with Loops

– name: Set dynamic fact inside a loop

  ansible.builtin.set_fact:

    port_{{ item }}: “{{ 8000 + item }}”

  loop: [1, 2, 3]

This would result with facts like port_1, port_2, and port_3 being created with values 8001, 8002, and 8003. 

Dynamic Variables with set_fact

Ansible set_fact is quite powerful when you need to define variables dynamically at runtime. 

Example: Use with Conditions

– name: Set environment based on hostname

  ansible.builtin.set_fact:

    env: “production”

  when: “‘prod’ in inventory_hostname”

Example: Use in Loops

– name: Set dynamic ports

  ansible.builtin.set_fact:

    “app_port_{{ item }}”: “{{ 8000 + item }}”

  loop: [1, 2, 3]

These facts become:
app_port_1 = 8001, app_port_2 = 8002, etc.

Overriding Existing Facts

Using Ansible set_fact, you can easily override previously defined facts. Here is an intermediate example:

Example: Override a system fact

– name: Override ansible_hostname

  ansible.builtin.set_fact:

    ansible_hostname: “custom-host”

Persisting Facts Across Plays and Runs

By default, Ansible set_fact variables are usually only available during the current playbook run. If you want to persist them across plays or even different runs, you can make sure of fact caching. 

Enable Fact Caching

In ansible.cfg:

[defaults]

fact_caching = jsonfile

fact_caching_connection = /tmp/ansible_facts

Mark Facts as Cacheable

– name: Set a persistent fact

  ansible.builtin.set_fact:

    my_cached_fact: “persistent value”

  cacheable: yes

Use Cases for Ansible set_fact

The Ansible set_fact module is extremely useful for managing dynamic values throughout your playbooks. Here are some of the use cases that will help you out understand them better: 

  1. Store Calculated Values

You can use Ansible set_fact to save results of expressions, task outputs, or runtime calculations. 

Example:

– name: Calculate total disk space in GB

  ansible.builtin.set_fact:

    total_disk_gb: “{{ ansible_facts[‘devices’][‘sda’][‘size’] | int / 1024 }}”

This helps when you need to reuse calculated values in multiple places.

  1. Simplify Complex Conditionals

You can store values that are used repeatedly. 

Example:

– name: Determine if the host is a production server

  ansible.builtin.set_fact:

    is_production: “{{ ‘prod’ in inventory_hostname }}”

Then use it cleanly later:

– name: Restart service in production

  ansible.builtin.service:

    name: myapp

    state: restarted

  when: is_production

  1. Control Flow Between Tasks

You can store an output from one task and use it to make important decisions. 

Example:

– name: Check if file exists

  ansible.builtin.stat:

    path: /etc/myapp/config.yml

  register: file_check

– name: Set config_exists variable

  ansible.builtin.set_fact:

    config_exists: “{{ file_check.stat.exists }}”

Later in the play:

– name: Load configuration if present

  ansible.builtin.include_tasks: config_setup.yml

  when: config_exists

Related Article: Ansible Cheat Sheet: A 2025 Complete Guide for Effective Automation

Common Mistakes and Troubleshooting

Even though Ansible set_fact is pretty easy to use, sometimes a few common issues can cause trouble. Here are the most common mistakes and a how-to guide to resolve them. 

MistakeProblemFix
Referencing set_factvariables too earlyVariables set with set_fact are only available after the task that defines them runs.Ensure that any task referencing the fact comes after the set_fact task in the playbook.
Incorrect variable name or syntaxTypos or incorrect syntax (e.g., missing curly braces) when referencing variables.Always use the format {{ variable_name }} and double-check names.
Overwriting critical facts unintentionallyUsing set_fact to override built-in facts like ansible_hostname may cause issues.Avoid using names of built-in Ansible facts for custom facts unless intentionally overriding.
Using set_fact inside a loop without unique keysIn a loop, the fact gets overwritten in each iteration.Use a list or dictionary to store each iteration’s result uniquely.
Expecting set_fact to persist across plays by defaultset_fact facts are temporary and do not persist across plays or runs.Add cacheable: true to make facts persist:yaml<br>- name: Set a persistent fact<br> ansible.builtin.set_fact:<br> deployment_env: “staging”<br> cacheable: true<br>

Wrapping Up – Ansible set_fact

Ansible set_fact is one of the most easy and straightforward tools out there that must be a part of your routine. Following and understanding this guide will enable you to easily navigate through facts and troubleshoot common issues.

How is set_fact different from variables defined in vars or defaults?

Variables in vars or defaults are static, defined before playbook execution.
set_fact defines variables dynamically during runtime, based on task results or conditions.

Can I override an existing variable with set_fact?

Yes, set_fact can overwrite previously defined variables by assigning them new values during execution.

How do I set multiple facts at once in Ansible?

You can define multiple facts in one set_fact task:
- set_fact: var1: "value1" var2: "value2"

Marium Fahim
Hi! I am Marium, and I am a full-time content marketer fueled by an iced coffee. I mainly write about tech, and I absolutely love doing opinion-based pieces. Hit me up at [email protected].
Unlock Benefits

Become a Community Member

SIMPLIFY SETUP, MAXIMIZE EFFICIENCY!
Setting up CyberPanel is a breeze. We’ll handle the installation so you can concentrate on your website. Start now for a secure, stable, and blazing-fast performance!