How can I share a (global) variable between salt states? I am using Salt for deployment and configuration management. In order to attach to a FreeIPA server, I need to randomly generate an OTP token and then use it to attach to IPA. How can I share a variable between SLS files?

For example,

init.sls:

{%- from "freeipa/map.jinja" import client, ipa_host with context %}
include:
  - freeipa.example

freeipa_client_install:
  cmd.run:
  - name: &gt;
    ipa-client-install
    --server server.example.com
    --domain example.com
    --realm EXAMPLE.COM
    --hostname client.example.com
    -w {{ otp }}                                   &lt;===== !!!
    --unattended


./freeipa/example.sls:

{% set otp = salt['random.get_str'](20) %}         &lt;===== !!!

get_ticket:
  cmd.run:
    - name: kinit service-account@EXAMPLE.COM -kt /tmp/salt-service.keytab
ipa_host_add:
  cmd.run:
    - name: &gt;
      curl -k
      -H referer:https://{{ client.get("server", {}) }}/ipa
      --negotiate -u :
      -H "Content-Type:application/json"
      -H "Accept:applicaton/json"
      -c /tmp/cookiejar -b /tmp/cookiejar
      -X POST
      -d '{
        "id": 0,
        "method": "host_add",
        "params": [
          [
            "client.example.com"
          ],
          {
            "all": false,
            "force": false,
            "no_members": false,
            "no_reverse": false,
            "random": false,
            "raw": true,
            "userpassword": "{{ otp }}",          &lt;==== !!!
            "version": "2.156"
          }
        ]
      }' https://server.example.com/ipa/json


What I find is that everything looks good in example.sls, but I cannot reference this variable in init.sls. Do I need to be doing salt['random.get_str'](20) inside of init.sls instead? If so, how can I reference the otp variable in example.sls - or vice-versa - how can I reference the otp variable set in example.sls inside of init.sls?
When I encountered a related problem, I wound up having Jinja run execute Salt modules.

In my case, it was cmd.run to run mktmp (and, at the end of the template, rm for cleanup), with file.append and file.grep, though in your case, you might be able to use Salt's load_yaml extension to Jinja.

So, something like this (rough, untested): 

{% set tmpfile = salt['cmd.run']('mktmp') -%}
{% salt['file.append']('my_key: ' ~ your_key) -%}
{% set my_key = load_yaml(tmpfile)['my_key'] -%}
{% salt['file.remove'](tmpfile) %}


This certainly isn't the best place to put data, but it demonstrated using calling into Salt modules from Jinja to store data. I don't know of any existing Salt modules suitable for storing ephemeral data that only lives as long as the templates compile. I'll check back later and see what other solutions might work.