Ansible

Ansible local_action

In most situations, we use Ansible to manage and configure remote hosts from a single control node. Hence, when creating playbooks, it’s with the understanding that they shall execute on the remote machines we specify in the host’s block of the playbooks.

However, there are instances where you may need to perform a specific action on the local machine instead of remote hosts. In such instances, a feature like local_action comes in handy.

This guide will show you how to work with the Ansible local_action module to execute tasks locally.

How the Ansible local_action Module Works

As mentioned earlier, when creating playbooks, the target is typically remote hosts. If you need to perform a task to hosts other than the remote hosts, you can use Ansible modules such as local_action and delegate_to.

Delegate_to is useful when you need to set a task to execute on a specific host. You point the delegate_to module to the target hosts by specifying either its hostname or IP address.

Local_action, on the other hand, will execute the set tasks on the local machine only. It is similar to setting the value of delegate_to to localhost or 127.0.0.1

delegate_to: localhost

The local_action module is convenient when you first need to perform a task on the local machine before sending it to remote systems. These are mainly custom or shell commands within the local system.

The best way to understand how to use the local_action module is by using example playbooks.

Ansible local_action Example Use cases

For simplicity, we will try to keep the playbooks short and not too complex.

Before focusing on the playbooks, let us describe our Ansible setup, which will allow us to understand how the local_action module works.

In our example setup, we have an Ubuntu 20.04 server that has Ansible installed. This will serve as the Ansible control node.

Next, we have three remote machines: an Ubuntu 21.04 server, a Debian 11 server, and a CentOS 8 server.

We have the Ansible inventory file containing all the three hosts’ IP addresses in the control node.

Once we run a playbook, it executes on all three hosts.

NOTE: We will limit the output to a single host to avoid complexity and confusion.

Local_action using a module

Consider the following playbook:

---
- hosts
: all
gather_facts
: no
  become
: true
  tasks
:
    - name
: Archivethelocallogfiles
local_action
:
        module
: community.general.archive
        path
: /var/log
dest
: /var/log/log.tar.gz
        format
: gz
force_archive
: true
    - name
: Copylogarchivetoremotehost
ansible.builtin.copy
:
src
: /var/log/log.tar.gz
dest
: /home/ubuntu

In the first block, we specify the target hosts to run the tasks unless specified otherwise.

The playbook continues to disable fact-gathering about the remote hosts by setting the gather_facts block to no.

To have the read and write permission, we set the become block to true.

In the subsequent blocks, we define two tasks:

The first task creates an archive of the log files from the local system. We delegate the task to run in the local system by using the local_actiob block. In our example, we use a community module that we can install using the command:

ansible-galaxy collection install community.general

The next task copies the log archive from the local system to the specified path on the remote host.

Save the playbook and run it using the command:

ansible-playbook local_action.yml

Upon successful completion, you should see an output similar to the one shown below:

Local_action using a shell command

The example below shows you how to run shell commands using the local_action module.

---
- hosts
: all
gather_facts
: no
  become
: true
  tasks
:
  - name
: countfilesanddirectoriesonthe remotehost
    shell
: ls-la~| wc -l
    register
: remote_files
  - name
: printremotefiles
    debug
:
      msg
: '{{remote_files.stdout}}'
  - name
: countfilesanddirectoriesonthe localmachine
local_action
: shellls-la~| wc -l
    register
: local_files
  - name
: printlocalfiles
    debug
:
      msg
: '{{local_files.stdout}}'

In the example playbook above, we use the local_action module to run a shell command. The shell command counts the number of files and directories saved to a variable.

We then use the debug module to print the number of files both on the remote and localhost.

Run the file as:

ansible-playbook filecount.yml

Local_action with run_once

You can use the local_action module alongside the run_once parameter.

---
- hosts
: all
gather_facts
: no
  become
: true
  tasks
:
  - name
: Stoptheapacheserver
local_action
:
      module
: ansible.builtin.service
      name
: httpd
      state
: stopped
run_once
: True

The playbook above will run the local_action block once on the local system.

Conclusion

The local_action module is useful when you want to delegate a task to run on the local machine. You can use it both with an Ansible module or a shell command.

About the author

John Otieno

My name is John and am a fellow geek like you. I am passionate about all things computers from Hardware, Operating systems to Programming. My dream is to share my knowledge with the world and help out fellow geeks. Follow my content by subscribing to LinuxHint mailing list