Delegation a set of tasks to another host that relies on conditional

Viewed 5549

My question is slightly complex. I have some multi-node cluster infrastructure that orchestrated with Ansible.

And there can be nodes that Kubernetes masters or slaves. Depending on that I need to delegate a specific set of tasks to master node if current task is playing on slave node.

For example, I have inventory structure like this:

[k8s_master]
hostname ansible_ssh_host= ... etc.

[k8s_slaves]
hostname ansible_ssh_host= ... etc.

[k8s_cluster:children]
k8s_master
k8s_slaves

I have a task that checking if k8s node is master or slave and registering some value:

    - name: Checking if node is kubernetes master
      stat:
        path: "{{kubeconf}}"
      register: master_conf

and I want to execute some set of tasks depending on master_conf.stat.exists value (true or false) locally (if the node is k8s master) or delegate it to master (if the node is k8s slave). Problems:

  • I need to delegate a set of tasks or dynamically included playbook but delegate_to does not work with block: or include_tasks:.
  • I need to delegate this set of tasks depending on conditional statement or play it locally.
  • I need to pass node hostname to this set of tasks even it they will be playing on remote node. For example, I can set it like that:
         set_fact:
           node_hostname: "{{ansible_hostname}}"

and then I need the variable {{node_hostname}} inside tasks even if they were delegated. Then I need to register some variables during the play on master node and use it in tasks on the slave node again.

Still can't find right solution. I've tried something like:

    - name: Including tasks to perform if we are on the master node
      include_tasks: set-of-tasks.yml
      when: master_conf.stat.exists

    - name: Including tasks to perform if we are on the slave node
      include_tasks: set-of-tasks.yml
      delegate_to: "{{item}}"
      delegate_facts: true
      with_items: "{{groups.k8s_master}}"
      when: master_conf.stat.exists == false

but this doesn't work.

1 Answers

Resolved this case with combination of include and arbitrary var containing hostname of the node where I need to delegate my task (include_task doesn't support arbitrary vars). So the syntax is:

    - name: Checking if node is kubernetes master
      stat:
        path: "{{kubeconf}}"
      register: master_conf

    - name: Including tasks to perform if we are on the master node
      include: set-of-tasks.yml
      when: master_conf.stat.exists

    - name: Including tasks to perform if we are on the slave node
      include: set-of-tasks.yml
      delegate_host: "{{item}}"
      with_items: "{{groups.k8s_master}}"
      when: master_conf.stat.exists == false

And then in set-of-tasks.yml adding delegate_to to delegated tasks: delegate_to: "{{delegate_host}}"

For some reason default(omit) doesn't work for me (Ansible tries to resolve original node hostname and fails though it works fine with that name from inventory file with IP specified). So I added something like that at the beginning of set-of-tasks.yml:

    - name: Setting target kubernetes master node
      set_fact:
        delegate_host: "{{ansible_hostname}}"
      when: delegate_host is undefined
Related