Learn Computing from the Experts | The Rheinwerk Computing Blog

What Are Registered Variables in Ansible?

Written by Rheinwerk Computing | Dec 3, 2025 2:00:02 PM

When you start to familiarize yourself with Ansible, especially in the early phase, you’ll often call Linux commands with command or shell—and later, you’ll realize that using a specific module would have been better.

 

You could have used the file module instead of a mkdir call, the user module instead of a useradd call, the synchronize module instead of a rsync call.

 

But first, you would have to know all of this, and second, there isn’t a module for everything. So now, we should take a look at how command and shell calls behave in the playbook context. Let’s start with a simple example:

 

---

- hosts: debian

  gather_facts: no

 

  tasks:

     - name: Determine space requirements

       command: df -h /

 

$ ansible-playbook command1.yml

 

PLAY [debian] ***************************************************************

 

TASK [Determine space requirements] *****************************************

changed: [debian]

 

PLAY RECAP ******************************************************************

debian :         ok=1    changed=1    unreachable=0    failed=0

 

You’ll notice immediately that, in contrast to an ad hoc call, you see nothing. Upon closer inspection, you’ll also see that Ansible reports a change (even though we are quite sure that a df -h should not cause any changes to the target system). The latter is easy to explain: Ansible does not perform a deep analysis of the Linux commands that are about to be executed, and therefore, it simply does not know the effect here. By default, Ansible always assumes a change for such a task—but you can define this assessment yourself with the task changed_when attribute. Once you’ve finished learning about conditions in Ansible, you’ll have many options available. However, in this case, simple negation using changed_when: false is already sufficient. A df command never causes a change to the system:

 

---

- hosts: debian

  gather_facts: no

 

  tasks:

     - name: Determine space requirements

       command: df -h /

       changed_when: false

 

However, the issue remains that you do not see the output of the command.

 

First of all, you should come to terms with the fact that playbooks are not meant to produce pretty output. Rather, they are intended to perform actions on target systems to achieve a desired target state, and pretty output is irrelevant.

 

Therefore, all standard outputs from command and shell calls are suppressed. However, we can access them (and many other pieces of information) by taking a small detour: Ansible can store all information about the execution of a task in a structured variable (the register keyword). You can then access that variable in later tasks, as follows:

 

---

- hosts: debian

  gather_facts: no

 

  tasks:

     - name: Determine space requirements

       command: df -h /

       changed_when: false

       register: df_cmd

 

     - debug:

       msg: ''

 

$ ansible-playbook command3.yml

 

PLAY [debian] ***************************************************************

 

TASK [Determine space requirements] *****************************************

ok: [debian]

 

TASK [debug] ****************************************************************

ok: [debian] => {

   "msg": [

       "Filesystem                     Size  Used  Avail  Use%  Mounted on”:

       "/dev/mapper/debian--12--vg-root 62G   1.3G  57G    3%   /"

   ]

}

 

PLAY RECAP ******************************************************************

debian :         ok=2    changed=0    unreachable=0    failed=0

First, I would like to clarify the technical classification of registered variables:.

 

Important: Registered variables are technically the same as set_fact variables. They are host specific, meaning they are only visible to the host that has just executed the task. They also have exactly the same precedence.

 

A registered variable has various fields or attributes that depend on the type of task. Here, we accessed the stdout_lines field. It contains a list of the individual output lines, so it is close what would have been printed. (You can somewhat influence the display of such structures on the screen.)

 

This table shows all the fields that would appear if you were to output the complete df_ cmd variable in the debug task:

 

Attributes Values
changed Did the task make a change to the system?

failed

Did the task fail?
cmd This is the command with parameters.
rc This is the UNIX return code of the command 
start This is the start time.
end This is the end time.
delta This is the execution duration.
stdout This is the joined standard output with newliness as \n.
stdout_lines This is the list of individual standard output lines.
stderrr This is the standard error output that's similar to stdout.
stderr_lines This is the standard error output that's similar to stdout_lines.

Tip: The debug module offers an even simpler way to output the contents of a variable. Instead of using

 

- debug: msg=''

 

you can simply use

 

- debug: var=some_variable.

 

Editor’s note: This post has been adapted from a section of the book Ansible: The Practical Guide for Administrators and DevOps Teams by Axel Miesen. Axel is an Ansible coach. His interest in Linux systems began with his studies at the University of Kaiserslautern, where he studied mathematics and computer science. After graduating in 1998, he began working as a consultant and trainer and has passed on his Linux knowledge and experience to numerous professionals.

 

This post was originally published 12/2025.