Convention over configuration or generating list fact from list variable

I want to create users and then authorise their respective ssh public keys.

Following the mantra of convention over configuration, the public key filename can be easily derived from the user name. However, I find myself having to explicitly declare the public key filename for each user because I can’t find a way of generating the public key filenames from the user names (from what I could find out, set_fact doesn’t really support this), and I have to use with_file or a lookup + with_items, which don’t really allow me to interpolate the user name variable inline.

I would suppose this is a fairly common use case, if one is aiming to avoid “code duplication”.

Does anyone have any pointers on how to best deal with cases like this?

–Pedro.

  • name: Set Authorized keys for named user
    action:
    ¦ ¦ ¦ module: authorized_key
    ¦ ¦ ¦ user: “{{ item }}”
    ¦ ¦ ¦ key: “{{ lookup(‘file’, ‘ssh_pub_keys/’ + item + ‘.pub’) }}”
    ¦ ¦ ¦ manage_dir: yes
    ¦ ¦ ¦ state: present
    with_flattened: real_users
    when: user[item] is defined and user[item] != "

Might be useful sharing your datastructure with that example Serge, so people can see how it fits in. In particular I’m not sure where the variable “user” comes in from your example.

In any case, I do agree this is the good part:

“{{ lookup(‘file’, ‘ssh_pub_keys/’ + item + ‘.pub’) }}”

This can be simplified by assigning it to a variable somewhere, as Ansible knows how to lazy-evaluate things such as this, and it won’t “compress” down into the actual value until item is in scope.

user_key: “{{ lookup(‘file’, ‘ssh_pub_keys/’ + item + ‘.pub’) }}”

{{ user_key }}

etc, which would make for a cleaner playbook by a small margin.

Thanks Serge and Michael!

I hadn’t remembered Jinja2 would actually evaluate and expression like ‘ssh_pub_keys/’ + item + ‘.pub’ without any issues.

And Michael’s tip about the lazy evaluation of variables is very interesting and actually more widely applicable than the present concrete case, and it does make for a slightly cleaner playbook.

–Pedro.