hashi_vault refresh - Add AWS login methods, bugfixes, cleanup (#23)

* hashi_vault refresh from PR in ansible/ansible/#66735

* Duplicate AWS doc fragments, remove version_added

* Restore FQCNames

* Fully qualify examples

* Add changelog for #23 hash_vault refresh

* Reduce examples below 160 chars

* Address review feedback

* Update changelogs/fragments/23-hashi-vault-lookup-refresh.yaml

Use review suggestion

Co-Authored-By: flowerysong <junk+github@flowerysong.com>

Co-authored-by: flowerysong <junk+github@flowerysong.com>
This commit is contained in:
Brian Scholer 2020-04-28 07:27:37 -04:00 committed by GitHub
parent 5febbca503
commit eaa484eb37
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 614 additions and 251 deletions

View file

@ -2,3 +2,4 @@
vault_gen_path: 'gen/testproject'
vault_kv1_path: 'kv1/testproject'
vault_kv2_path: 'kv2/data/testproject'
vault_kv2_multi_path: 'kv2/data/testmulti'

View file

@ -1,110 +1,159 @@
---
- name: Install Hashi Vault on controlled node and test
vars:
vault_version: 0.11.0
vault_uri: https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/lookup_hashi_vault/vault_{{ vault_version }}_{{ ansible_system | lower }}_{{ vault_arch }}.zip
vault_version: '0.11.0'
vault_uri: 'https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/lookup_hashi_vault/vault_{{ vault_version }}_{{ ansible_system | lower }}_{{ vault_arch }}.zip'
vault_cmd: '{{ local_temp_dir }}/vault'
block:
- name: Create a local temporary directory
tempfile:
state: directory
register: tempfile_result
- set_fact:
local_temp_dir: '{{ tempfile_result.path }}'
- when: pyopenssl_version.stdout is version('0.15', '>=')
block:
- name: Generate privatekey
community.crypto.openssl_privatekey:
path: '{{ local_temp_dir }}/privatekey.pem'
- name: Generate CSR
community.crypto.openssl_csr:
path: '{{ local_temp_dir }}/csr.csr'
privatekey_path: '{{ local_temp_dir }}/privatekey.pem'
subject:
commonName: localhost
- name: Generate selfsigned certificate
register: selfsigned_certificate
community.crypto.openssl_certificate:
path: '{{ local_temp_dir }}/cert.pem'
csr_path: '{{ local_temp_dir }}/csr.csr'
privatekey_path: '{{ local_temp_dir }}/privatekey.pem'
provider: selfsigned
selfsigned_digest: sha256
- name: Install unzip
package:
name: unzip
when: ansible_distribution != "MacOSX"
- assert:
that: ansible_architecture in ['i386', 'x86_64', 'amd64']
- set_fact:
vault_arch: '386'
when: ansible_architecture == 'i386'
- set_fact:
vault_arch: amd64
when: ansible_architecture in ['x86_64', 'amd64']
- name: Download vault binary
unarchive:
src: '{{ vault_uri }}'
dest: '{{ local_temp_dir }}'
remote_src: true
- environment:
VAULT_DEV_ROOT_TOKEN_ID: 47542cbc-6bf8-4fba-8eda-02e0a0d29a0a
block:
- name: Create configuration file
template:
src: vault_config.hcl.j2
dest: '{{ local_temp_dir }}/vault_config.hcl'
- name: Start vault service
environment:
VAULT_ADDR: http://localhost:8200
- name: Create a local temporary directory
tempfile:
state: directory
register: tempfile_result
- set_fact:
local_temp_dir: '{{ tempfile_result.path }}'
- when: pyopenssl_version.stdout is version('0.15', '>=')
block:
- name: Start vault server (dev mode enabled)
shell: nohup {{ vault_cmd }} server -dev -config {{ local_temp_dir }}/vault_config.hcl </dev/null >/dev/null 2>&1 &
- name: Create generic secrets engine
command: '{{ vault_cmd }} secrets enable -path=gen generic'
- name: Create KV v1 secrets engine
command: '{{ vault_cmd }} secrets enable -path=kv1 -version=1 kv'
- name: Create KV v2 secrets engine
command: '{{ vault_cmd }} secrets enable -path=kv2 -version=2 kv'
- name: Create a test policy
shell: echo '{{ policy }}' | {{ vault_cmd }} policy write test-policy -
vars:
policy: "path \"{{ vault_gen_path }}/secret1\" {\n capabilities = [\"read\"]\n}\npath \"{{ vault_gen_path }}/secret2\" {\n capabilities = [\"read\", \"update\"]\n}\npath \"{{ vault_gen_path }}/secret3\" {\n capabilities = [\"deny\"]\n}\npath \"{{ vault_kv1_path }}/secret1\" {\n capabilities = [\"read\"]\n}\npath \"{{ vault_kv1_path }}/secret2\" {\n capabilities = [\"read\", \"update\"]\n}\npath \"{{ vault_kv1_path }}/secret3\" {\n capabilities = [\"deny\"]\n}\npath \"{{ vault_kv2_path }}/secret1\" {\n capabilities = [\"read\"]\n}\npath \"{{ vault_kv2_path }}/secret2\" {\n capabilities = [\"read\", \"update\"]\n}\npath \"{{ vault_kv2_path }}/secret3\" {\n capabilities = [\"deny\"]\n}\n"
- name: Create generic secrets
command: '{{ vault_cmd }} write {{ vault_gen_path }}/secret{{ item }} value=foo{{ item }}'
loop:
- 1
- 2
- 3
- name: Create KV v1 secrets
command: '{{ vault_cmd }} kv put {{ vault_kv1_path }}/secret{{ item }} value=foo{{ item }}'
loop:
- 1
- 2
- 3
- name: Create KV v2 secrets
command: '{{ vault_cmd }} kv put {{ vault_kv2_path | regex_replace("/data") }}/secret{{ item }} value=foo{{ item }}'
loop:
- 1
- 2
- 3
- name: setup approle auth
import_tasks: approle_setup.yml
when: ansible_distribution != 'RedHat' or ansible_distribution_major_version is version('7', '>')
- name: setup token auth
import_tasks: token_setup.yml
- import_tasks: tests.yml
vars:
auth_type: approle
when: ansible_distribution != 'RedHat' or ansible_distribution_major_version is version('7', '>')
- import_tasks: tests.yml
vars:
auth_type: token
always:
- name: Kill vault process
shell: kill $(cat {{ local_temp_dir }}/vault.pid)
ignore_errors: true
- name: Generate privatekey
community.crypto.openssl_privatekey:
path: '{{ local_temp_dir }}/privatekey.pem'
- name: Generate CSR
community.crypto.openssl_csr:
path: '{{ local_temp_dir }}/csr.csr'
privatekey_path: '{{ local_temp_dir }}/privatekey.pem'
subject:
commonName: localhost
- name: Generate selfsigned certificate
community.crypto.openssl_certificate:
path: '{{ local_temp_dir }}/cert.pem'
csr_path: '{{ local_temp_dir }}/csr.csr'
privatekey_path: '{{ local_temp_dir }}/privatekey.pem'
provider: selfsigned
selfsigned_digest: sha256
register: selfsigned_certificate
- name: 'Install unzip'
package:
name: unzip
when: ansible_distribution != "MacOSX" # unzip already installed
- assert:
# Linux: x86_64, FreeBSD: amd64
that: ansible_architecture in ['i386', 'x86_64', 'amd64']
- set_fact:
vault_arch: '386'
when: ansible_architecture == 'i386'
- set_fact:
vault_arch: amd64
when: ansible_architecture in ['x86_64', 'amd64']
- name: 'Download vault binary'
unarchive:
src: '{{ vault_uri }}'
dest: '{{ local_temp_dir }}'
remote_src: true
- environment:
# used by vault command
VAULT_DEV_ROOT_TOKEN_ID: '47542cbc-6bf8-4fba-8eda-02e0a0d29a0a'
block:
- name: 'Create configuration file'
template:
src: vault_config.hcl.j2
dest: '{{ local_temp_dir }}/vault_config.hcl'
- name: 'Start vault service'
environment:
VAULT_ADDR: 'http://localhost:8200'
block:
- name: 'Start vault server (dev mode enabled)'
shell: 'nohup {{ vault_cmd }} server -dev -config {{ local_temp_dir }}/vault_config.hcl </dev/null >/dev/null 2>&1 &'
- name: 'Create generic secrets engine'
command: '{{ vault_cmd }} secrets enable -path=gen generic'
- name: 'Create KV v1 secrets engine'
command: '{{ vault_cmd }} secrets enable -path=kv1 -version=1 kv'
- name: 'Create KV v2 secrets engine'
command: '{{ vault_cmd }} secrets enable -path=kv2 -version=2 kv'
- name: 'Create a test policy'
shell: "echo '{{ policy }}' | {{ vault_cmd }} policy write test-policy -"
vars:
policy: |
path "{{ vault_gen_path }}/secret1" {
capabilities = ["read"]
}
path "{{ vault_gen_path }}/secret2" {
capabilities = ["read", "update"]
}
path "{{ vault_gen_path }}/secret3" {
capabilities = ["deny"]
}
path "{{ vault_kv1_path }}/secret1" {
capabilities = ["read"]
}
path "{{ vault_kv1_path }}/secret2" {
capabilities = ["read", "update"]
}
path "{{ vault_kv1_path }}/secret3" {
capabilities = ["deny"]
}
path "{{ vault_kv2_path }}/secret1" {
capabilities = ["read"]
}
path "{{ vault_kv2_path }}/secret2" {
capabilities = ["read", "update"]
}
path "{{ vault_kv2_path }}/secret3" {
capabilities = ["deny"]
}
path "{{ vault_kv2_multi_path }}/secrets" {
capabilities = ["read"]
}
- name: 'Create generic secrets'
command: '{{ vault_cmd }} write {{ vault_gen_path }}/secret{{ item }} value=foo{{ item }}'
loop: [1, 2, 3]
- name: 'Create KV v1 secrets'
command: '{{ vault_cmd }} kv put {{ vault_kv1_path }}/secret{{ item }} value=foo{{ item }}'
loop: [1, 2, 3]
- name: 'Create KV v2 secrets'
command: '{{ vault_cmd }} kv put {{ vault_kv2_path | regex_replace("/data") }}/secret{{ item }} value=foo{{ item }}'
loop: [1, 2, 3]
- name: 'Create multiple KV v2 secrets under one path'
command: '{{ vault_cmd }} kv put {{ vault_kv2_multi_path | regex_replace("/data") }}/secrets value1=foo1 value2=foo2 value3=foo3'
- name: setup approle auth
import_tasks: approle_setup.yml
when: ansible_distribution != 'RedHat' or ansible_distribution_major_version is version('7', '>')
- name: setup token auth
import_tasks: token_setup.yml
- import_tasks: tests.yml
vars:
auth_type: approle
when: ansible_distribution != 'RedHat' or ansible_distribution_major_version is version('7', '>')
- import_tasks: tests.yml
vars:
auth_type: token
always:
- name: 'Kill vault process'
shell: "kill $(cat {{ local_temp_dir }}/vault.pid)"
ignore_errors: true
always:
- name: Delete temp dir
file:
path: '{{ local_temp_dir }}'
state: absent
- name: 'Delete temp dir'
file:
path: '{{ local_temp_dir }}'
state: absent

View file

@ -9,6 +9,9 @@
kv1_secret2: "{{ lookup('community.general.hashi_vault', conn_params ~ 'secret=' ~ vault_kv1_path ~ '/secret2 token=' ~ user_token) }}"
kv2_secret1: "{{ lookup('community.general.hashi_vault', conn_params ~ 'secret=' ~ vault_kv2_path ~ '/secret1 auth_method=token token=' ~ user_token) }}"
kv2_secret2: "{{ lookup('community.general.hashi_vault', conn_params ~ 'secret=' ~ vault_kv2_path ~ '/secret2 token=' ~ user_token) }}"
kv2_secret2_as_raw: "{{ lookup('community.general.hashi_vault', vault_kv2_path ~ '/secret2 ' ~ conn_params, auth_method='token', token=user_token, return_format='raw') }}"
kv2_secrets_as_dict: "{{ lookup('community.general.hashi_vault', vault_kv2_multi_path ~ '/secrets ' ~ conn_params, auth_method='token', token=user_token) }}"
kv2_secrets_as_values: "{{ query('community.general.hashi_vault', vault_kv2_multi_path ~ '/secrets ' ~ conn_params, auth_method='token', token=user_token, return_format='values') }}"
- name: 'Check secret generic values'
fail:
@ -25,6 +28,32 @@
msg: 'unexpected secret values'
when: kv2_secret1['value'] != 'foo1' or kv2_secret2['value'] != 'foo2'
- name: 'Check kv2 secret raw return value'
fail:
msg:
when: >-
'data' not in kv2_secret2_as_raw
or 'data' not in kv2_secret2_as_raw['data']
or 'metadata' not in kv2_secret2_as_raw['data']
- name: "Check multiple secrets as dict"
fail:
msg: 'Return value was not dict or items do not match.'
when: (kv2_secrets_as_dict | type_debug != 'dict') or (kv2_secrets_as_dict['value{{ item }}'] != 'foo{{ item }}')
loop: [1, 2, 3]
- name: "Check multiple secrets as values"
fail:
msg: 'Return value was not list or items do not match.'
when: (kv2_secrets_as_values | type_debug != 'list') or ('foo{{ item }}' not in kv2_secrets_as_values)
loop: [1, 2, 3]
- name: "Check multiple secrets as dict"
fail:
msg: 'Return value was not dict or items do not match.'
when: (kv2_secrets_as_dict | type_debug != 'dict') or (kv2_secrets_as_dict['value{{ item }}'] != 'foo{{ item }}')
loop: [1, 2, 3]
- name: 'Failure expected when erroneous credentials are used'
vars:
secret_wrong_cred: "{{ lookup('community.general.hashi_vault', conn_params ~ 'secret=' ~ vault_kv2_path ~ '/secret2 auth_method=token token=wrong_token') }}"
@ -43,7 +72,7 @@
- name: 'Failure expected when inexistent secret is read'
vars:
secret_inexistent: "{{ lookup('community.general.hashi_vault', conn_params ~ 'secret=' ~ vault_kv2_path ~ '/secret4 token=' ~ user_token) }}"
secret_inexistent: "{{ lookup('community.general.hashi_vault', conn_params ~ 'secret=' ~ vault_kv2_path ~ '/secret4 token=' ~ user_token) }}"
debug:
msg: 'Failure is expected ({{ secret_inexistent }})'
register: test_inexistent