Ansible Integration

The DevOps Secrets Safe lookup plugin and modules import the secretssafe package and create an instance of the client that communicates with the DevOps Secrets Safe API.

Prerequisites

Before proceeding with this section, please ensure that you have access to the secretssafe Python package, installable from a BeyondTrust-provided WHL file. To run any DevOps Secrets Safe plugin or module, you must use a Python interpreter version 3.6 or greater.

Install the DevOps Secrets Safe Package

Install the secretssafe package to your Python environment using pip.

pip install secretssafe-<version_details>.whl

Configure Ansible to Discover the DevOps Secrets Safe Lookup Plugin and Modules

You can load any of the DevOps Secrets Safe Ansible integrations automatically.

For the DevOps Secrets Safe lookup plugin, do any of the following:

  • Store it in the ~/.ansible/plugins/lookup subdirectory.
  • Store it in the /usr/share/ansible/plugins/lookup subdirectory.
  • Place the path to the plugin in your ansible.cfg file.

For any of the DevOps Secrets Safe Ansible modules, do any of the following:

  • Store it in the ~/.ansible/plugins/modules subdirectory.
  • Store it in the /usr/share/ansible/plugins/modules subdirectory.
  • Place the path to the plugin in your ansible.cfg file.

To use the Ansible components in certain playbooks:

  • Store the lookup plugin in the lookup_plugins subdirectory, located in the directory that contains the playbook.
  • Store the modules in the library subdirectory, located in the directory that contains the playbook.

To use the environment to configure the plugin location for the DevOps Secrets Safe lookup plugin, run the following export command:

export ANSIBLE_LOOKUP_PLUGINS=<path/to/secretssafe/lookup/plugin/directory/>

To use the environment to configure the plugin location for the DevOps Secrets Safe modules, run the following export command:

export ANSIBLE_LIBRARY=<path/to/secretssafe/module/directory/>

Once properly configured, validate the discovery of the plugin:

ansible-doc -t lookup secretssafelookup
ansible-doc -t module secretssafe_dynamic_accout_create
ansible-doc -t module secretssafe_create    

Execute the Plugin with Environment Variables

DevOps Secrets Safe Ansible components share some common options that can be set via environment variables. The following variables must be set either on the control machine (shell where Ansible is called), or within the playbook that uses the plugin:

SECRETSSAFE_HOST=<IP address or hostname of Secrets Safe instance>
SECRETSSAFE_PORT=<port of Secrets Safe instance>SECRETSSAFE_API_KEY=<pregenerated API key>
SECRETSSAFE_APP_NAME=<application name associated with API key>
SECRETSSAFE_VERIFY_CA=<true/false/path to CA certificate>

This allows you to invoke the plugin without the credential or configuration keyword arguments.

The DevOps Secrets Safe client verifies the SSL certificate presented by the DSS instance. The SECRETSSAFE_VERIFY_CA environment variable specifies the path to the CA certificate that the Secrets Safe certificate is checked against.

If no SECRETSSAFE_VERIFY_CA is specified, the default certificate bundles provided by the Python requests library are used.

Certificate verification can be disabled by setting SECRETSSAFE_VERIFY_CA=false. This is strongly discouraged for a production environment.

Common Options

All Secrets Safe Ansible components share some common options:

Component Description Settings
name The name of the application used to create the secret. Required: true
api_key API key that corresponds to the application provided in the name option.

Required: true

host DNS or IP address of the DSS instance this secret are saved to.

Required: true

verify_ca SSL certificate verification flag; looks to publicly available CA if set to true.

Required: false

Default: true

Choices:

  • true
  • false
  • path to CA certificate
port DSS instance port.

Required: false

Default: 443

DevOps Secrets Safe Lookup Plugin

This module supports retrieving secrets withDevOps Secrets Safe.

In addition to the common options listed above, the secretssafelookup plugin also has the following:

Component Description Settings
uri The DSS URI where the secret is retrieved. Required: true
Retrieve and display multiple secrets from DSS using string arguments.
- name: Retrieving and displaying a series of plaintext secrets from Secrets Safe using string arguments.
  hosts: controlnode
  vars:
    secretssafe:
      credentials:
        api_key: "{{ secretssafe_api_key }}"
        app_name: "{{ secretssafe_app_name }}"
      configuration:
        host: "{{ secretssafe_host }}"
        port: "{{ secretssafe_port }}"
        verify_ca: "{{ secretssafe_verify_ca }}"
    uris:
      uri1: some/uri:1
      uri2: some/uri:2

  tasks:
    - name: Call Secrets Safe using jinja2 with_<lookup_plugin_name> syntax
      debug:
        msg: "{{ item }}"
      with_secretssafelookup:
        - 'uri={{ uris.uri1 }} | credentials={{ secretssafe.credentials }} | configuration={{ secretssafe.configuration }}'
        - 'uri={{ uris.uri2 }} | credentials={{ secretssafe.credentials }} | configuration={{ secretssafe.configuration }}'
Retrieve and display multiple secrets from DSS, reading the configuration from the environment.
- name: Retrieving and displaying a series of plaintext secrets from Secrets Safe, reading the configuration/credentials from the environment.
  hosts: controlnode
  vars:
    uris:
      - some/uri:1
      - some/uri:2

  tasks:
    - name: Call Secrets Safe using jinja2 with_<lookup_plugin_name> syntax and pre-exported environment variables
      debug:
        msg: "{{ item }}"
      with_secretssafelookup: "{{ uris }}"
Retrieve and display a single secret from DSS, reading the configuration from defined variables as keyword arguments.
- name: Retrieve and display a single secret from DSS, reading the configuration from defined variables as keyword arguments.
  hosts: controlnode
  vars:
    secretssafe:
      credentials:
        api_key: "{{ secretssafe_api_key }}"
        app_name: "{{ secretssafe_app_name }}"
      configuration:
        host: "{{ secretssafe_host }}"
        port: "{{ secretssafe_port }}"
        verify_ca: "{{ secretssafe_verify_ca }}"
    uri: some/uri:1

  tasks:
      - set_fact:
          decrypted_secret: "{{ lookup('secretssafelookup', uri, credentials=secretssafe.credentials, configuration=secretssafe.configuration) }}"
      - debug:
          msg: "{{ decrypted_secret }}"
Retrieve and display multiple secrets from DSS, reading the configuration from defined variables as keyword arguments.
- name: Retrieve and display multiple secrets from DSS, reading the configuration from defined variables as keyword arguments.
  hosts: controlnode
  vars:
    secretssafe:
      credentials:
        api_key: "{{ secretssafe_api_key }}"
        app_name: "{{ secretssafe_app_name }}"
      configuration:
        host: "{{ secretssafe_host }}"
        port: "{{ secretssafe_port }}"
        verify_ca: "{{ secretssafe_verify_ca }}"
    uris:
      - some/uri:1
      - some/uri:2

  tasks:
    - name: Call Secrets Safe lookup in a with_items loop
      debug:
        msg: "{{ lookup('secretssafelookup', item, credentials=secretssafe.credentials, configuration=secretssafe.configuration) }}"
      with_items: "{{ uris }}"
- name: Retrieve and display multiple secrets from DSS, reading the configuration from defined variables as keyword arguments.
  hosts: controlnode
  vars:
    secretssafe:
      credentials:
        api_key: "{{ secretssafe_api_key }}"
        app_name: "{{ secretssafe_app_name }}"
      configuration:
        host: "{{ secretssafe_host }}"
        port: "{{ secretssafe_port }}"
        verify_ca: "{{ secretssafe_verify_ca }}"
    uris:
      - some/uri:1
      - some/uri:2

  tasks:
    - name: Call Secrets Safe lookup in a with_items loop
      debug:
        msg: "{{ lookup('secretssafelookup', item, credentials=secretssafe.credentials, configuration=secretssafe.configuration) }}"
      with_items: "{{ uris }}"

Create Secret Module

This module supports creating secrets with DevOps Secrets Safe. Secrets can be read from a file on disk or an Ansible fact. Secret creation by providing a generator name is also supported. You must provide credentials for a DevOps Secrets Safe application.

In addition to the common options listed above, the create secret module also has the following options:

Component Description Settings
secret_uri The DSS URI where the secret is saved. Required: true
generator Name of generator used to create secret value. Mutually exclusive with secret_file_path and secret_value options.

Required: true

secret_file_path Path to file that is saved as a secret. Mutually exclusive with generator and secret_value options.
  • Required: false
  • secret_value Value, in the form of a string, that is saved as a secret path to file that is saved as a secret. Mutually exclusive with generator and secret_file_path options.

    Required: false

    Create Secret From File.
    - name: Create Secret From File
      hosts: managed_1
      tasks:
        - name: Create With File Path
        secretssafe_create:
          api_key: <api_key>
          name: myapp
          host: <secretssafe_host>
          port: 443
          verify_ca: false
          secret_uri: this/is:secret2500
          secret_file_path: /home/lockboxadmin/examples.desktop      
    

     

    Create Secret From Fact.
    - name: Create Secret From Fact
      hosts: managed_1
      tasks:
        - name: Set Fact Value
        set_fact:
            test_value: This is my secret
        - name: Create From Fact
          secretssafe_create:
            api_key: <api_key>
            name: myapp
            host: <secretssafe_host>
            port: 443
            verify_ca: false
            secret_value: "{{ test_value }}"
            secret_uri: this/is:secret3      
    
    - name: Create Secret From Fact
      hosts: managed_1
      tasks:
        - name: Set Fact Value
        set_fact:
            test_value: This is my secret
        - name: Create From Fact
          secretssafe_create:
            api_key: <api_key>
            name: myapp
            host: <secretssafe_host>
            port: 443
            verify_ca: false
            secret_value: "{{ test_value }}"
            secret_uri: this/is:secret3      
    

     

    Create Secret From Generator
    - name: Create Secrets Using Generator
      hosts: managed_1
      tasks:
        - name: Create With Generator
        secretssafe_create:
          api_key: <api_key%gt;
          name: myapp
          host: <secretssafe_host>
          port: 443
          verify_ca: true
          generator: my-number-generator
          secret_uri: this/is:secret111  
    

    DevOps Secrets Safe secretssafe_dynamic_accout_create Module

    This module supports creating dynamic accounts with DevOps Secrets Safe.

    In addition to the common options listed above, the secretssafe_dynamic_accout_create module also has the following options:

    Component Description Options
    provider Provider used to create the dynamic account.

    Required: true

    account_definition Account definition used to create the dynamic account.

    Required: true

    input_file Input file with data for dynamic account creation. Mutually exclusive with the input_json option.

    Required: false

    input_json JSON file that contains data for dynamic account creation. Mutually exclusive with the input_file option.

    Required: false

    Create Dynamic Account and Copy Output to File
    - name: Create Dynamic Account and Copy Output to File
        hosts: managed_host_1
        tasks:
        - name: create dynamic account
          secretssafe_dynamic_account_create:
            api_key: 04ab4f29-21c7-4348-98d7
            name: myapp
            host: mydss.myorg.com
            port: 443
            verify_ca: 'false'
            provider: my_gcp_provider
            account_definition: my_gcp_definition
            input_file: path/to/myfile.json
          register: create_output
        - name: copy account info to file
          copy:
            dest: ~/dss_dynamic_account.json
            content: '{{ create_output.msg }}'