1

I want to do something very similar as mentioned in How can I have a nested loop with a fileglob pattern? except that the list of files is a glob pattern which refers to the items from the outer loop.

My (failing) code so far:

    - name: Deploy authorized_keys files for users
      authorized_key:
        user: "{{ item }}"
        key: "{{ query('fileglob', 'ssh-pub-keys/{{ item }}/*.pub') }}"
      with_list:
        - user1
        - user2

The directory ssh-pub-keys looks as follows:

ssh-pub-keys
├── user1
│   ├── hostA_id_ecdsa.pub
│   ├── hostA_id_ed25519.pub
│   ├── hostB_id_ecdsa.pub
│   ├── hostB_id_ed25519.pub
│   └── hostB_id_rsa.pub
└── user2
    ├── hostC_id_ecdsa.pub
    ├── hostC_id_rsa.pub
    ├── hostD_id_ecdsa.pub
    └── hostD_id_ed25519.pub

The error message looks like this:

failed: [somehost] (item=user1) => {"changed": false, "item": "user1", "msg": "invalid key specified: ['…/ssh-pub-keys/user1/hostA_id_ecdsa.pub', '…/ssh-pub-keys/user1/hostA_id_ed25519.pub', …]"}
failed: [somehost] (item=user2) => {"changed": false, "item": "user2", "msg": "invalid key specified: ['…/ssh-pub-keys/user2/hostC_id_ecdsa.pub', '…/ssh-pub-keys/user2/hostC_id_rsa.pub', …]"}

I don't seem to be able to use with_nested as I can't refer from the one list to other one.

Also tried Ansible/Jinja2 filters like loop: {{ ['user1','user2'] | product(query(('fileglob', 'ssh-pub-keys/{{ ??? }}/*.pub'')) | list }}, but didn't figure out how to refer to the items from the first list inside product(…)

Another try was to use two tasks with the second referring to the first's registered output, but I didn't figure out how to make shell output into a proper data structure (output split by space, but keeping the information which input item was used) again:

    - name: Enumerate all authorized_keys files for all users
      shell: "echo ssh-pub-keys/{{ item }}/*.pub"
      with_list:
        - user1
        - user2
      register: keyfiles

Anyone knows how these kind of tasks are implemented properly?

P.S.: Using Ansible 2.7.7 as available in Debian 10 Buster (current Debian stable release).

Axel Beckert
  • 398
  • 2
  • 17

1 Answers1

1

It's possible to concatenate the keys. Quoting from authorized_key:

Multiple keys can be specified in a single key string value by separating them by newlines.

For example

- name: Deploy authorized_keys files for users
  authorized_key:
    user: "{{ item }}"
    key: |
      {% for fn in lookup('fileglob', 'ssh-pub-keys/' ~ item ~ '/*.pub', wantlist=True) %}
      {{ lookup('file', fn) }}
      {% endfor %}
  loop:
    - user1
    - user2
Vladimir Botka
  • 5,138
  • 8
  • 20