Ansible SSH private key in source control?

Alejandro Ricoveri picture Alejandro Ricoveri · Apr 1, 2015 · Viewed 37.3k times · Source

I have been developing an Ansible playbook for a couple of weeks, therefore, my experience with such technology is relatively short. Part of my strategy includes using a custom ansible_ssh_user for provisioning hosts throughout the inventory, however, such user will need its own SSH key pair, which would involve some sort of a plan for holding/storing its correspondent private key. On a production environment, this playbook would be cloned/pulled and run inside a certain playbook node whose role is to provision the rest of the infrastructure.

At first, I was thinking to just put that private key inside the playbook git repository, but I am having second thoughts about it nonetheless, mostly because of somewhat obvious security reasons and common sense around it, hence the reason I need to consult you about this matter.

With this set on the table, here are the follow-up questions:

  • In an Ansible-based development environment, is it sane/reasonable to hold a private SSH key in source control?
  • Would this practice be advised only for development environments whereas another local git branch inside the playbook node would be then used to hold the actual production SSH private key?
  • Would it be better to address this case scenario via Ansible Vault instead?, I have not ever used this before, but regardless of that I cannot yet tell whether this would be a proper case for using it.
  • In your experience, what would be your approach around this in a production environment?, what would it be considered as the best practice in this particular scenario?

Answer

Ben Whaley picture Ben Whaley · Apr 1, 2015

It's a bad idea to store any kind of plaintext secret in revision control, SSH private keys included. Instead, use ansible-vault to store the private key.

ansible-vault can operate on any file type. Just encrypt the file with

ansible-vault encrypt /path/to/local/private_key

then install the key:

- name: Install a private SSH key
  vars:
    source_key: /path/to/local/private_key
    dest_key: /path/to/remote/private_key
  tasks:
  - name: Ensure .ssh directory exists.
    file: 
      dest: "{{ dest_key | dirname }}"
      mode: 0700 
      owner: user 
      state: directory
  - name: Install ssh key
    copy: 
      src: "{{ source_key }}" 
      dest: "{{ dest_key }}"
      mode: 0600
      owner: user

Earlier versions of ansible-vault would only operate on variables defined in var files, so you had to do something like this:

ssh_key: |
  -----BEGIN RSA PRIVATE KEY-----
  ...
  -----END RSA PRIVATE KEY-----
key_file: /home/user/.ssh/id_rsa

Encrypt with ansible-vault:

ansible-vault encrypt /path/to/var_file

And install the key:

- name: Ensure .ssh directory exists.
  file: 
    dest: "{{ key_file | dirname }}"
    mode: 0700 
    owner: user 
    state: directory

- name: Install ssh key
  copy: 
    content: "{{ ssh_key }}" 
    dest: "{{ key_file }}"
    mode: 0600
    owner: user

Thanks to all those below who improved the answer with their comments.