Files
openstack-ansible-ops/encrypt_secrets/roles/ansible_vault/tasks/ansible_vault_strings.yml
Dmitriy Rabotyagov 6a600eb981 Add a collection for managing encryption of secret data
Best practices should referring to at least basic encryption of data
including SSH keypairs, PKI certificates, user_secrets, etc.

This collection aims to help/assist with managing data in encrypted
state, in case ansuble_vault is used as an encryption mechanism.

The collection should allow adding more supproted mechanism,
like SOPS for managing data encryption in the future.

Change-Id: I8af3118946682af4ec31bb1d4f6bea93be34f68c
2025-05-02 08:03:24 +00:00

96 lines
3.2 KiB
YAML

---
# Copyright 2025, Advanced Hosters B.V.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
- name: Try to read secrets file as yaml or fallback to decrypt secrets
block:
- name: Fetch the file
ansible.builtin.slurp:
src: "{{ file['stat']['path'] }}"
register: _secrets_file
- name: Read file as unencrypted
ansible.builtin.set_fact:
_secrets: "{{ _secrets_file['content'] | b64decode | from_yaml }}"
rescue:
- name: Skipping file as it is likely already encrypted
ansible.builtin.debug:
msg: "We failed to read file as YAML, which means that it's likely already encrypted. Skipping..."
when:
- ansible_vault_action == "encrypt"
- name: Loading encrypted variables to re-encrypt
ansible.builtin.include_vars:
file: "{{ file['stat']['path'] }}"
when:
- ansible_vault_action == "rotate"
- name: Read current secrets file for rotation
vars:
_secret_vars: "{{ _secrets_file['content'] | b64decode | regex_findall('(.*):\\s!vault\\s\\|\\n') }}"
ansible.builtin.set_fact:
_secrets: |-
{% set secrets_mapping = {} %}
{% for var in _secret_vars %}
{% set _ = secrets_mapping.update({var: hostvars['localhost'][var]}) %}
{% endfor %}
{{ secrets_mapping }}
when:
- ansible_vault_action == "rotate"
always:
- name: Encrypt individual secrets from unencrypted file
ansible.builtin.command:
argv:
- "{{ ansible_vault_binary }}"
- encrypt_string
- --vault-id
- "{{ ansible_vault_region | upper }}@{{ _ansible_vault_encrypt_file }}"
- --encrypt-vault-id
- "{{ ansible_vault_region | upper }}"
- '{{ item.value }}'
- --name
- "{{ item.key }}"
with_dict: "{{ _secrets | default({}) }}"
no_log: true
register: new_secrets
changed_when: false
- name: Place encrypted secrets in-place
ansible.builtin.copy:
content: "---\n{{ new_secrets.results | map(attribute='stdout') | join('\n') }}\n"
dest: "{{ file['stat']['path'] }}"
mode: "0600"
when:
- _secrets is defined
- _secrets | length > 0
- ansible_vault_in_place_copy
- name: Place encrypted secrets in independent blocks
ansible.builtin.blockinfile:
block: "{{ item['stdout'] }}"
dest: "{{ file['stat']['path'] }}"
marker: "# {mark} ANSIBLE MANAGED {{ item.item['key'] }}"
mode: "0600"
loop: "{{ new_secrets.results }}"
when:
- _secrets is defined
- _secrets | length > 0
- not ansible_vault_in_place_copy
- name: Undefine the secrets variable
ansible.builtin.set_fact:
_secrets: {}