Definition

The run_once: true directive allows you to run the task once, regardless of the number of managed hosts

Why might this be necessary? For example:

  • If a cluster is configured and changes need to be made only on the master node
  • If you need to make an API request only once
  • If you need to generate or get a token

run_once and register

Interestingly, the result of executing the module via the register: directive will be passed to all other hosts within the play, for example, the following play will execute the date command on one of the hosts (don’t do this in real playbooks) and then output the contents of the result of this command on all hosts of this play:

- name: A simple example
  hosts: all
  tasks:
    - name: Run this ask only on one of the hosts
      ansible.builtin.command: date
      run_once: true
      register: host_kernel

    - name: Show it on all hosts
      ansible.builtin.debug:
        var: host_kernel

run_once and set_fact

Unlike register:, set_fact: is a module, and therefore a variable from set_fact will only belong to the host that was selected for run_once:, but I will remind you that set_fact can be passed between different plays (more details in the post about set_fact):

- name: A simple example
  hosts: all
  tasks:
    - name: Run this ask only on one of the hosts
      ansible.builtin.set_fact:
        sample_variable: Played on {{ ansible_host }}
      run_once: true

   # Эта таска упадет с ошибкой на всех других хостах
    - name: Try to show it on all hosts
      ansible.builtin.debug:
        var: sample_variable

run_once and handlers

With handlers, run_once works differently than with register:, in this example the handler will be called only once, on the host that was selected for run_once (you can read more about handlers in the corresponding post):

- name: A simple example
  hosts: all
  handlers:
    - name: Say hello
      ansible.builtin.debug:
        msg: Hello from {{ ansible_host }}
  tasks:
    - name: Run this ask only on one of the hosts
      ansible.builtin.command: /bin/true
      run_once: true
      notify: Say hello

run_once and delegate_to

Using run_once and delegate_to you can explicitly specify on which host in the group the task should be executed:

- name: A simple example
  hosts: all
  tasks:
    - name: Run this ask only on localhost
      ansible.builtin.command: /bin/true
      run_once: true
      delegate_to: localhost