Ansible

How to Use Ansible Register Module

In Ansible, you can run any shell command on your Ansible hosts, the hosts you will be configuring with Ansible. These shell commands may have outputs. By default, the output is ignored. If you want to store the output in a variable and use it later, then you can use the Ansible register module. This article will show you how to use the Ansible register module to store the command output in a variable and access it later in your Ansible playbook.

Prerequisites

If you want to try out the examples in this article, you must:

1) Have Ansible installed on your computer.

2) Have an Ubuntu host configured for Ansible automation.

There are many articles on LinuxHint dedicated to installing Ansible and configuring hosts for Ansible automation. You may check these articles out if necessary.

Setting Up a Project Directory

Before moving on any further, set up a new Ansible project directory, just to keep things a bit organized.

To create the project directory register-demo/ and all the required subdirectories (in your current working directory), run the following command:

$ mkdir -pv register-demo/playbooks

Once the project directory is created, navigate to the project directory, as follows:

$ cd register-demo/

Create a hosts inventory file, as follows:

$ nano hosts

Add the host IP or DNS name of your Ubuntu host in the inventory file (one host per line), as shown in the screenshot below.

Here, I have added my Ubuntu 20.04 LTS host vm3.nodekite.com in the ubuntu20 group.

Once you are done, save the file by pressing <Ctrl> + X, followed by Y and <Enter>.

Create an Ansible configuration file ansible.cfg in your project directory, as follows:

$ nano ansible.cfg

Next, type the following lines in the ansible.cfg file:

[defaults]
inventory           = hosts
host_key_checking   = False

Once you are done, save the ansible.cfg file by pressing <Ctrl> + X, followed by Y and <Enter>.

Now, try to ping your Ubuntu host, as follows:

$ ansible ubuntu20 -u ansible -m ping

As you can see, my Ubuntu 20.04 host vm3.nodekite.com is accessible.

Example 1: The Basics

In this example, I will show you some of the basics of the Ansible register module. I will use Ansible to generate a random password in my Ubuntu 20.04 host using the pwgen command, store the password in a variable using the register module, and print the password on the screen.

First, create the new playbook generate_pass.yaml in the playbooks/ directory, as follows:

$ nano playbooks/generate_pass.yaml

Type the following lines in the generate_pass.yaml file:

- hosts: ubuntu20
  user
: ansible
  become
: True
  tasks
:
    - name
: Ensure pwgen is installed
      apt
:
         name
: pwgen
         state
: present
         update_cache
: True
    - name
: Generate password
      shell
: pwgen -N 1 -s 30
      register
: mypass
    - name
: Print the generated password
      debug
:
      msg
: "The password is {{ mypass }}"

Once you are done, press <Ctrl> + X, followed by Y and <Enter>, to save the generate_pass.yaml file.

The following line tells Ansible to run the playbook generate_pass.yaml on every host in the ubuntu20 group. In my case, the playbook will be run on the host vm3.nodekite.com.

In this playbook, I will define three tasks.

The first task will enure that the pwgen package is installed.

The second task will generate a random, 30-character password using the pwgen command. I will use the register module to store the generated password in the mypass variable.

The third task will print the mypass variable using the Ansible debug module.

Run the playbook generate_pass.yaml using the following command:

$ ansible-playbook playbooks/generate_pass.yaml

As you can see, the playbook ran successfully. A password has also been generated.

But, why did the variable mypass print so many items?

Well, the variable mypass is an object that contains some important properties.

The most important properties of each of the register variables are as follows:

cmd – The command that ran to generate the output.

stdout – The output of the command.

stderr – The error output of the command.

start – The date and time when the command began executing.

end – The date and time when the command finished executing.

delta – The time taken to run the command. This is the difference between the end and the start properties.

stdout_lines – An array containing each output line of the command. Same as stdout, but stdout separates the lines using a newline (\n) characters instead of arrays.

stderr_lines –  An array containing each error output line of the command. Same as stderr, but stderr separates the lines using newlines (\n) characters instead of arrays.

If you just want to print/access the password string (which is very likely), you may print/access the stdout property of the mypass variable in your playbook, as marked in the screenshot below.

$ nano playbooks/generate_pass.yaml

Once you are done, run the playbook generate_pass.yaml again. Only the password string will be printed, as you can see in the screenshot below.

That covers the basics of the Ansible register module.

Example 2: Store Directory Contents

In this example, I will show you how to store the contents of a directory in a variable using the Ansible register module, as well as how to iterate over them.

First, create the new playbook get_dir_contents.yaml in the playbooks/ directory.

$ nano playbooks/get_dir_contents.yaml

Next, type the following lines in the get_dir_contents.yaml playbook:

- hosts: ubuntu20
  user
: ansible
  become
: True
  tasks
:
    - name
: List all files and directories in /home/ansible
      shell
: ls /home/ansible
      register
: dir_contents
    - name
: Print directory contents using loops
      debug
:
        msg
: "{{ item }}"
      loop
: "{{ dir_contents.stdout_lines }}"

Once you are done, press <Ctrl> + X, followed by Y and <Enter>, to save the generate_pass.yaml file.

In this playbook, I will define two tasks.

The first task lists all the contents of the /home/ansible directory and stores them in the dir_contents variable.

The second task prints the dir_contents variable.

Run the get_dir_contents.yaml playbook, as follows.

$ ansible-playbook playbooks/get_dir_contents.yaml

As you can see, the stdout_lines property stored the directory contents as an array. The stdout property is also stored in the directory contents. These properties are separated by newline (\n) characters. In this example, the stdout_lines property is easy to work with.

Next, iterate over the directory contents using a loop.

To do this, open the get_dir_contents.yaml playbook and change the second task, as marked in the screenshot below.

$ nano playbooks/get_dir_contents.yaml

Here, I am iterating over the dir_contents.stdout_lines array using a loop and printing the array items using the Ansible debug module. In this task, the item variable is a loop variable used to iterate over the array elements.

Run the get_dir_contents.yaml playbook, as follows:

$ ansible-playbook playbooks/get_dir_contents.yaml

As you can see, the contents of the /home/ansible directory are printed on the screen.

Example 3: Back Up Directory

In this example, I will show you how to back up a directory using the Ansible register, file, and copy modules.

First, create the new playbook backup_home_dir.yaml in the playbooks/ directory, as follows:

$ nano playbooks/backup_home_dir.yaml

Next, type the following lines in the backup_home_dir.yaml file.

- hosts: ubuntu20
  user
: ansible
  become
: True
  tasks
:
    - name
: Get home directory /home/ansible contents
      shell
: ls /home/ansible
      register
: dir_contents
    - name
: Create a new directory /tmp/ansible
      file
:
        path
: /tmp/ansible
        state
: directory
    - name
: Backup home directory /home/ansible to /tmp/ansible
      copy
:
        src
: /home/ansible/{{ item }}
        dest
: /tmp/ansible/
        remote_src
: True
      loop
: "{{ dir_contents.stdout_lines }}

Once you are done, press <Ctrl> + X, followed by Y and <Enter>, to save the backup_home_dir.yaml file.

In this playbook, I will define three tasks.

The first task stores the contents of the /home/ansible directory (the directory I will be backing up) in the dir_contents variable using the Ansible register module.

The second task creates a new directory /tmp/ansible using the Ansible file module. This is the directory where the backup will be stored.

The third task loops through the dir_contents.stdout_lines array and uses the Ansible copy module to copy each directory to the /tmp/ansible/ directory.

Run the backup_home_dir.yaml playbook, as follows:

$ ansible-playbook playbooks/backup_home_dir.yaml

As you can see, on my Ubuntu 20.04 LTS host, the backup was successful.

Example 4: Run or Skip Tasks

In this example, I will show you how to run or skip tasks, depending on the variable you have registered, using the register module.

First, create the new playbook register_conditions.yaml in the playbooks/ directory as follows:

$ nano playbooks/register_conditions.yaml

Next, type the following lines in the register_conditions.yaml file.

- hosts: ubuntu20
  user
: ansible
  become
: True
  tasks
:
    - name
: List directory contents
      shell
: ls /home/ansible/test3
      register
: dir_contents
    - name
: Check if directory is empty
      debug
:
        msg
: "Directory is empty."
     when
: dir_contents.stdout == ""

Once you are done, press <Ctrl> + X, followed by Y and <Enter>, to save the register_conditions.yaml file.

In this playbook, I have defined two tasks.

The first task stores the contents of the /home/ansible/test3 directory in the dir_contents variable.

The second task checks if dir_contents.stdout is an empty string, or whether the directory /home/ansible/test3 is empty. If the directory is empty, the message Directory is empty will print.

Run the register_conditions.yaml playbook, as follows:

$ ansible-playbook playbooks/register_conditions.yaml

As you can see, the playbook ran successfully.

Since the directory /home/ansible/test3 is empty, the playbook printed the message Directory is empty.

Next, create a new file in the /home/ansible/test3 directory.

$ touch test3/myfile

Since the /home/ansible/test3 directory is no longer empty, the task Check if directory is empty is skipped, as you can see in the screenshot below.

$ ansible-playbook playbooks/register_conditions.yaml

Conclusion

The Ansible register module is very useful for server automation. This article showed you the basics of the register module, including examples of using the Ansible register module for directory storage and backup, and for running directory tasks.

About the author

Shahriar Shovon

Freelancer & Linux System Administrator. Also loves Web API development with Node.js and JavaScript. I was born in Bangladesh. I am currently studying Electronics and Communication Engineering at Khulna University of Engineering & Technology (KUET), one of the demanding public engineering universities of Bangladesh.