Greetings,
We have long list of packages with versions that change frequently, those packages need to be installed on quite a lot of servers but each server needs a different combination of those packages. Defining a role or set of group vars that lists each package and it’s version works fine except that managing the versions is very unwieldy because the versions change daily and we need to maintain parallel stacks of servers that have different package versions.
The way I have it working is with a central list of all packages in a var file with their versions, then group var files that list the packages that need to be installed. The play iterates over the central package list for each item in the group vars file to find a name match and grab the version. This is working great except for one highly annoying issue, when the playbooks run it outputs ‘skipping’ for each package from the central file that isn’t matched to the current item in the group var list. With many dozen packages and many dozen hosts this results in an overwhelming stream of ‘skipping’ messages, it also seems like it’s fairly inefficient and could eventually run into scale issues.
Here is roughly how it’s setup:
Not sure why you are keeping the list of multiple versions in there, but sounds like you should define a nested datastructure or an array or something.
Looks like you want to look up a package version by package name:
## Vars file
version_for_package:
foo: 1.1.19-1
bar: 3.11.0-6
baz: 6.11.1-1
...
## Task
- name: update packages
action: yum name={{ item }}-{{ version_for_package[item] }} state=present
with_items: packages
Kahlil (Kal) Hodgson GPG: C9A02289
Head of Technology (m) +61 (0) 4 2573 0382
DealMax Pty Ltd (w) +61 (0) 3 9008 5281
Suite 1415
401 Docklands Drive
Docklands VIC 3008 Australia
"All parts should go together without forcing. You must remember that
the parts you are reassembling were disassembled by you. Therefore,
if you can't get them together again, there must be a reason. By all
means, do not use a hammer." -- IBM maintenance manual, 1925
Thanks so much Kal, that did the trick. I suspected something like that was possible but I couldn’t find a good example.
Being new to ansible the syntax has been a bit frustrating to muddle through which is part of what had me stumped here. The many real world examples in the documentation are very helpful but it’s difficult to find a straight description of how things work. I suspect it’s because there is assumption that YAML is described elsewhere but it would be helpful if there was a formatting/syntax guide was direct explanations instead of relying on examples. For example, in this case ${variable} is behaving differently than {{variable}} and my initial searching isn’t revealing exactly what the differences are without having to infer it from a collection of examples.
Glad that helped
Just to note, the {{ variable }} syntax is preferred over the old
${variable} syntax, and I believe there are plans to remove the old
syntax in version 1.5.
K
Kahlil (Kal) Hodgson GPG: C9A02289
Head of Technology (m) +61 (0) 4 2573 0382
DealMax Pty Ltd (w) +61 (0) 3 9008 5281
Suite 1415
401 Docklands Drive
Docklands VIC 3008 Australia
"All parts should go together without forcing. You must remember that
the parts you are reassembling were disassembled by you. Therefore,
if you can't get them together again, there must be a reason. By all
means, do not use a hammer." -- IBM maintenance manual, 1925
It’s going to be removed in 1.6 but already throws deprecation warnings.
As for YAML, http://docs.ansible.com/YAMLSyntax.html
Thanks, that page is a good representation of where examples are used when a less conversational tone would also be helpful. Don’t get me wrong, the examples are really great but they tend to break down as soon as you want to something outside of the norm. Using that page as an example it would be helpful to see a straight list of all special characters that the YAML interpreter will key off of and what they mean, two things that jump to mind are comments and single brackets (which were instrumental in my problem). Single brackets aren’t listed at all and comments aren’t mentioned beyond an appearance in one of the examples (it is admittedly trivial to figure out comments from the example).
My experience so far is that it’s been wonderfully easy to find examples how to do the normal things but it becomes an exercise in trial and error when you can’t find a close example to work off of.
" Don’t get me wrong, the examples are really great but they tend to break down as soon as you want to something outside of the norm."
Ansible is a KISS system. I would recommend asking questions like “how do I do this” on the mailing list rather than “here’s something I did complicated, please fix” and you will get more idiomatic answers. What you are doing, with having multiple versions of bloop as hashes in a single list is weird, and you’ll get better examples of “how would I model something like this”, rather than us trying to tweak your example, and you’ll learn a bit more in the process too.
“My experience so far is that it’s been wonderfully easy to find examples how to do the normal things but it becomes an exercise in trial and error when you can’t find a close example to work off of.”
We prefer including best practices examples and things that are idiomatic of the way Ansible should be used in the field rather than arbitrary examples most of the time.
As you have probably found in the docs you should also look at:
http://github.com/ansible/ansible-examples
For some complete things, used end to end.
Well ideological quibbles aside it turns out the method above isn’t working as well as I’d initially though and it seems like there might be some inconsistent behavior with the yum module. My initial test had only one rpm defined for a host and that worked, but adding any additional RPMS to the group var file fails with:
One or more undefined variables: ‘dict’ object has no attribute ‘foo, baz’
Inserting a debug line in place of the yum call shows that it seems to be looping correctly:
debug: msg=“yum name={{ item }}-{{ package_versions[item] }} state=present”
yields:
ok: [host1] => (item=foo) => {“item”: “foo”, “msg”: “yum name=foo-1.1.19-1 state=present”}
ok: [host1] => (item=baz) => {“item”: “baz”, “msg”: “yum name=baz-6.11.1-1 state=present”}
I believe the yum module condenses with_items lists to run a single invocation of yum rather than repeatedly for each item and I wonder if that is somehow being tripped up by the nested data structure.
Also, if it’s relevant this is ansible 1.3.4 (I cannot upgrade immediately but will be in the very near future)