How to generate host SSH keys via ansible?
Solution 1:
As far as I know the only reason why you would need to pipe a 'y' to ssh-keygen, is if your command is replacing an existing file. In my opinion this is not a good way to do something from a configuration management tool.
You should adjust your tasks to make them idempotent. Specifically if you add the creates: filename
to your command, then the new keys will only be created when they don't already exist, instead of being replaced each time you run that playbook.
---
- hosts: all
become: true
gather_facts: false
tasks:
- name: Generate /etc/ssh/ RSA host key
command : ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -C "" -N ""
args:
creates: /etc/ssh/ssh_host_rsa_key
- name: Generate /etc/ssh/ DSA host key
command : ssh-keygen -q -t dsa -f /etc/ssh/ssh_host_dsa_key -C "" -N ""
args:
creates: /etc/ssh/ssh_host_dsa_key
- name: Generate /etc/ssh/ ECDSA host key
command : ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -C "" -N ""
args:
creates: /etc/ssh/ssh_host_ecdsa_key
If for some reason you wanted to replace those keys for example if they were too old or something you might want to add another task to remove them. Here is a simple delete
- file:
state: absent:
path: "{{item}}"
loop:
- /etc/ssh/ssh_host_rsa_key
- /etc/ssh/ssh_host_dsa_key
- /etc/ssh/ssh_host_ecdsa_key
If you wanted to delete files generated before a certain time, you could use the stat module to retrieve details about this files, and setup when
conditions to selectively remove them if they were older then a certain date or something.
Solution 2:
The ansible command
module does not pass commands through a shell. This means you can't use shell operators such as the pipe, and that is why you are seeing the pipe symbol in the output. As far as ansible is concerned, it has executed the command echo
with all of the rest of the line as arguments to echo
.
If you need the command line processed by a shell, use shell
instead of command
.
And, there ought to be a better way to regenerate ssh host keys, but I can't find one right now...
Solution 3:
Use the special module for this task:
- name: Generate an OpenSSH keypair with the default values (4096 bits, rsa)
openssh_keypair:
path: /home/youruser/.ssh/id_rsa
owner: youruser
group: youruser
- name: Fix owner of the generated pub key
file:
path: /home/youruser/.ssh/id_rsa.pub
owner: youruser
group: youruser
Solution 4:
Another option is to use user module. Positive side of this is that you'll get an idempotent task. Here is an example how to generate ssh keys on localhost:
- name: Generate ssh keys
local_action:
module: "user"
name: "{{ lookup('env','USER') }}"
generate_ssh_key: true
ssh_key_type: "{{ item.0 }}"
ssh_key_bits: "{{ item.1 }}"
ssh_key_file: "{{ playbook_dir }}/{{ item.0 }}_{{ item.1 }}_key"
with_together:
- [ 'rsa', 'dsa' ]
- [ 2048, 1024 ]
loop_control:
label: "{{ item.0 }}_{{ item.1 }}_key"
- name: Copy generated ssh keys to remote machine
copy:
src: "{{ playbook_dir }}/{{ item.0 }}_{{ item.1 }}_key"
dest: "/etc/ssh/ssh_host_{{ item.0 }}_key{{ item.1 }}"
with_nested:
- [ 'rsa', 'dsa' ]
- [ '', '.pub' ]
notify:
- Restart sshd
loop_control:
label: "/etc/ssh/ssh_host_{{ item.0 }}_key{{ item.1 }}"