Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SET-651] Adds support to read secrets from HashiCorp Vault #232

Merged
merged 3 commits into from
Jan 18, 2024
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
8 changes: 8 additions & 0 deletions molecule/vault/converge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
- name: Converge
hosts: all
vars_files:
- vars.yml
tasks:
- name: "Include vault tasks"
ansible.builtin.include_tasks: vault.yml
44 changes: 44 additions & 0 deletions molecule/vault/molecule.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
dependency:
name: galaxy
options:
ignore-certs: True
ignore-errors: True
requirements-file: molecule/default/requirements.yml
driver:
name: podman
platforms:
- name: instance
image: registry.access.redhat.com/ubi8/ubi-init
tmpfs:
- /run
- /tmp
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
capabilities:
- SYS_ADMIN
- CAP_IPC_LOCK
command: "/usr/sbin/init"
pre_build_image: true
provisioner:
name: ansible
playbooks:
converge: converge.yml
verify: verify.yml
env:
ANSIBLE_ROLES_PATH: "../../roles"
verifier:
name: ansible
scenario:
test_sequence:
- dependency
- cleanup
- destroy
- create
- prepare
- converge
- idempotence
- side_effect
- verify
- cleanup
- destroy
94 changes: 94 additions & 0 deletions molecule/vault/prepare.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
- name: Prepare
hosts: all
vars_files:
- vars.yml
environment:
- VAULT_ADDR: "{{ ansible_hashi_vault_addr }}"
tasks:
- name: "Import Vault repo for installation"
ansible.builtin.yum_repository:
name: 'vault'
description: 'The vault repository'
file: external_repos
baseurl: https://rpm.releases.hashicorp.com/RHEL/$releasever/$basearch/stable
gpgcheck: no

- name: "Install Vault and pip"
ansible.builtin.package:
name: "{{ item }}"
state: present
with_items:
- vault
- python3-pip

- name: Install hvac python package
ansible.builtin.pip:
name: hvac

- name: "Set up Vault env - Start dev server in background for 5 minutes"
ansible.builtin.shell: "vault server -dev -dev-root-token-id={{ root_vault_token }}"
async: 300
poll: 0
register: result

- name: "Show the Vault server start result"
ansible.builtin.debug:
msg: "{{ result }}"

- name: Create a temporary shell script file
ansible.builtin.copy:
content: |
#!/bin/bash
set -x
sleep 5
echo "Create test policy to read on path: secret/*"
echo 'path "secret/*" {
capabilities = ["list", "read"]
}' | vault policy write test -
echo "Enable approle auth method"
vault auth enable approle
echo "Set up the role_id "
vault write auth/approle/role/{{ role_name }} secret_id_ttl=10m token_num_uses=10 token_ttl=20m token_max_ttl=30m secret_id_num_uses=40 policies="default","test"
dest: /tmp/setup_vault.sh
mode: '0755'

- name: Execute the script to set up Vault
command: '/tmp/setup_vault.sh'
register: script_output

- name: Display script output for debugging purpose
debug:
var: script_output.stdout_lines

- name: Remove the temporary script file
file:
path: /tmp/setup_vault.sh
state: absent

- name: "Set up Vault env - Write test data"
shell: |
vault kv put {{ vault_mount }}/{{ item.vault_path }} {{ item.secrets }}
with_items: "{{ test_secrets }}"

- name: "Read role_id for role: {{ role_name }} "
community.hashi_vault.vault_read:
path: "auth/approle/role/{{ role_name }}/role-id"
register: role_id

- name: Generate a secret-id for the given approle
community.hashi_vault.vault_write:
path: "auth/approle/role/{{ role_name }}/secret-id"
register: secret_id

- name: "Write role_id to {{ role_id_file }}"
ansible.builtin.copy:
content: "{{ role_id.data.data.role_id }}"
dest: "{{ role_id_file }}"
mode: '0644'

- name: "Write secret_id to {{ secret_id_file }}"
ansible.builtin.copy:
content: "{{ secret_id.data.data.secret_id }}"
dest: "{{ secret_id_file }}"
mode: '0644'
19 changes: 19 additions & 0 deletions molecule/vault/vars.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
ansible_hashi_vault_addr: 'http://127.0.0.1:8200'
root_vault_token: 'root-token'
role_name: 'jboss-set'
vault_mount: "secret"
vault_paths:
- "jboss-set/ansible"
- "jboss-set/olympus"
test_secrets:
- {
"vault_path": "jboss-set/ansible",
"secrets": "ansible_site=ansible.com ansible_nodename=node1"
}
- {
"vault_path": "jboss-set/olympus",
"secrets": "olympus_ip=127.0.0.1 olympus_fqdn=olympus.host.local"
}
role_id_file: '/tmp/role_id'
secret_id_file: '/tmp/secret_id'
26 changes: 26 additions & 0 deletions molecule/vault/vault.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
- name: "Read role_id from {{ role_id_file }}"
ansible.builtin.slurp:
src: "{{ role_id_file }}"
register: role_id

- name: "Set role_id variable"
ansible.builtin.set_fact:
"ansible_hashi_vault_role_id": "{{ role_id.content | b64decode }}"

- name: "Read secret_id from {{ secret_id_file }}"
ansible.builtin.slurp:
src: "{{ secret_id_file }}"
register: secret_id

- name: "Set secret_id varialbe"
ansible.builtin.set_fact:
"ansible_hashi_vault_secret_id": "{{ secret_id.content | b64decode }}"

- name: "Show the role_id and secret_id"
ansible.builtin.debug:
msg: "role_id: {{ ansible_hashi_vault_role_id }}, secret_id: {{ ansible_hashi_vault_secret_id }}"

- name: "Include vault"
ansible.builtin.include_role:
name: "vault"
20 changes: 20 additions & 0 deletions molecule/vault/verify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
- name: Verify for vault role
hosts: all
vars_files:
- vars.yml
gather_facts: false

tasks:
- name: "Include vault tasks"
ansible.builtin.include_tasks: vault.yml

- name: Check variables
ansible.builtin.assert:
that:
- ansible_site == 'ansible.com'
- ansible_nodename == 'node1'
- olympus_ip == '127.0.0.1'
- olympus_fqdn == 'olympus.host.local'
fail_msg: "Secrets in Vault should be converted to Anislbe variables"
success_msg: "Great, it passed!"
1 change: 1 addition & 0 deletions requirements.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ collections:
- community.general
- community.crypto
- community.postgresql
- community.hashi_vault
- ansible.posix
- containers.podman
15 changes: 15 additions & 0 deletions roles/ssh/tasks/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@
- files.ssh_keys is defined
- files.ssh_keys | length > 0

- name: "Deploy identity content into {{ ssh_home }}"
ansible.builtin.copy:
content: "{{ key.content }}"
dest: "{{ ssh_home }}/.ssh/{{ key.file_name }}"
owner: "{{ files.username }}"
group: "{{ group }}"
mode: 0400
loop: "{{ files.ssh_keys_content }}"
loop_control:
loop_var: key
when:
- files.ssh_keys is not defined
- files.ssh_keys_content is defined
- files.ssh_keys_content | length > 0

- block:
- ansible.builtin.assert:
that:
Expand Down
8 changes: 8 additions & 0 deletions roles/vault/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
ansible_hashi_vault_addr: "{{ lookup('ansible.builtin.env', 'VAULT_ADDR') }}"
ansible_hashi_vault_token: "{{ lookup('ansible.builtin.env', 'VAULT_TOKEN') }}"
ansible_hashi_vault_role_id: "{{ lookup('ansible.builtin.env', 'ANSIBLE_HASHI_VAULT_ROLE_ID') }}"
ansible_hashi_vault_secret_id: "{{ lookup('ansible.builtin.env', 'ANSIBLE_HASHI_VAULT_SECRET_ID') }}"
vault_mount: 'secret'
vault_paths:
- "jboss-set"
25 changes: 25 additions & 0 deletions roles/vault/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
- ansible.builtin.assert:
that:
- vault_paths is defined
- vault_paths | length > 0
- ansible_hashi_vault_addr is defined and ansible_hashi_vault_addr | length > 0
quiet: true

- name: "Check the Vault Secrets using token auth method"
ansible.builtin.include_tasks: tasks/vault-token.yml
with_items: "{{ vault_paths }}"
loop_control:
loop_var: vault_path
when:
- ansible_hashi_vault_token is defined and ansible_hashi_vault_token | length > 0

- name: "Check the Vault Secrets using approle auth method"
ansible.builtin.include_tasks: tasks/vault-approle.yml
with_items: "{{ vault_paths }}"
loop_control:
loop_var: vault_path
when:
- ansible_hashi_vault_token is not defined or ansible_hashi_vault_token | length == 0
- ansible_hashi_vault_role_id is defined and ansible_hashi_vault_role_id | length > 0
- ansible_hashi_vault_secret_id is defined and ansible_hashi_vault_secret_id | length > 0
29 changes: 29 additions & 0 deletions roles/vault/tasks/vault-approle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
- ansible.builtin.assert:
that:
- vault_path is defined
- ansible_hashi_vault_addr is defined and ansible_hashi_vault_addr | length > 0
- ansible_hashi_vault_role_id is defined and ansible_hashi_vault_role_id | length > 0
- ansible_hashi_vault_secret_id is defined and ansible_hashi_vault_secret_id | length > 0
quiet: true

- name: "Retrieve the secrets from Vault Path {{ vault_path }} using approle"
community.hashi_vault.vault_kv2_get:
url: '{{ ansible_hashi_vault_addr }}'
auth_method: approle
role_id: '{{ ansible_hashi_vault_role_id }}'
secret_id: '{{ ansible_hashi_vault_secret_id }}'
engine_mount_point: '{{ vault_mount }}'
path: '{{ vault_path }}'
register: vault_path_result

- name: "Set variables from result of vault path {{ vault_path }}"
ansible.builtin.set_fact:
"{{ item.key }}": "{{ item.value }}"
with_items: "{{ vault_path_result.secret | dict2items }}"
loop_control:
label: "{{ item.key }} ==> ***** "
when:
- vault_path_result is defined
- vault_path_result.secret is defined and vault_path_result.secret | length > 0

27 changes: 27 additions & 0 deletions roles/vault/tasks/vault-token.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
- ansible.builtin.assert:
that:
- vault_path is defined
- ansible_hashi_vault_addr is defined and ansible_hashi_vault_addr | length > 0
- ansible_hashi_vault_token is defined and ansible_hashi_vault_token | length > 0
quiet: true

- name: "Retrieve the secrets from Vault Path {{ vault_path }} using token auth method"
community.hashi_vault.vault_kv2_get:
url: '{{ ansible_hashi_vault_addr }}'
auth_method: token
token: '{{ ansible_hashi_vault_token }}'
engine_mount_point: '{{ vault_mount }}'
path: '{{ vault_path }}'
register: vault_path_result

- name: "Set variables from result of vault path {{ vault_path }}"
ansible.builtin.set_fact:
"{{ item.key }}": "{{ item.value }}"
with_items: "{{ vault_path_result.secret | dict2items }}"
loop_control:
label: "{{ item.key }} ==> ***** "
when:
- vault_path_result is defined
- vault_path_result.secret is defined and vault_path_result.secret | length > 0

Loading