Reputation: 381
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?
Upvotes: 9
Views: 27835
Reputation: 3209
Use ansible.posix.authorized_key module:
---
- name: Add public SSH key for user vagrant
hosts: all
tasks:
- name: Add public SSH key to authorized_keys file
ansible.posix.authorized_keys:
user: vagrant
state: present
key: "{{ lookup('file', '/path/to/key.pub') }}"
Here /path/to/key.pub
is the path to public key file on your local machine.
By default this module manage ~/.ssh/authorized_keys
file, but you can define own path with path
key.
Upvotes: 0
Reputation: 68609
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.
Upvotes: 9
Reputation: 11
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.
Upvotes: 1