Create user with ssh key, error deploying key

Need help with the error I’m getting trying to create users with ssh keys. It creates the user fine but when it comes time to deploy the ssh key it fails. I’ve tried this using a couple different playbooks and both similarly error out. I believe this was the online guide I followed. I’ve looked at so many I can’t recall:
https://medium.com/@khandelwal12nidhi/setup-ssh-key-and-initial-user-using-ansible-playbook-61eabbb0dba4

Playbook

`

tasks:

  • name: Create Users
    user:
    name: joe
    shell: /bin/bash

  • name: Add user to the sudoers
    copy:
    dest: “/etc/sudoers.d/joe”
    content: “joe ALL=(ALL) NOPASSWD: ALL”

  • name: Deploy SSH Key
    authorized_key: user=joe
    key=“{{ lookup(‘file’, ‘roles/manage-ssh-users/files/joe_id_rsa.pub’) }}”
    state=present

`

Error:

`

fatal: [test.preprod.io]: FAILED! => {
“changed”: false,
“module_stderr”: “OpenSSH_7.4p1 Debian-10+deb9u6, OpenSSL 1.0.2u 20 Dec 2019\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: /etc/ssh/ssh_config line 19: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug2: fd 3 setting O_NONBLOCK\r\ndebug2: mux_client_hello_exchange: master version 4\r\ndebug3: mux_client_forwards: request forwardings: 0 local, 0 remote\r\ndebug3: mux_client_request_session: entering\r\ndebug3: mux_client_request_alive: entering\r\ndebug3: mux_client_request_alive: done pid = 18482\r\ndebug3: mux_client_request_session: session request sent\r\ndebug1: mux_client_request_session: master session id: 2\r\nTraceback (most recent call last):\n File "", line 113, in \n File "", line 105, in _ansiballz_main\n File "", line 48, in invoke_module\n File "/tmp/ansible_authorized_key_payload_bQp3_I/main.py", line 678, in \n File "/tmp/ansible_authorized_key_payload_bQp3_I/main.py", line 673, in main\n File "/tmp/ansible_authorized_key_payload_bQp3_I/main.py", line 572, in enforce_state\n File "/tmp/ansible_authorized_key_payload_bQp3_I/main.py", line 439, in parsekey\nIndexError: list index out of range\ndebug3: mux_client_read_packet: read header failed: Broken pipe\r\ndebug2: Received exit status from master 1\r\n”,
“module_stdout”: “”,
“msg”: “MODULE FAILURE\nSee stdout/stderr for the exact error”,
“rc”: 1
}

`

Version info:

`

ansible@ansible:~$ ansible --version
ansible 2.7.10.post0
config file = /home/ansible/ansible.cfg
configured module search path = [u’/home/ansible/.ansible/plugins/modules’, u’/usr/share/ansible/plugins/modules’]
ansible python module location = /usr/local/lib/python2.7/dist-packages/ansible-2.7.10.post0-py2.7.egg/ansible
executable location = /usr/local/bin/ansible
python version = 2.7.13 (default, Sep 26 2018, 18:42:22) [GCC 6.3.0 20170516]

`

Config:

`

[defaults]
inventory = ./hosts
log_path = /var/log/ansible.log
retry_files_enabled = False
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
ssh_arg = -o ServerAliveInterval=30 -o ControlMaster=auto -o ControlPersist=60s
pipelining = True
[accelerate]
[selinux]
[colors]

`

Joe,

If the path to the ssh key is in the current Role, you could just write is as:

key=“{{ lookup(‘file’, ‘files/joe_id_rsa.pub’) }}”
state=present

If that doesn’t work I would try putting the key in the same directory as the playbook and just do:

key=“{{ lookup(‘file’, ‘./joe_id_rsa.pub’) }}”
state=present

I believe the lookup will look for ‘files’ in the files directory off the root of the playbook or role just like copy or template would. Or you could use an absolute path to the key file.

I appreciate the suggestion though I don’t believe that is the solution to my problem, right? I suppose I should have posted the actual playbook I’m working with. The one previously provided was just a test one.

Here’s the task yml file within the role

`

  • include_vars: users.yml

  • name: Create Users On VMs
    user: name=“{{ item.username }}”
    with_items: “{{ users }}”
    #shell: /bin/bash
    #groups:

  • name: Add .ssh Keys and Directories
    authorized_key: >
    user=“{{item.username}}”
    key=“{{ lookup(‘file’, ‘./files/{{ item.username}}_id_rsa.pub’)}}”
    with_items: “{{ users }}”

`

Error

`

failed: [test.preprod.io] (item={u’username’: u’joe’}) => {
“changed”: false,
“item”: {
“username”: “joe”
},
“module_stderr”: “OpenSSH_7.4p1 Debian-10+deb9u6, OpenSSL 1.0.2u 20 Dec 2019\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: /etc/ssh/ssh_config line 19: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug2: fd 3 setting O_NONBLOCK\r\ndebug2: mux_client_hello_exchange: master version 4\r\ndebug3: mux_client_forwards: request forwardings: 0 local, 0 remote\r\ndebug3: mux_client_request_session: entering\r\ndebug3: mux_client_request_alive: entering\r\ndebug3: mux_client_request_alive: done pid = 22809\r\ndebug3: mux_client_request_session: session request sent\r\ndebug1: mux_client_request_session: master session id: 2\r\nTraceback (most recent call last):\n File "", line 113, in \n File "", line 105, in _ansiballz_main\n File "", line 48, in invoke_module\n File "/tmp/ansible_authorized_key_payload_GKpQf3/main.py", line 678, in \n File "/tmp/ansible_authorized_key_payload_GKpQf3/main.py", line 673, in main\n File "/tmp/ansible_authorized_key_payload_GKpQf3/main.py", line 572, in enforce_state\n File "/tmp/ansible_authorized_key_payload_GKpQf3/main.py", line 439, in parsekey\nIndexError: list index out of range\ndebug3: mux_client_read_packet: read header failed: Broken pipe\r\ndebug2: Received exit status from master 1\r\n”,
“module_stdout”: “”,
“msg”: “MODULE FAILURE\nSee stdout/stderr for the exact error”,
“rc”: 1
}

`

Perhaps your ssh key file is somehow malformed? What happens if you go old-school and use ssh-copy-id to try to copy over the key file that way? At least you’ll know if it’s a problem with your key or the playbook (and if it works with ssh-copy-id of course you can just delete it off the target host when you are ready to retry with your ansible playbook).

parsekey
IndexError: list index out of range

Pretty much says it - something is wrong with the pubkey, in the sense
that the authorized_key module can parse it (see
modules/system/authorized_key.py).
LIkely something with the options of the pubkey, their quoting, or
something with comments (#)?

What does your pubkey look like?

Awesome, thanks for the assist. I created a new key using RSA and it’s working. Does ansible not work with ecdsa? That’s the only difference in the two pub keys I used

Depends which ecdsa, there are 3 of them:

https://github.com/ansible/ansible/blob/stable-2.9/lib/ansible/modules/system/authorized_key.py#L400-L407

I couldn’t remember but I checked the key and it’s in ecdsa-sha2-nistp256 format. I’ll play around with this and troubleshoot more, I’m just glad the mechanics are working and can work on improving it. I’m still somewhat novice to ansible but learning quite a bit lately.

This same task I’m trying to ensure the user is created with /bin/bash shell and I thought that was the default but it doesn’t get appended to my user account after creation. When I try to add it to the file it errors out interpreting it as another task. Any idea how I rectify this one?

`

I couldn't remember but I checked the key and it's in ecdsa-sha2-nistp256 format. I'll play around with this and
troubleshoot more, I'm just glad the mechanics are working and can work on improving it. I'm still somewhat novice to
ansible but learning quite a bit lately.

This same task I'm trying to ensure the user is created with /bin/bash shell and I thought that was the default but it
doesn't get appended to my user account after creation. When I try to add it to the file it errors out interpreting it
as another task. Any idea how I rectify this one?

Module parameters needs to be intended (e.g. shell), task parameters (e.g. with_items) are on the same level as the task.

This should do the trick:

- name: Create Users On VMs
  user:
    name: "{{ item.username }}"
    shell: /bin/bash
  with_items: "{{ users }}"

Regards
          Racke

That did it, thanks. I’ve been struggling with yaml spacing lately. I’ve installed yamllint and ansible-lint but in some cases they don’t necessarily help if you don’t understand proper formatting to begin with. I’ve got some learning to do here.

Any suggestion on the best way to execute user creation and deletion based on conditional access? For example only the dev guys get access to dev systems, qa get accounts on qa systems. My thought was to create different user files for each group and then when running the playbook specify the host groups. I’m not sure how to get the users set up like a host file in groups or if this is possible. Maybe I’m over thinking this and there’s a simpler way that this has been done.