4
votes

I'm programming a simple task with Ansible to create a user and add an existing RSA public key. This is the code I wrote:

- name: SYSTEM - Create test user
  tags: system-user
  user: 
        name: "{{ test_user }}"
        state: present
        createhome: yes

- name: SYSTEM - Add existing pub key for test user
  tags: system-user
  copy: 
       content: "{{ test_user_pubkey }}"
       dest: "/tmp/test_user_id_rsa.pub"
       force: no
       owner: "{{ test_user }}"
       group: "{{ test_user }}"
       mode: 0600

- name: SYSTEM - Set authorized key for test_user took from file
  tags: system-user
  authorized_key:
        user: "{{ test_user }}"
        state: present
        key: "{{ lookup('file', '/tmp/test_user_id_rsa.pub') }}"

The code I wrote is not elegant and I think that the best option will be to add the existing RSA public key with the user creation block in order to create and filled up the authorized_keys file.

I've read the Ansible user module but ssh_key_file method does not include the possibility to echo the value of an existing pub key to the authorized_keys file (the end purpose is to be able to remote connect with ssh using the user and the private key).

ssh_key_file = Optionally specify the SSH key filename. If this is a relative filename then it will be relative to the user's home directory.

Is it possible with Ansible to manage this process within the user module?

2
So you wrote some code and have not even bothered to try it before posting to StackOverflow? Because it will fail on execution. It will say /tmp/test_user_id_rsa.pub does not exist (unless you have mess on your local computer).techraf
You right for the error message, I got it during my test but I forgot to mention it in the post. I'm going to edit it for clarification and will be more careful for my future post. Furthermore I'm not too sure why I'm getting it with the code because the file exist after the copy was run.Alexandre Roux

2 Answers

4
votes

The answer to your problem is:

- name: SYSTEM - Create test user
  tags: system-user
  user: 
    name: "{{ test_user }}"
    state: present
    createhome: yes

- name: SYSTEM - Set authorized key for test_user took from file
  tags: system-user
  authorized_key:
    user: "{{ test_user }}"
    state: present
    key: "{{ test_user_pubkey }}"

That's all that is needed.


Regarding your reading of the documentation, ssh_key_file pertains to generating an SSH key pair, which is not what you want.

0
votes

So I've been lurking this thread trying to get this wrapped around my head.. And I ended up being able to make my way around this.

First things first, I tend to cram everything in dicts and then use | dict2items whenever I need to loop within jinja2.

My main problem is that once the user module generates the ssh_keys, there are no clean ways to use the authorized_key module with what you just made (or so I think? I am probably not the smartest guy in here) without bending Ansible in ways impossible (slurping? it is impossible to place another variable within a variable (from what I've tried)"{{ slurp_{{ item.key }} | b64decode }}" seem undoable)

So if you are using massive loops and unwilling to copy all keys to your localhost (which honestly is time consuming), I've found this sneaky trick that does not make reading your code an Olympian challenge :

- name: Prepare the SFTP user
  user:
    name: "{{ item.key }}"
    groups: sftp_users
    home: /home/{{ item.key }}
    password: "{{ impossible_sftp_pass }}"
    generate_ssh_key: yes
    ssh_key_file: .ssh/id_rsa
    shell: /bin/nologin
  with_dict: "{{ instances }}"

- name: sneaky way to get the keys right
  shell: cat /home/{{ item.key }}/.ssh/id_rsa.pub > /home/{{ item.key }}/.ssh/authorized_keys
  args:
    creates: /home/{{ item.key }}/.ssh/authorized_keys
  with_dict: "{{ instances }}"

In this example, our goal is to setup an STFP bastion host that will finally rsync SFTP data repos to the appropriate web fronts that are within a private network.