Yet another dynamic variable problem

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?

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

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) =>
  ansible_loop_var: item
  item: myos7
  myos7:
  - os7package1
  - os7package2
  - os7package3

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

    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.
    It has been a long day, sometimes just walking away for a bit makes all the difference in the world.
    Thanks,
    -Mark

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

vars:
    packages:
      myos7:
          - os7package1
          - os7package2
          - os7package3

      myos8:
          - os8package1
          - os8package2
          - os8package3

  - debug:
        var: "{{item}}"
    with_items:
        - "{{'packages.myos' + ansible_distribution_major_version}}"

  - shell:
        for pkg in "{{lookup('vars', 'packages.myos' ~ ansible_distribution_major_version)}}"; \
        do \
            echo "pkg=$pkg"; \
        done

And the output looks like this:

TASK [debug] *******************************************************************
ok: [ldappoc4] => (item=packages.myos7) =>
  ansible_loop_var: item
  item: packages.myos7
  packages.myos7:
  - os7package1
  - os7package2
  - os7package3

TASK [shell] *******************************************************************
fatal: [ldappoc4]: FAILED! =>
  msg: |-
    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?

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
   - debug:
       var: "{{item}}"

actually becomes
   - debug:
       var: "packages.myos7"

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

What you need is
{{ packages['myos' ~ ansible_distribution_major_version] }}

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

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

        for pkg in $(echo "{{packages['myos' ~ ansible_distribution_major_version]|to_json|regex_replace('[,\[\]]', '')}}");

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