You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
7.1 KiB
7.1 KiB
Ansible Vault SSH Key Management Guide
Overview
This document explains how to securely manage SSH private keys using Ansible Vault and the copy module with decryption capabilities, including proper playbook configuration to handle decryption before fact gathering.
Important: Playbook Configuration
Critical Setup Requirements
---
- name: Deploy with encrypted SSH key
hosts: all
gather_facts: false # ⚠️ ESSENTIAL - prevents early SSH connection attempts
vars:
ssh_private_key_file: key/deploy # Path to your encrypted key file
tasks:
# Your decryption and deployment tasks here
Why gather_facts: false is Mandatory
Without gather_facts: false:
- Ansible attempts to connect to target hosts immediately
- It tries to use SSH with the default SSH agent configuration
- Fails because the encrypted key isn't decrypted yet
- Playbook stops before reaching your decryption task
With gather_facts: false:
- Ansible skips the initial fact gathering phase
- Allows your decryption task to run first
- You control when and how the SSH key is used
Step 1: Encrypt SSH Private Key with Ansible Vault
Encrypt an existing SSH key:
# Method 1: Interactive password prompt
ansible-vault encrypt key/deploy --ask-vault-pass
# Method 2: Using a password file
ansible-vault encrypt key/deploy --vault-password-file vault_pass.txt
# Method 3: Using vault ID
ansible-vault encrypt key/deploy --vault-id deploy@vault_pass.txt
Create a new encrypted SSH key:
ansible-vault create key/deploy --vault-password-file vault_pass.txt
Verify encrypted content:
ansible-vault view key/deploy --vault-password-file vault_pass.txt
Step 2: Complete Ansible Playbook Example
Full playbook structure:
---
- name: Deploy using encrypted SSH key
hosts: all
gather_facts: false # CRITICAL: Must be disabled
vars:
ssh_private_key_file: key/deploy
decrypted_key_path: /tmp/ansible_deploy_key
tasks:
- name: Decrypt SSH private key
copy:
src: "{{ ssh_private_key_file }}"
dest: "{{ decrypted_key_path }}"
decrypt: yes
mode: '0600'
delegate_to: localhost
become: false
run_once: true
- name: Enable fact gathering with decrypted key
setup:
delegate_to: localhost
become: false
- name: Use the decrypted key for deployment
ansible.builtin.shell: |
ssh -i "{{ decrypted_key_path }}" \
-o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
deploy@{{ inventory_hostname }} 'deployment_command'
args:
executable: /bin/bash
- name: Remove decrypted SSH key (cleanup)
file:
path: "{{ decrypted_key_path }}"
state: absent
delegate_to: localhost
become: false
always: yes
Step 3: Running the Playbook
Execution methods:
# With password file
ansible-playbook playbook.yml --vault-password-file vault_pass.txt
# Interactive password prompt
ansible-playbook playbook.yml --ask-vault-pass
# With vault ID
ansible-playbook playbook.yml --vault-id deploy@vault_pass.txt
# With inventory file
ansible-playbook -i hosts.ini playbook.yml --vault-password-file vault_pass.txt
Step 4: Advanced Error Handling & Security
Robust playbook with proper error handling:
---
- name: Secure deployment with encrypted SSH key
hosts: all
gather_facts: false
vars:
ssh_private_key_file: key/deploy
decrypted_key_path: "/tmp/ansible_deploy_key_{{ ansible_date_time.epoch }}"
tasks:
- name: Ensure encrypted key file exists
stat:
path: "{{ ssh_private_key_file }}"
register: key_file
delegate_to: localhost
become: false
- name: Fail if encrypted key is missing
fail:
msg: "Encrypted SSH key file {{ ssh_private_key_file }} not found"
when: not key_file.stat.exists
delegate_to: localhost
become: false
- name: Decrypt SSH private key
copy:
src: "{{ ssh_private_key_file }}"
dest: "{{ decrypted_key_path }}"
decrypt: yes
mode: '0600'
delegate_to: localhost
become: false
run_once: true
- name: Verify decrypted key permissions
file:
path: "{{ decrypted_key_path }}"
mode: '0600'
delegate_to: localhost
become: false
- name: Gather facts using decrypted key (if needed)
setup:
delegate_to: localhost
become: false
- name: Perform deployment tasks
block:
- name: Execute remote deployment
ansible.builtin.shell: |
ssh -i "{{ decrypted_key_path }}" \
-o ConnectTimeout=30 \
-o StrictHostKeyChecking=no \
deploy@{{ inventory_hostname }} 'your_deployment_script'
args:
executable: /bin/bash
register: deployment_result
- name: Display deployment output
debug:
var: deployment_result.stdout
rescue:
- name: Handle deployment failure
debug:
msg: "Deployment failed - check SSH connectivity and permissions"
always:
- name: Always remove decrypted key
file:
path: "{{ decrypted_key_path }}"
state: absent
delegate_to: localhost
become: false
Security Best Practices
1. File Security:
# Secure permissions for password files
chmod 600 vault_pass.txt
# Secure permissions for encrypted key
chmod 600 key/deploy
2. Temporary File Safety:
- Use unique temporary filenames with timestamps
- Set strict permissions (0600)
- Always clean up, even on failure
3. Key Management:
- Never store unencrypted keys in version control
- Rotate deployment keys regularly
- Use different keys for different environments
Troubleshooting
Common Issues & Solutions:
-
"Permission denied" errors:
- Verify vault password is correct
- Check encrypted file permissions
- Ensure cleanup tasks run successfully
-
SSH connection failures:
- Verify the decrypted key is authorized on target hosts
- Check network connectivity
- Validate target host accessibility
-
Fact gathering issues:
- Use
gather_facts: falsein main playbook - Manually call
setupmodule after decryption if needed
- Use
Debug Commands:
# Test vault decryption
ansible-vault view key/deploy --vault-password-file vault_pass.txt
# Verify playbook syntax
ansible-playbook playbook.yml --syntax-check
# Dry run to see what would happen
ansible-playbook playbook.yml --vault-password-file vault_pass.txt --check
Summary
The key points for successful encrypted SSH key management:
- Always use
gather_facts: falsein the main playbook - Decrypt the key early in your tasks
- Use unique temporary paths for decrypted keys
- Always clean up decrypted keys, even on failures
- Secure your vault passwords with proper file permissions
This approach ensures your SSH keys remain encrypted at rest and are only temporarily decrypted during execution, maintaining security throughout your deployment process.