Passing complex variables to a role

I’m currently stuck on a bit of an issue trying to pass complex variables to a role that I’ve created, please see this Gist for an example:

https://gist.github.com/Synforge/9665085

I’m currently using Ansible with hash_behaviour merge as I want to manage configuration parameters as a hash and then override some of the default variables using host_vars and group_vars without having to specify all mysql parameters.

In the example above I have a mysql role that has various defaults as a hash for the configuration file, the idea is that with merge I can override some of these parameters by passing in a complex variable from my host_vars folder. I have host_vars set up so that at the moment it only overrides the server_id parameter.

The issue that I’m having is that the hashes seem to be being passed in as a string to the role (I’ve tried old style variable and new style variable substitution without any luck) so I get this trace when it attempts to merge the hashes together:

fatal: [mysql-master-1.example.org] => Traceback (most recent call last): File "/home/paul/dev/ansible/lib/ansible/runner/__init__.py", line 527, in _executor exec_rc = self._executor_internal(host, new_stdin) File "/home/paul/dev/ansible/lib/ansible/runner/__init__.py", line 562, in _executor_internal inject = utils.combine_vars(inject, self.module_vars) File "/home/paul/dev/ansible/lib/ansible/utils/__init__.py", line 1060, in combine_vars return merge_hash(a, b) File "/home/paul/dev/ansible/lib/ansible/utils/__init__.py", line 545, in merge_hash result[k] = merge_hash(a[k], v) File "/home/paul/dev/ansible/lib/ansible/utils/__init__.py", line 540, in merge_hash for k, v in b.iteritems(): AttributeError: 'str' object has no attribute 'iteritems'

Can anyone confirm whether this is an error with my configuration or a known issue?

Many thanks,
Paul

I see you are still using legacy variables here.

Please switch to {{ foo }}, which is the only option available starting in 1.6, and let us know if you still have problems.

However without seeing the source to the role, I can’t tell how this is being used.

A traceback is always worthy of a bug report – but it looks like we will need more information in order to reproduce the problem.

I can confirm the issue still exists when using the newer style variables.

I’ve created an example minimal repo that demonstrates this issue:

https://github.com/Synforge/ansible-example

I’ll create a bug report on github now for that issue, looking at the source it looks like I’m not supposed to use it in this way and instead the host_vars and group_vars will be merged when the role configuration is evaluated. The only issue with this at the moment is I use roles more than once (I’m not sure if this is good practice or not), for example we have some boxes with more than one redis instance and it’s nice when you can simply re-use the role to create multiple instances on different ports. But the way that host_vars and group_vars are currently evaluated means that I can’t provide distinct configurations to each individual invocation of that role.

Please let me know if this is a fundamental misunderstanding by me of how this should be used. Many thanks.

“I’ll create a bug report on github now for that issue, looking at the source it looks like I’m not supposed to use it in this way and instead the host_vars and group_vars will be merged when the role configuration is evaluated.”

I’m not sure where that assumption was drawn, but it should be possible to pass arbitrary datastructures to roles.

There’s probably just an extra call to the template system needed somewhere.