How to pass variables between Ansible plays and hosts
I’m working on a set of Ansible plays in which there is a common or base play, a master play (items relevant only to the master server) and a node play (items relevant to all the node servers). This is pretty standard stuff, apt update and upgrade, install dependencies, do some shenanigans.
Then I needed to pass a variable from the master play/host to the node play/host. In Ansible you use the magic variable called hostvars for this.
So in the master play I registered the output I needed and then set a fact for it:
- name: get join command
shell: kubeadm token create --print-join-command
register: join_command_raw
- name: set join command
set_fact:
join_command: "{{ join_command_raw.stdout_lines[0] }}"Then, I went to the node play and tried writing something based on the hostvars variable. The problem is that this variable is made to be attached to a host. And this is a set of dynamic plays in which I am using the excellent dynamic inventory ec2.py. This means that I don’t know what the IP or even the name of my master is, so I can’t reference it using hostvars['master']['myvariable'].
So I did what any self-respecting professional would do and scoured google and stack overflow looking for an answer. It took a while, and it was not exactly an answer, but I finally made it. I am using tags to identify my masters, so I found that I can still use hostvars for a group and use the dynamic inventory tagging for that. Here is a bit of the inventory in question:
./ec2.py --list
(...)
"tag_k8stype_master": [
"34.254.186.212"
],
"tag_k8stype_node": [
"52.16.45.100"
],
(...)And this is how I got access to the variable in the node play:
- name: join cluster
shell: "{{ hostvars[groups['tag_k8stype_master'][0]]['join_command'] }} >> /home/ubuntu/node_joined.txt"
args:
creates: /home/ubuntu/node_joined.txtI hope this helps someone else!
Originally published at tech.migueldavid.eu on September 4, 2018.
