Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible SSH private key in source control?

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?
like image 550
Alejandro Ricoveri Avatar asked Apr 01 '15 13:04

Alejandro Ricoveri


People also ask

Where does Ansible store SSH keys?

ansible uses a user to connect to the target machine. So if your user is ubuntu ( -u ubuntu in ansible flags) the key will be ~ubuntu/. ssh/authorized_keys on target machine).

Do Ansible need SSH key?

By default, Ansible assumes you are using SSH keys to connect to remote machines. SSH keys are encouraged, but you can use password authentication if needed with the --ask-pass option.


2 Answers

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.

like image 174
Ben Whaley Avatar answered Sep 23 '22 17:09

Ben Whaley


Since you are provisioning from scratch, you should generate the private/public key pair on the playbook node and then distribute the public key via the authorized_keys module. This would eliminate the need to store a secret anywhere except on the host where it is needed. Here is a playbook to achieve this, which would be executed on the playbook node:

--- - hosts: 127.0.0.1   sudo: yes   gather_facts: no   tasks:    - name: create ansible_ssh_user locally     user: name=ansible_ssh_user generate_ssh_key=yes ssh_key_bits=2048 ssh_key_file=.ssh/id_rsa    - name: copy the generated public key to an accessible location for the next play     shell: cp ~ansible_ssh_user/.ssh/id_rsa.pub /tmp/ansible_ssh_user.pub  - hosts: all   sudo: yes   gather_facts: no   tasks:    - name: create ansible_ssh_user     user: name=ansible_ssh_user groups=group1,group2    - name: Add RSA public key to the remote host     authorized_key: user=ansible_ssh_user key="{{ lookup('file', '/tmp/ansible_ssh_user.pub') }}"  - hosts: 127.0.0.1   sudo: yes   gather_facts: no   tasks:    - name: remove public key from /tmp     shell: rm /tmp/ansible_ssh_user.pub ... 
like image 27
gmoon Avatar answered Sep 21 '22 17:09

gmoon