Last active
September 25, 2019 10:25
-
-
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 file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
# 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