# Yet another dynamic variable problem

**URL:** <https://forum.ansible.com/t/yet-another-dynamic-variable-problem/30851>\
**Category:** Ansible Project\
**Created:** [July 23, 2019, 10:19pm UTC](https://forum.ansible.com/t/yet-another-dynamic-variable-problem/30851 "2019-07-23T22:19:36Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![mark.tovey](https://avatars.discourse-cdn.com/v4/letter/m/ce73a5/32.png) [@mark.tovey](https://forum.ansible.com/u/mark.tovey)\
**Post date:** [July 23, 2019, 10:19pm UTC](https://forum.ansible.com/t/yet-another-dynamic-variable-problem/30851/1 "2019-07-23T22:19:36Z")

</div>

I am trying to generate a variable name dynamically, but so far I have been stymied.

I have lists whose names are based upon the OS name:

> myos7:
> 
> - os7package1
> - os7package2
> - os7package3

> myos8:
> 
> - os8package1
> - os8package2
> - os8package3

I want to access these lists dynamically in a shell command:

> - shell:  
> for pkg in “{{‘myos’ + ansible\_facts.distribution\_major\_release}}”; \
> 
> do   
> echo “pkg=$pkg”;   
> done

All I get in the output from the echo command is ‘myos7’ or ‘myos8’, but not the contents of those variables. If I output the variable in a debug task, I get the expected results, the list of packages:

> - debug:

> var: “{{item}}”

> with\_items:

> - “{{‘myos’ + ansible\_facts.distribution\_major\_release}}”

So what is the difference? Why does it work as expected in the debug task but not in the shell task?

---

<div class="post-metadata">

**Author:** ![cassell](https://avatars.discourse-cdn.com/v4/letter/c/ecae2f/32.png) [@cassell](https://forum.ansible.com/u/cassell)\
**Post date:** [July 24, 2019, 1:03am UTC](https://forum.ansible.com/t/yet-another-dynamic-variable-problem/30851/2 "2019-07-24T01:03:09Z")

</div>

> I am trying to generate a variable name dynamically, but so far I have  
> been stymied.
> 
> I have lists whose names are based upon the OS name:
> 
> \> myos7:  
> \> - os7package1  
> \> - os7package2  
> \> - os7package3
> 
> \> myos8:  
> \> - os8package1  
> \> - os8package2  
> \> - os8package3
> 
> I want to access these lists dynamically in a shell command:
> 
> \> - shell:  
> \> for pkg in "{{'myos' + ansible\_facts.distribution\_major\_release}}"; \  
> \> do \  
> \> echo "pkg=$pkg"; \  
> \> done

You want

lookup('vars', 'myos' ~ ansible\_facts.distribution\_major\_release)

> All I get in the output from the echo command is 'myos7' or 'myos8',  
> but not the contents of those variables. If I output the variable in a  
> debug task, I get the expected results, the list of packages:
> 
> \> - debug:  
> \> var: "{{item}}"  
> \> with\_items:  
> \> - "{{'myos' + ansible\_facts.distribution\_major\_release}}"
> 
> So what is the difference? Why does it work as expected in the debug  
> task but not in the shell task?

You're doing a double lookup here. Once in with\_items and again by using `var` instead of `msg`

V/r,  
James Cassell

---

<div class="post-metadata">

**Author:** ![mark.tovey](https://avatars.discourse-cdn.com/v4/letter/m/ce73a5/32.png) [@mark.tovey](https://forum.ansible.com/u/mark.tovey)\
**Post date:** [July 24, 2019, 2:50am UTC](https://forum.ansible.com/t/yet-another-dynamic-variable-problem/30851/3 "2019-07-24T02:50:56Z")

</div>

I tried that. I swear I tried that. And it kept telling me that it could not locate my variable. I thought maybe I had mistyped the variable name, but it looked good. It still would not work. But now, of course it does:

TASK [debug] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [ldappoc4] =\> (item=myos7) =\>  
&nbsp;&nbsp;ansible\_loop\_var: item  
&nbsp;&nbsp;item: myos7  
&nbsp;&nbsp;myos7:  
&nbsp;&nbsp;- os7package1  
&nbsp;&nbsp;- os7package2  
&nbsp;&nbsp;- os7package3

TASK [shell] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
changed: [ldappoc4] =\> changed=true  
&nbsp;&nbsp;cmd: for pkg in "[u'os7package1', u'os7package2', u'os7package3']"; do echo "pkg=$pkg"; done  
&nbsp;&nbsp;delta: '0:00:00.031796'  
&nbsp;&nbsp;end: '2019-07-24 04:40:34.798245'  
&nbsp;&nbsp;rc: 0  
&nbsp;&nbsp;start: '2019-07-24 04:40:34.766449'  
&nbsp;&nbsp;stderr: ''  
&nbsp;&nbsp;stderr\_lines: \<omitted\>  
&nbsp;&nbsp;stdout: pkg=[u'os7package1', u'os7package2', u'os7package3']  
&nbsp;&nbsp;stdout\_lines: \<omitted\>

&nbsp;&nbsp;&nbsp;&nbsp;That is what I expected to see. So at least now I have proof that it will work. I need to go back to my original code and see where I went wrong.  
&nbsp;&nbsp;&nbsp;&nbsp;It has been a long day, sometimes just walking away for a bit makes all the difference in the world.  
&nbsp;&nbsp;&nbsp;&nbsp;Thanks,  
&nbsp;&nbsp;&nbsp;&nbsp;-Mark

---

<div class="post-metadata">

**Author:** ![mark.tovey](https://avatars.discourse-cdn.com/v4/letter/m/ce73a5/32.png) [@mark.tovey](https://forum.ansible.com/u/mark.tovey)\
**Post date:** [July 24, 2019, 3:34am UTC](https://forum.ansible.com/t/yet-another-dynamic-variable-problem/30851/4 "2019-07-24T03:34:59Z")

</div>

Okay, I did not describe the problem properly. The code looks more like the following:

vars:  
&nbsp;&nbsp;&nbsp;&nbsp;packages:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myos7:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- os7package1  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- os7package2  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- os7package3

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myos8:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- os8package1  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- os8package2  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- os8package3

&nbsp;&nbsp;- debug:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var: "{{item}}"  
&nbsp;&nbsp;&nbsp;&nbsp;with\_items:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- "{{'packages.myos' + ansible\_distribution\_major\_version}}"

&nbsp;&nbsp;- shell:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for pkg in "{{lookup('vars', 'packages.myos' ~ ansible\_distribution\_major\_version)}}"; \  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do \  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo "pkg=$pkg"; \  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;done

And the output looks like this:

TASK [debug] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [ldappoc4] =\> (item=packages.myos7) =\>  
&nbsp;&nbsp;ansible\_loop\_var: item  
&nbsp;&nbsp;item: packages.myos7  
&nbsp;&nbsp;packages.myos7:  
&nbsp;&nbsp;- os7package1  
&nbsp;&nbsp;- os7package2  
&nbsp;&nbsp;- os7package3

TASK [shell] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
fatal: [ldappoc4]: FAILED! =\>  
&nbsp;&nbsp;msg: |-  
&nbsp;&nbsp;&nbsp;&nbsp;The task includes an option with an undefined variable. The error was: No variable found with this name: packages.myos7

My data is actually stored in a dictionary. The debug task is able to interpret that but the lookup plugin is not.  
So now what?

---

<div class="post-metadata">

**Author:** ![Kai\_Stian\_Olstad](https://avatars.discourse-cdn.com/v4/letter/k/e19adc/32.png) [@Kai\_Stian\_Olstad](https://forum.ansible.com/u/Kai_Stian_Olstad)\
**Post date:** [July 27, 2019, 3:05pm UTC](https://forum.ansible.com/t/yet-another-dynamic-variable-problem/30851/5 "2019-07-27T15:05:36Z")

</div>

The debug doesn't work eihter, at least not the way you think.

The debug var: takes a variable name and print out the content of that variable.  
As you can see from the above output your item is "item: packages.myos7"

So you  
&nbsp;&nbsp;&nbsp;- debug:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var: "{{item}}"

actually becomes  
&nbsp;&nbsp;&nbsp;- debug:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var: "packages.myos7"

and the content of packages.myos7 is the list  
&nbsp;&nbsp;&nbsp;- os7package1  
&nbsp;&nbsp;&nbsp;- os7package2  
&nbsp;&nbsp;&nbsp;- os7package3

What you need is  
{{ packages['myos' ~ ansible\_distribution\_major\_version] }}

---

<div class="post-metadata">

**Author:** ![mark.tovey](https://avatars.discourse-cdn.com/v4/letter/m/ce73a5/32.png) [@mark.tovey](https://forum.ansible.com/u/mark.tovey)\
**Post date:** [July 30, 2019, 4:01pm UTC](https://forum.ansible.com/t/yet-another-dynamic-variable-problem/30851/6 "2019-07-30T16:01:43Z")

</div>

Okay, that makes sense and looks a lot simpler. I will try that.  
&nbsp;&nbsp;&nbsp;&nbsp;Thanks,  
&nbsp;&nbsp;&nbsp;&nbsp;-Mark

---

<div class="post-metadata">

**Author:** ![mark.tovey](https://avatars.discourse-cdn.com/v4/letter/m/ce73a5/32.png) [@mark.tovey](https://forum.ansible.com/u/mark.tovey)\
**Post date:** [July 30, 2019, 4:28pm UTC](https://forum.ansible.com/t/yet-another-dynamic-variable-problem/30851/7 "2019-07-30T16:28:27Z")

</div>

And that works. The actual 'for' line looks like the following to get one package name per iteration:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for pkg in $(echo "{{packages['myos' ~ ansible\_distribution\_major\_version]|to\_json|regex\_replace('[,\[\]]', '')}}");

&nbsp;&nbsp;&nbsp;&nbsp;But that got me what I am trying to achieve.  
&nbsp;&nbsp;&nbsp;&nbsp;-Mark
