DSV lookup plugin for Ansible
DSV has lookup plugin for Ansible in the delinea.core
collection.
The collection is certified and available in Ansible Galaxy.
To install delinea.core
collection run:
ansible-galaxy collection install delinea.core
Use ansible-galaxy collection list
to verify the installation. Example:
$ ansible-galaxy collection list delinea.core
# /root/.ansible/collections/ansible_collections
Collection Version
------------ -------
delinea.core 1.0.0
$
Source code of the delinea.core
collection is available on GitHub: DelineaXPM/ansible-core-collection.
Requirements
The DSV lookup plugin depends on version 0.0.1 of Python DSV SDK. To install it run:
pip install python-dsv-sdk==0.0.1
Authentication
Only available option for authentication is via client credentials, i.e. client id and client secret. Read more about client credentials here.
Usage
The DSV lookup plugin can be used to access data from DSV and then store it in variables within your playbook.
Use "ansible-doc" to display all available configuration options:
ansible-doc --type lookup delinea.core.dsv
Recommended way to use the plugin is to configure it with environment variables and then set only path to a secret in the playbook file:
vars:
my_secret: "{{ lookup('delinea.core.dsv', '<path to secret>') }}"
Also you can set only client id and client secert as env vars and provide tenant name as a named argument:
vars:
my_secret: "{{ lookup('delinea.core.dsv', '<path to secret>', tenant='<tenant name>') }}"
Another option available from Ansible 1.5 is the Ansible Vault. Using it you can store client credentials for DSV in encrypted files.
Permissions
We strongly recommend using policies to control access to secrets needed by the plugin. The role tied to the client should only have read access to applicable secrets.
For example if name of the role used to generate client credentials is "ansible-role" and in your playbook you have:
vars:
dsv_secret_one: "{{ lookup('delinea.core.dsv', 'playbooks:example:one') }}"
dsv_secret_two: "{{ lookup('delinea.core.dsv', 'playbooks:example:two') }}"
Then for this role create a policy with only read action allowed:
dsv policy create \
--path 'secrets:playbooks:example' \
--subjects 'roles:ansible-role' \
--actions 'read' \
--resources 'secrets:playbooks:example:one,secrets:playbooks:example:two'
Example
The example shows how you can use DSV lookup plugin to read secret from DSV and store in a playbook variable.
To prepare DSV for this example, you need to:
-
create a secret
Copydsv secret create --path 'mysecret' --data '{"key": "1"}'
-
create a role
Copydsv role create --name 'ansible-example'
-
generate client credentials
Copydsv client create --role 'ansible-example'
-
create a policy with permission that will allow role "ansible-example" to read "mysecret" secret
Copydsv policy create \
--path 'secrets:mysecret' \ --resources 'secrets:mysecret' \ --subjects 'roles:ansible-example' \ --actions 'read'
This example requires Python and Ansible to be installed. To install Ansible follow official installation guide from Ansible docs.
Python 3.10 and the ansible-core
version 2.13.5 are used.
$ ansible --version
ansible [core 2.13.5]
< skipped for brevity >
python version = 3.10.8 (main, Oct 13 2022, 22:36:54) [GCC 10.2.1 20210110]
jinja version = 3.1.2
libyaml = True
Install the delinea.core
collection which includes DSV lookup plugin:
ansible-galaxy collection install delinea.core
Next, install Python DSV SDK:
pip install python-dsv-sdk==0.0.1
For security reasons we do not recommend passing client id and client secret directly as named arguments directly to lookup plugin from Ansible playbook. In this example set "DSV_CLIENT_ID" and "DSV_CLIENT_SECRET" env variables to your values of client id and client secret respectively.
Also set "DSV_TENANT" to your tenant name (e.g. "demo" for "https://demo.secretsvaultcloud.com")
Now create a simple playbook which reads secret "mysecret" from DSV, stores it in the "my_secret" variable and then prints "key" value from the secret's data.
cat <<EOF > dsv_playbook.yml
- hosts: localhost
vars:
my_secret: "{{ lookup( 'delinea.core.dsv', 'mysecret' ) }}"
tasks:
- debug: msg="Key retrieved from DSV = {{ my_secret["data"]["key"] }}"
EOF
Example of running the dsv_playbook.yml
using ansible-playbook
:
$ ansible-playbook dsvlookup.yml
< skipped for brevity >
TASK [debug] ********************************************************************************************************************
ok: [localhost] => {
"msg": "Key retrieved from DSV = 1"
}
PLAY RECAP ********************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
$
Please note that DSV lookup plugin is similar to reading a secret using DSV CLI. If you create a playbook like this:
cat <<EOF > dsv_playbook2.yml
- hosts: localhost
tasks:
- debug: msg="{{ lookup( 'delinea.core.dsv', 'mysecret' ) }}"
EOF
and run it, then the output will be similar to reading the secrets using CLI:
dsv secret read --path mysecret