Generate SSH keys using Ansible

Generate SSH keys using Ansible

While working on a project, I noticed I needed to generate SSH keys using Ansible to configure my Ubuntu servers. Usually I would do that with the help of ssh-keygen… That could indeed take the form of a shell task. But I always attempt to find an Ansible module that would do that in a neater way… Here’s a couple of options I’ve found.

Generate SSH keys using Ansible’s “openssh_keypair”

The openssh_keypair module was made available in Ansible from version 2.8. It does exactly what we need to do, and it does it in the simplest possible way:

- name: generate SSH key
  hosts: 127.0.0.1
  connection: local

  vars:
    ssh_key_filename: id_rsa_myproject

  tasks:

    - name: generate SSH key "{{ssh_key_filename}}"
      openssh_keypair:
        path: "~/.ssh/{{ssh_key_filename}}"
        type: rsa
        size: 4096
        state: present
        force: no

The playbook above connects to the localhost, since we want to generate the SSH keys in our local “.ssh” folder. And the only task defined is pretty much self-explicit! Even so you may want to pay attention to that “force” parameter. In this case its “no” value means that your keys won’t be overwritten should you run this playbook multiple time. In contrast a value of “yes” would create new keys at each run.

You can find here the full documentation for this module. It exposes an expansive set of options… except for one very important one!

At the time of writing this, the module does not provide an option to protect the key with a passphrase! And I really want to protect my keys!

Generate SSH keys using Ansible’s “user”

I normally use the user module to create users remotely. But I found out I could use the module to generate SSH keys locally… provided that I work around a few gotchas.

So I ended up with this playbook:

- name: generate SSH key
  hosts: 127.0.0.1
  connection: local

  vars:
    ssh_key_filename: id_rsa_myproject

  vars_prompt:
    - name: "ssh_passphrase"
      prompt: "Enter the passphrase for the SSH key"

  tasks:

    - name: generate SSH key "{{ssh_key_filename}}"
      user:
        name: "{{ansible_user}}"
        generate_ssh_key: yes
        ssh_key_type: rsa
        ssh_key_bits: 4096
        ssh_key_file: .ssh/{{ssh_key_filename}}
        ssh_key_passphrase: "{{ssh_passphrase}}"
        force: no

Still using a local connection, the playbook begins by prompting for the SSH passphrase. Then the task skips all parameters related to user creation, and keeps only those for SSH keys creation. However the “ssh_key_passphrase” parameter now protects our private key!

Pay attention to the “name” parameter. Indeed, you must indicate your login user in that field, so that Ansible saves the SSH keys in your “.ssh” folder. If you use any other username, then the playbook will attempt to create a user account on your local machine. And since you probably don’t run the playbook as “sudo”, Ansible will likely raise a complaint.

Okay, try it out!

ansible-playbook generate-ssh.yaml

Conclusion

And so we have a couple of options to generate SSH keys using Ansible!

If you don’t want a passphrase on your keys, you can go with “openssh_keypair“. But if like me you’d rather add an extra layer of protection, you can leverage the “user” module. Your choice!

Of course the next step would be to add your SSH key to the list of authorized keys on your remote servers. But I will discuss that another day…

Aw okay, just a hint then: look for that “authorized_key” module đŸ˜‰

Cheers!

[Image by Hans Braxmeier from Pixabay]

Leave A Comment

Please be polite. We appreciate that. Your email address will not be published and required fields are marked

This site uses Akismet to reduce spam. Learn how your comment data is processed.