defining package lists across roles

Hi.

Another semi-related question arose while I was installing packages.

I have roles named "smtp-server", "imap-server", and so on; and in each
role I have a task that does essentially the same thing:

    - apt: pkg=$item state=installed
      with_items: [ foo, bar, … ]

Now, this works fine, but I started wondering if I could do this in one
task[*]. For example, I could have roles/common/tasks/packages.yml that
does:

    - apt: pkg=$item state=installed
      with_items: packages

…where "packages" is a variable defined via vars/main.yml by each role:

    - packages: [ postfix, dovecot, … ]

This sounds good, but unfortunately, there's no way to append to the
"packages" list in successive vars/main.yml files.

As far as I can tell, the "hash_behaviour=merge" setting doesn't really
help here, because it merges only hashes, not lists.

At the moment, the solution I've settled for is to remove *all* package
installation from the individual roles, and just put the whole package
list into roles/common/tasks/packages.yml. Obviously, this works, but
it "would be nice" to have each role declare its dependencies.

Can anyone suggest a neat way to do this or something like it? Each role
should be able to declare packages it wants, but they should be combined
into a single apt transaction somewhere.

-- ams

1. One good reason to do this in one place is to not sprinkle handling
   of policy-rc.d across tasks, but I can think of other reasons. And
   at least one other person on IRC independently expressed a desire
   to build up package lists in this way in the past few days.

“This sounds good, but unfortunately, there’s no way to append to the
“packages” list in successive vars/main.yml files.”

This is true.

You can add to hash variables if you configure the merging policy in ansible.cfg but you can’t append to variables.

It would be fine to just have seperate apt statements that operate on the specific lists – invoking apt a few extra times should be fine.

Excerpts from Michael DeHaan's message of 2013-08-13 20:34:22 -0400:

It would be fine to just have seperate apt statements that operate on the
specific lists -- invoking apt a few extra times should be fine.

If you're really concerned with multiple transactions, you could do
something like:

    - apt: pkg={{item}} state=installed
      with_flattened:
        - list_of_common_packages
        - list_of_role_specific_packages