Ansible – Managing Multiple Remote User Accounts and Pubkeys

ansibleansible-playbook

I'm trying to work out a way to manage a single user's pubkey across multiple sites, as well as dropping that key into multiple $HOME directories. Reason being; our devs login as themselves to check on things, run sudo etc, however they deploy code as a passenger user over SSH so their pubkey needs to be in ~/home/passenger/.ssh/authorized_keys as well.

I'm not sure if changing AuthorizedKeysFile in /etc/ssh/sshd_config would make this less crazy but since I'm almost there with my current playbook, I thought I'd post the question as-is and see what comes of it. Perhaps this would indeed be better solved another way.

In my homedirs.yml file, I create user's home directories (they exist in LDAP) and then move their pubkey into place. This works fine for their own home directory, but the passenger user needs this key as well. Since I may use this playbook for other users and hosts, I have defined a to_user: list which defines which home directories the pubkey should be setup for.

How do I loop over the {{ item.to_user }} list in the authorized_key: play where {{ item.name }} is currently referenced?

playbook

---
- hosts: all
  vars_files:
    - ../group_vars/homedirs.yml
  gather_facts: false

  tasks:
    - name: Set up home directory
      when: inventory_hostname in item.allowed_hosts
      file:
        path: "/home/{{ item.name }}"
        state: directory
        owner: "{{ item.name }}"
        group: "{{ item.group }}"
        mode : 0750
      with_items: "{{ homedirs }}"


    - name: setup ssh pub key
      when: inventory_hostname in item.allowed_hosts
      authorized_key:
        user: '{{ item.name }}'
        state: present
        key: '{{ item.pubkey }}'
      with_items: "{{ homedirs }}"

homedirs.yml

# homedirs.yml
homedirs:
  - name   : usr123
    group  : developers
    pubkey :  "{{ lookup('file', '../group_vars/pubkeys/user123@somehost.pub') }}"
    to_user:
      - user123
      - passenger
    allowed_hosts  :
      - web1.my.com
      - web1.test.my.com

  - name   : usr555
    group  : admin
    pubkey :  "{{ lookup('file', '../group_vars/pubkeys/user555@somehost.pub') }}"
    to_user:
      - user555
      - sysadmin
    allowed_hosts  :
      - blah.blah.host

Best Answer

This is a classic requirement for a with_subelements loop in Ansible:

- name: Set up home directory
  when: inventory_hostname in item.0.allowed_hosts
  file:
    path: "/home/{{ item.1 }}"
    state: directory
    owner: "{{ item.1 }}"
    group: "{{ item.0.group }}"
    mode : 0750
  with_subelements:
    - "{{ homedirs }}"
    - to_user