[Howto] Reference Ansible variables between plays

Ansible LogoAnsible’s strenght is to work with all kinds of devices and services – in one go. To properly call a variable value from one server while working on another host the variable needs to be referenced properly.

One of the major strength about Ansible is the capability to almost seamlessly talk to different hosts, devices and services. That’s agent-less at its best!

However, to do that often variables of one host need to be referenced on another. For the sake of an example, imagine a monitoring server which needs to ssh to the managed nodes. The task is to first collect the public SSH key of the monitoring server and afterwards add it to the managed nodes.

First you need a play to collect the SSH key:

- name: fetch ssh key 
  hosts: monitoringserver

    - name: fetch ssh key from monitoring server
        src: ~/.ssh/id_rsa.pub
      register: monitoringsshkey

After that, the key needs to be distributed. It makes sense to just add a second play to the same playbook. However, since the ssh key was fetched in the first play, it is not possible to just reference it as {{ monitoringsshkey }}. That would lead to an error:

fatal: [managednode.qxyz.de]: FAILED! => {"failed": true, "msg": "the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'monitoringsshkey' is undefined\n\nThe error appears to have been in '/home/liquidat/ansible/sshkey.yml': line 19, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  tasks:\n    - name: Distribute SSH to nodes\n      ^ here\n"}

Instead, the variable needs to be referenced properly, highlighting the actual host it is coming from:

- name: provide ssh key
  hosts: managednode.qxyz.de

    - name: Distribute SSH to nodes
        user: liquidat
        key: "{{ hostvars['monitoringserver']['monitoringsshkey']['content'] | b64decode }}"

The reason for this need is simple: in his example we had only one host targeted in the first play – but it could also easily be five hosts. In that moment, Ansible could not reliably know which variable value to pick if we do not specify the actual host.