'Ansible: Unable to store command in variable and use it in different host

I am trying to set up a kubernetes cluster using kubeadm

I want to fetch the join command (done on the master node) and run it on worker node.

The following approach does not work:

- name: kubernetes.yml --> Get the join command
  shell: kubeadm token create --print-join-command
  register: rv_join_command
  when: inventory_hostname in (groups['masters'] | last)
  become: yes


- name: kubernetes.yml --> Store the join command
  set_fact:
    join_command: "{{ rv_join_command.stdout }}"
  run_once: true
  when: inventory_hostname in (groups['masters'] | last)


- name: DEBUG kubernetes.yml --> Print the join command
  debug:
    var: rv_join_command.stdout
  when: inventory_hostname in (groups['masters'] | last)


- name: kubernetes.yml --> Run the join command on kubernetes nodes
  shell: "{{ join_command }}"
  when: inventory_hostname in groups['nodes']

as it fails with:

'join_command' is undefined

But the approach below also fails:

- name: kubernetes.yml --> Run the join command on kubernetes nodes
  shell: "{{ rv_join_command.stdout }}"
  when: inventory_hostname in groups['nodes']
  become: yes

The error was: 'dict object' has no attribute 'stdout'

Any suggestions?



Solution 1:[1]

As pointed out in larsks' comment above, you are storing the join_command var only for a single host (i.e. groups['masters'] | last) and it is only available there.

Meanwhile, it is possible to access vars from other hosts from anywhere.

You basically have two options:

  1. Modify the set_fact to store the var on each node from the result on your master
  2. Modify the join_command to use the stored var on master on every node

Option 1

- name: kubernetes.yml --> Store the join command
  set_fact:
    join_command: "{{ hostvars[groups['masters'] | last].rv_join_command.stdout }}"
  when: inventory_hostname in groups['nodes']
# Now you can use join_command on each node

Option 2

# Leave set_fact as it was and then...
- name: kubernetes.yml --> Run the join command on kubernetes nodes
  shell: "{{ hostvars[groups['masters'] | last].join_command }}"
  when: inventory_hostname in groups['nodes']

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1