# Discover a hostname in one play and use it to run the next play?

**URL:** <https://forum.ansible.com/t/discover-a-hostname-in-one-play-and-use-it-to-run-the-next-play/17707>\
**Category:** Ansible Project\
**Created:** [March 10, 2015, 4:42am UTC](https://forum.ansible.com/t/discover-a-hostname-in-one-play-and-use-it-to-run-the-next-play/17707 "2015-03-10T04:42:22Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Michael\_Blakeley](https://avatars.discourse-cdn.com/v4/letter/m/35a633/32.png) [@Michael\_Blakeley](https://forum.ansible.com/u/Michael_Blakeley)\
**Post date:** [March 10, 2015, 4:42am UTC](https://forum.ansible.com/t/discover-a-hostname-in-one-play-and-use-it-to-run-the-next-play/17707/1 "2015-03-10T04:42:22Z")

</div>

I’m doing some cloud scripting that involves some work on one host, then using the results to take action on another host. The hostname of the second host is a dynamic result of that first bit, and won’t be in my inventory. I’d like to do as much of it as possible in ansible, and `add_host` seems to be working. But I’m having trouble using a variable or fact from one play as the `hosts` value for the next play.

Here’s a test case that I’ve been working on: I’ve made it as simple as possible.

# test.yml

- hosts: 127.0.0.1  
tasks:

- set\_fact: hostname\_test=‘fubar’

- add\_host: name=‘{{ hostname\_test }}’  
register: resp

- debug: msg=‘{{ resp }}’

- hosts: 127.0.0.1  
tasks:

- debug: msg=‘resp={{ resp|default(“None”) }}’

- debug: msg=‘hostname\_test={{ hostname\_test|default(“None”) }}’

# end

I’d like that second play to start with `- hosts: hostname_test`. But that results in “skipping: no hosts matched”. At first I thought that meant `add_host` wasn’t working. But if I hardcode `hosts: fubar` for the second play then ansible tries to connect as expected. However I need to determine the second hostname as part of the first play. Running the code as above suggests that neither `set_fact` nor `register` persists from the first play to the next: both seem to be undefined.

Is it possible to use a hostname determined in one play as the hosts value for the next play? If so, what am I doing wrong? Is there a better way to persist new information from one play to the next?

Is it significant that ansible reports the first play under `127.0.0.1`, as in the yml, but the second play shifts to `localhost`?

Thanks in advance for any help.

$ ansible --version  
ansible 1.8.4  
configured module search path = None  
$ ansible-playbook -v test.yml

PLAY [127.0.0.1] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

GATHERING FACTS \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [127.0.0.1]

TASK: [set\_fact hostname\_test=‘fubar’] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [127.0.0.1] =\> {“ansible\_facts”: {“hostname\_test”: “fubar”}}

TASK: [add\_host name=‘{{ hostname\_test }}’] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [127.0.0.1] =\> {“new\_host”: “fubar”}

TASK: [debug msg=‘{{ resp }}’] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [127.0.0.1] =\> {  
“msg”: “{‘invocation’: {‘module\_name’: u’add\_host’, ‘module\_args’: u"name=‘fubar’"}, ‘new\_host’: u’fubar’}”  
}

PLAY [127.0.0.1] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

GATHERING FACTS \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [localhost]

TASK: [debug msg=‘resp=None’] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [localhost] =\> {  
“msg”: “resp=None”  
}

TASK: [debug msg=‘hostname\_test=None’] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [localhost] =\> {  
“msg”: “hostname\_test=None”  
}

PLAY RECAP \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
127.0.0.1 : ok=4 changed=0 unreachable=0 failed=0  
localhost : ok=3 changed=0 unreachable=0 failed=0

---

<div class="post-metadata">

**Author:** ![Tomasz\_Kontusz](https://avatars.discourse-cdn.com/v4/letter/t/bc79bd/32.png) [@Tomasz\_Kontusz](https://forum.ansible.com/u/Tomasz_Kontusz)\
**Post date:** [March 10, 2015, 7:25am UTC](https://forum.ansible.com/t/discover-a-hostname-in-one-play-and-use-it-to-run-the-next-play/17707/2 "2015-03-10T07:25:42Z")

</div>

Play's hosts are rendered pretty early, I think you can only use --extra-vars in there. But you can put a group name in the second play, and add that dynamic host to that group.

Michael Blakeley \<michael.blakeley@gmail.com\> napisał:

---

<div class="post-metadata">

**Author:** ![Michael\_Blakeley](https://avatars.discourse-cdn.com/v4/letter/m/35a633/32.png) [@Michael\_Blakeley](https://forum.ansible.com/u/Michael_Blakeley)\
**Post date:** [March 10, 2015, 5:29pm UTC](https://forum.ansible.com/t/discover-a-hostname-in-one-play-and-use-it-to-run-the-next-play/17707/3 "2015-03-10T17:29:50Z")

</div>

Thanks, and I can probably do something with that. My inventory is ec2.py, so I’ll have to look into how to supplement it with at least one extra group. I believe that’s possible using an inventory directory, or else I’ll write a wrapper script.

Along with that I think I’m still going to need to pass _some_ new information from one play to the next, so I’d like to understand why the test.yml at the start of this thread isn’t working as expected. Both plays run as “hosts: 127.0.0.1”, but the second play doesn’t seem to have access to variables or facts set by the first play. The docs at [http://docs.ansible.com/playbooks\_variables.html](http://docs.ansible.com/playbooks_variables.html) say that “Registered variables are valid on the host the remainder of the playbook run, which is the same as the lifetime of _facts_ in Ansible. Effectively registered variables are just like facts.” Then [http://docs.ansible.com/set\_fact\_module.html](http://docs.ansible.com/set_fact_module.html) says that “Variables are set on a host-by-host basis just like facts discovered by the setup module. These variables will survive between plays.”

In my test case neither set\_fact nor register seems to be working as described. Information gathered in the first play isn’t available to tasks in the second play. I suspect ansible’s getting confused about the hosts. Both plays have “hosts: 127.0.0.1”, but the output shows 127.0.01 for the first play and localhost for the second. For this test my global inventory file is the only one in scope, and it has this entry:

localhost ansible\_connection=local ansible\_python\_interpreter=/usr/local/bin/python

If I change test.yml to target “hosts: localhost” for both plays, then my test.yml works. Using hostvars on 127.0.0.1 also works, but feels like it shouldn’t be necessary:

# test.yml

- hosts: 127.0.0.1  
tasks:

- set\_fact: hostname\_test=‘fubar’

- add\_host: name=‘{{ hostname\_test }}’  
register: resp

- debug: msg=‘{{ resp }}’

- hosts: 127.0.0.1  
tasks:

- debug: msg=‘resp={{ resp|default(“None”) }}’

- debug: msg=‘hostname\_test={{ hostname\_test|default(“None”) }}’

- debug: msg=‘resp={{ hostvars[“127.0.0.1”][“resp”]|default(“None”) }}’

- debug: msg=‘hostname\_test={{ hostvars[“127.0.0.1”][“hostname\_test”]|default(“None”) }}’

# end

Partial output:

TASK: [debug msg=‘resp=None’] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [localhost] =\> {  
“msg”: “resp=None”  
}

TASK: [debug msg=‘hostname\_test=None’] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [localhost] =\> {  
“msg”: “hostname\_test=None”  
}

TASK: [debug msg=‘resp={{ hostvars[“127.0.0.1”][“resp”]|default(“None”) }}’] \*\*\*  
ok: [localhost] =\> {  
“msg”: “resp={‘invocation’: {‘module\_name’: u’add\_host’, ‘module\_args’: u"name=‘fubar’"}, ‘new\_host’: u’fubar’}”  
}

TASK: [debug msg=‘hostname\_test={{ hostvars[“127.0.0.1”][“hostname\_test”]|default(“None”) }}’] \*\*\*  
ok: [localhost] =\> {  
“msg”: “hostname\_test=fubar”  
}

The first two debugs output None while the second two output the expected values. Apparently ansible (1.8.4) is smart enough to map 127.0.0.1 to localhost, but does so in a way that breaks variable scope across plays. Bug?

– Mike

---

<div class="post-metadata">

**Author:** ![Michael\_Blakeley](https://avatars.discourse-cdn.com/v4/letter/m/35a633/32.png) [@Michael\_Blakeley](https://forum.ansible.com/u/Michael_Blakeley)\
**Post date:** [March 11, 2015, 12:11am UTC](https://forum.ansible.com/t/discover-a-hostname-in-one-play-and-use-it-to-run-the-next-play/17707/4 "2015-03-11T00:11:21Z")

</div>

In case the variable scope behavior is a bug, I’ve filed [https://github.com/ansible/ansible/issues/10424](https://github.com/ansible/ansible/issues/10424)

---

<div class="post-metadata">

**Author:** ![Michael\_Blakeley](https://avatars.discourse-cdn.com/v4/letter/m/35a633/32.png) [@Michael\_Blakeley](https://forum.ansible.com/u/Michael_Blakeley)\
**Post date:** [March 11, 2015, 2:24am UTC](https://forum.ansible.com/t/discover-a-hostname-in-one-play-and-use-it-to-run-the-next-play/17707/5 "2015-03-11T02:24:31Z")

</div>

I’ve more or less solved the original problem now. There’s a sample playbook at [http://stackoverflow.com/a/28977513/908390](http://stackoverflow.com/a/28977513/908390) that shows the tricks I had to use. I’d welcome any suggestions to make it cleaner.
