Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions etc/kayobe/ansible/rekey-hosts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
---
# Playbook to rotate SSH keys across the cloud. By default it will rotate the
# standard keys used by kayobe/kolla-ansible, but it can be configured for any
# keys.

- name: Rekey hosts
hosts: overcloud,seed,seed-hypervisor,infra-vms
gather_facts: false
vars:
# The existing key is the key that is currently used to access overcloud hosts
existing_private_key_path: "{{ ssh_private_key_path }}"
existing_public_key_path: "{{ ssh_public_key_path }}"
# The new key is the key that will be generated by this playbook
new_private_key_path: "{{ ssh_private_key_path }}"
new_public_key_path: "{{ ssh_public_key_path }}"
new_key_type: "{{ ssh_key_type }}"
# The existing key will locally be moved to deprecated_key_path once it is replaced
deprecated_key_path: ~/old_ssh_key
rekey_users:
- stack
- kolla
rekey_remove_existing_key: false
tasks:
- name: Stat existing private key file
ansible.builtin.stat:
path: "{{ existing_private_key_path }}"
register: stat_result
delegate_to: localhost
run_once: true

- name: Fail when existing private key does not exist
ansible.builtin.fail:
msg: "No existing private key file found. Check existing_private_key_path is set correctly."
when:
- not stat_result.stat.exists
delegate_to: localhost
run_once: true

- name: Stat existing public key file
ansible.builtin.stat:
path: "{{ existing_public_key_path }}"
register: stat_result
delegate_to: localhost
run_once: true

- name: Fail when existing public key does not exist
ansible.builtin.fail:
msg: "No existing public key file found. Check existing_public_key_path is set correctly."
when:
- not stat_result.stat.exists
delegate_to: localhost
run_once: true

- name: Generate a new SSH key
community.crypto.openssh_keypair:
path: "{{ existing_private_key_path }}_new"
type: "{{ new_key_type }}"
delegate_to: localhost
run_once: true

- name: Set new authorized keys
vars:
lookup_path: "{{ existing_private_key_path }}_new.pub"
ansible.posix.authorized_key:
user: "{{ item }}"
state: present
key: "{{ lookup('file', lookup_path) }}"
loop: "{{ rekey_users }}"
become: true

- name: Locally deprecate existing key (private)
command: "mv {{ existing_private_key_path }} {{ deprecated_key_path }}"
delegate_to: localhost
run_once: true

- name: Locally deprecate existing key (public)
command: "mv {{ existing_public_key_path }} {{ deprecated_key_path }}.pub"
delegate_to: localhost
run_once: true

- name: Locally promote new key (private)
command: "mv {{ existing_private_key_path }}_new {{ new_private_key_path }}"
delegate_to: localhost
run_once: true

- name: Locally promote new key (public)
command: "mv {{ existing_private_key_path }}_new.pub {{ new_public_key_path }}"
delegate_to: localhost
run_once: true

- block:
- name: Stat old key file
ansible.builtin.stat:
path: "{{ deprecated_key_path }}.pub"
register: stat_result
delegate_to: localhost
run_once: true

- name: Fail when deprecated public key does not exist
ansible.builtin.fail:
msg: "No deprecated public key file found. Check deprecated_key_path is set correctly."
when:
- not stat_result.stat.exists
delegate_to: localhost
run_once: true

- name: Remove old key from hosts
vars:
lookup_path: "{{ deprecated_key_path }}.pub"
ansible.posix.authorized_key:
user: "{{ item }}"
state: absent
key: "{{ lookup('file', lookup_path) }}"
loop: "{{ rekey_users }}"
become: true
tags: remove-key
when: rekey_remove_existing_key | bool
5 changes: 5 additions & 0 deletions releasenotes/notes/add-rekey-playbook-0065c5057b1639f8.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
features:
- |
Added the ``rekey-hosts.yml`` playbook to automatically rotate the SSH
keys on all hosts.