Hi,
I’m trying to manage user creation with Ansible, but I am having problems getting variable interpolation, task includes and with_items to play nicely together. This is using a recent devel checkout, but it also seems to be a problem in 1.0 and 0.9.
Below is a stripped down example, in which users just have the pubkey attribute defined. The key idea is that a task file create.yml contains a list of tasks which should be executed for each user, and that the main playbook includes that from within a loop and sets the user attributes differently each time round.
tasks:
- include: create_user.yml user="${item}" pubkey="${userdefs.${item}.pubkey}"
with_items: ${users}
I’ve put a fuller example in a gist here, with two versions of create_user.yml trying different variations of the above: https://gist.github.com/wu-lee/4994831. Output of running it is appended.
The problem I find is, when the variables are defined via group_vars/standard_users
, they don’t seem to be interpolated as you’d expect - ${item} becomes “user1,user2”, and not “user1” then “user2” in sequence. This is frustrating since I think the pattern I’m using in createA.yml would be very handy in various other circumstances, when a number of tasks need to be grouped and repeated.
Furthermore, when ${users}
is defined in a vars:
section within the users.yml
playbook, they do result in $item expanding to “user1”, “user2” in sequence. Some subtle interaction between variables, parameterised tasks, and with_items
, it seems? However, I don’t want to have to use a vars:
section because it means I can’t define a different user list by host/group via host_vars/group_vars.
So although it seems like it ought to work, I can’t get it to. Is this a bug?
And evidently other people must do it differently, since I can’t find much evidence anyone else has this problem. Is there any prior art for creating varying sets of users I can emulate? (For now I’ve worked around it by iterating each task in create_user.yml directly in the parent playbook, but it’s not very DRY).
One final point: in cases when a playbook actually fails to interpolate some variables (rather than interpolating them as something odd), Ansible blindly attempts to continue and, say, create users, only failing because the resulting user name is invalid. Wouldn’t it be better if Ansible refused to execute such commands with failed interpolations? I can’t imagine a situation when you’d actually want Ansible to excecute commands containing the unexpanded string “${item}” (for example). On the contrary, I imagine in some circumstances it might be harmful - if the command executes successfully and does something unexpected. (This sort of non-strict behaviour in Puppet has burnt me in the past.)
Cheers,
Nick