Skip to content

Instantly share code, notes, and snippets.

@tomwassenberg
Last active September 25, 2019 10:25
Show Gist options
  • Save tomwassenberg/02fdc091f53b7d091768f2012aaa6333 to your computer and use it in GitHub Desktop.
Save tomwassenberg/02fdc091f53b7d091768f2012aaa6333 to your computer and use it in GitHub Desktop.
A hacky Ansible playbook that can be adapted to rotate Ansible Vault-encrypted secrets in-place.
---
# This playbook rotates Ansible Vault-encrypted secrets that are defined
# as dictionaries in the group_vars of an Ansible repository.
#
# The changes are split over multiple tasks, because the dictionary logic
# doesn't handle looping over secrets on differing levels within a
# dictionary.
- hosts: "all"
user: "ansible"
force_handlers: true
gather_facts: false
vars:
deploy_env: "{{ group_names | difference(['all']) | first }}"
secrets_path: "../group_vars/{{ deploy_env }}/vault.yml"
password_length: 32
tasks:
- name: "unlogged block to prevent logging of secrets"
no_log: true
block:
- name: "import current secrets"
include_vars:
name: "vars_to_change"
file: "{{ secrets_path }}"
- name: "change nested secrets"
set_fact: &replace_nested_secrets
# This takes the duplicated secrets, loops over the selected keys,
# replaces each value by a generated password, and merges that new
# pair with the existing dictionary.
vars_to_change:
"{{ vars_to_change |
combine({
secrets_category: {
item.key:
lookup('password',
'/dev/null length=' ~ password_length)
}
},
recursive=True) }}"
vars:
secrets_category: "vault_secret_example1_nested"
with_dict: "{{ vars_to_change[secrets_category] }}"
- name: "change more nested secrets"
set_fact: *replace_nested_secrets
vars:
secrets_category: "vault_secret_example2_nested"
with_dict: "{{ vars_to_change[secrets_category] }}"
- name: "change subset of more nested secrets"
set_fact: *replace_nested_secrets
vars:
secrets_category: "vault_secret_example3_nested"
with_dict: "{{ vars_to_change[secrets_category] }}"
when: "item.key == 'secret_that_needs_rotation'"
- name:
"encrypt and save changed vars to disk"
command:
"ansible-vault encrypt --vault-id
{{ deploy_env }}@script-outputting-vault-passphrase.sh
--output={{ secrets_path }}"
args:
stdin:
"{{ vars_to_change | to_nice_yaml(default_style='\"',
explicit_start=True, indent=2, width=79) }}"
delegate_to: "localhost"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment