4

The real scenario, want to get a resource id of sqs in AWS, which will be returned after the execution of a playbook. So, using this variable in files to configure the application.

Persisting variables from one playbook to another

checking out the documentation, modules like set_fact and register have scope only for that specific host. There are many purpose of using the variables from one host to another.

Alternatives I can think of:

  1. using Command module and echoing the variables to a file. Later, using the variable file using vars section or include.

  2. Setting the env variables and then accessing it but this will be difficult.

So what is the solution?

Lakshman Diwaakar
  • 7,207
  • 6
  • 47
  • 81
  • 1
    To be sure of your question, you mean dynamic variables that are either pulled from a host or created during the course of a playbook run, correct? If so, you should edit your question as otherwise this sounds like something that could be solved by linking you to the variables documentation. –  Sep 03 '15 at 13:39

4 Answers4

6

If you're gathering facts, you can access hostvars via the normal jinja2 + variable lookup:

e.g.

- hosts: serverA.example.org
  gather_facts: True
  ...
  tasks:

    - set_fact:
        taco_tuesday: False 

and then, if this has run, on another host:

- hosts: serverB.example.org
  ...
  tasks:

    - debug: var="{{ hostvars['serverA.example.org']['ansible_memtotal_mb'] }}"

    - debug: var="{{ hostvars['serverA.example.org']['taco_tuesday'] }}"

Keep in mind that if you have multiple Ansible control machines (where you call ansible and ansible-playbook from), you should take advantage of the fact that Ansible can store its facts/variables in a cache (currently Redis and json), that way the control machines are less likely to have different hostvars. With this, you could set your control machines to use a file in a shared folder (which has its risks -- what if two control machines are running on the same host at the same time?), or set/get facts from a Redis server.

For my uses of Amazon data, I prefer to just fetch the resource each time using a tag/metadata lookup. I wrote an Ansible plugin that allows me to do this a little more easily as I prefer this to thinking about hostvars and run ordering (but your mileage may vary).

  • I will try this and get back to you. – Lakshman Diwaakar Sep 03 '15 at 22:01
  • Moreover I use set_facts and the scope of this is host level. So when I use this in other hosts, should use with jinja 2 template. It works if the set_fact is retrieved in the same playbook but when I use in different playbook, it is not persisted. Is the implementation is wrong or should I use redis for fact caching to persist across playbooks – Lakshman Diwaakar Sep 09 '15 at 09:51
  • This is the officially supported way to do it. Look into "fact-caching" and enable it in your ansible.cfg if you have not already: http://docs.ansible.com/ansible/playbooks_variables.html#fact-caching –  Sep 09 '15 at 15:19
1

You can pass variables On The Command Line: http://docs.ansible.com/ansible/playbooks_variables.html#passing-variables-on-the-command-line

ansible-playbook release.yml --extra-vars "version=1.23.45 other_variable=foo"

You can use local connection to run playbook = get variable and apply it to another playbook:

- hosts: 127.0.0.1
  connection: local
  - shell: ansible-playbook -i ...
    register: sqs_id
  - shell: ansible-playbook -i ... -e "sqs_id={{sqs_id.stdout}}"

Also delegation might be useful in this scenario: http://docs.ansible.com/ansible/playbooks_delegation.html#delegation

Also you can store output in the local file and use (http://docs.ansible.com/ansible/playbooks_delegation.html#delegation): - name: take a sqs id local_action: command cat ~/sqs_id

PS:

I don't understand why you can't write complex playbook where will be included many roles that will share variables?

Valeriy Solovyov
  • 5,384
  • 3
  • 27
  • 45
0

You can write "common" variables to a host_vars or group_vars this way all the servers has access to it.

Another way may be to create a custom ansible module/lookup plugin to hide all the boilerplate code and get an easy and flexible access to the variables you need.

Vor
  • 33,215
  • 43
  • 135
  • 193
  • The need for this is, var A is a fact of host A, so I need this var A in playbook while executing host B. So any alternatives? – Lakshman Diwaakar Sep 03 '15 at 13:34
  • You need a shared storage that would keep your variables for undetermined amount of time. So that you can run a play A today and play B tomorrow. you can easily and secure store them on AWS S3. and create a simple ansible module/ lookup plugin to access this information. – Vor Sep 03 '15 at 15:00
0

I had a similar issue with azure DevOps pipelines. I created VM:s with terraform, ssh-keys and windows username/password was generated by terraform and stored it in a KeyVault.

So I then needed to query KeyVault before running Ansible on all created VM:s. I ended up using Azure python SDK to get all secrets. I also generate an inventory file and a host_vars folder with a file for each VM.

The actual play-book is now very basic and does the job perfectly. All variables for terraform and ansible is in a json file. And the python script is less than 30 lines.

plejon
  • 1