Поддержка типизированных engines в HashiCorp для секретов компонента Deploy tools (CDJE) и приложений#
Секреты CDJE и приложений могут храниться в типизированных engines начиная с версии CDJE 1.7.
Для секретов CDJE в файле pipeline_vault.conf#
Все секреты из хранилища с KV engine могут быть перенесены в хранилище с KV2 engine.
Для этого в часть с расположением секрета нужно добавить инфикс /data/.
Инфикс добавляется после корневого каталога хранилища, перед дочерними путями внутри хранилища.
Пример для KV:
{% set namespace_id = lookup('custom_vars', 'global.hashicorp.opsPathCommon').split('/')[1] %}
{% set credId = lookup('custom_vars','global.hashicorp.opsHashiCorpCred') %}
{% set opsPathCommon = lookup('custom_vars', 'global.hashicorp.opsPathCommon') %}
{% set secmanUserPassCreds = lookup('community.hashi_vault.hashi_vault', opsPathCommon + 'user_pass_tech',namespace=namespace_id, token=lookup('vars',credId)) %}
maven_username={{ secmanUserPassCreds['secretUsername'] }}
maven_password={{ secmanUserPassCreds['secretPassword'] }}
git_username={{ secmanUserPassCreds['secretUsername'] }}
git_password={{ secmanUserPassCreds['secretPassword'] }}
Пример для KV 2:
{% set namespace_id = lookup('custom_vars', 'global.hashicorp.opsPathCommon').split('/')[1] %}
{% set credId = lookup('custom_vars','global.hashicorp.opsHashiCorpCred') %}
{% set opsPathCommon = lookup('custom_vars', 'global.hashicorp.opsPathCommon') %}
{% set secmanUserPassCreds = lookup('community.hashi_vault.hashi_vault', opsPathCommon + '/data/' + 'user_pass_tech',namespace=namespace_id, token=lookup('vars',credId)) %}
maven_username={{ secmanUserPassCreds['secretUsername'] }}
maven_password={{ secmanUserPassCreds['secretPassword'] }}
git_username={{ secmanUserPassCreds['secretUsername'] }}
git_password={{ secmanUserPassCreds['secretPassword'] }}
Для секретов типа «Сертификат» возможно использование хранилищ с PKI engine.
Для этого необходимо:
задать расположение секрета — указать корневой путь к целевому engine;
задать параметры сертификата;
обработать ответ от hashicopr :
private_key,ca_chain,certificate;
Пример для KV:
{% set namespace_id = lookup('custom_vars', 'global.hashicorp.opsPathCommon').split('/')[1] %}
{% set credId = lookup('custom_vars','global.hashicorp.opsHashiCorpCred') %}
{% set opsPathCommon = lookup('custom_vars', 'global.hashicorp.opsPathCommon') %}
{% set secmanGatewayClientCer = lookup('community.hashi_vault.hashi_vault', opsPathCommon + 'gateway_client_cer',namespace='', token=lookup('vars',credId)) %}
gateway_client_cer={{ secmanGatewayClientCer['secretFileBase64'] | b64decode | b64encode }}
{% set secmanGatewayClientKey = lookup('community.hashi_vault.hashi_vault', opsPathCommon + 'gateway_client_key',namespace='', token=lookup('vars',credId)) %}
gateway_client_key={{ secmanGatewayClientKey['secretFileBase64'] | b64decode | b64encode}}
{% set secmanGatewayClientKeystore = lookup('community.hashi_vault.hashi_vault', opsPathCommon + 'gateway_client_keystore',namespace='', token=lookup('vars',credId)) %}
gateway_client_keystore={{ secmanGatewayClientKeystore['secretFileBase64'] | b64decode | b64encode }}
Пример для PKI:
{% set namespace_id = lookup('custom_vars', 'global.hashicorp.opsPathCommon').split('/')[1] %}
{% set credId = lookup('custom_vars','global.hashicorp.opsHashiCorpCred') %}
{% set opsPathCommon = lookup('custom_vars', 'global.hashicorp.opsPathCommon') %}
{% set credId_infra = lookup('custom_vars','global.hashicorp.infraHashiCorpCred') %}
# формируем параметры сертификата
{% set data = {
'common_name': "sample1.dot.solution.sbt",
'email': "Nigmatulin.Y.A@sbertech.ru",
'format': "pem",
'private_key_format': "pem",
'alt_names': "dot.solution.sbt"
}
%}
## Запрос в HashiCorp
{% set gatewayClient = lookup('community.hashi_vault.vault_write','PKI/fetch/role-ga-secman-run4c-deploy', namespace=namespace_id,token=lookup('vars', credId_infra),data=data).data %}
# обработка запроса и запись значения в параметры CDJE
gateway_client_cer="{{ gatewayClient['certificate'] | b64encode }}"
gateway_client_key="{{ gatewayClient['private_key'] | b64encode }}"
gateway_client_keystore="{{ gatewayClient['ca_chain'] | b64encode }}"
Для секретов приложений#
Пример для KV в файле environment_vault.conf:
{%- macro print(secret, token) -%}
{% if lookup('env', 'HASHI_VAULT_DEBUG') == 'true' %}
{{ lookup('pipe', 'echo \033[32m Обработка секрета path=' + secret + ' token=' + token + ' \033[0m > /dev/stderr') }}
{% endif %}
{%- endmacro -%}
# Объявление переменных для удобства
{% set namespace_id = lookup('custom_vars', 'global.hashicorp.opsPathCommon').split('/')[1] %}
{% set credId = lookup('custom_vars','global.hashicorp.opsHashiCorpCred') %}
{% set opsPathPasswordsConfKV_1 = lookup('custom_vars', 'global.hashicorp.opsPathPasswordsConfKV_1') %}
{{ lookup('pipe', 'echo \033[34m Адрес hashicorp: ' + lookup('env','VAULT_ADDR') + ' \033[0m > /dev/stderr') }}
{{ lookup('pipe', 'echo \033[32m Обрабатывается секрет в kv1 engine \033[0m > /dev/stderr') }}
{{ lookup('pipe', 'echo \033[32m Обработка секрета path=' + opsPathPasswordsConfKV_1 + ' namespace=' + namespace_id + ' token=' + credId + ' \033[0m > /dev/stderr') }}
{% for secret_entry in lookup('community.hashi_vault.hashi_vault_list', 'path=' + opsPathPasswordsConfKV_1, namespace='',token=lookup('custom_vars', credId)).split(',') %}
{% if not secret_entry.endswith('/') %}
{{ print( opsPathPasswordsConfKV_1 + ':' + secret_entry,credId) }}
{% set results=lookup('community.hashi_vault.hashi_vault', 'secret=' + opsPathPasswordsConfKV_1 + secret_entry, namespace='',token=lookup('custom_vars', credId)) %}
{% for key, value in results.items() %}
{{ key }}={{ value }}
{% endfor %}
{% endif %}
{% endfor %}
{% endif %}
Пример для KV2:
{%- macro print(secret, token) -%}
{% if lookup('env', 'HASHI_VAULT_DEBUG') == 'true' %}
{{ lookup('pipe', 'echo \033[32m Обработка секрета path=' + secret + ' token=' + token + ' \033[0m > /dev/stderr') }}
{% endif %}
{%- endmacro -%}
# Объявление переменных для удобства
{% set namespace_id = lookup('custom_vars', 'global.hashicorp.opsPathCommon').split('/')[1] %}
{% set credId = lookup('custom_vars','global.hashicorp.opsHashiCorpCred') %}
{% set opsPathPasswordsConfKV_2 = lookup('custom_vars', 'global.hashicorp.opsPathPasswordsConfKV_2') %}
## где global.hashicorp.opsPathPasswordsConfKV_2=/<путь до хранилища kv2>/KV2 задан в _global.hashicorp.conf
{{ lookup('pipe', 'echo \033[32m Обрабатывается секрет в kv2 engine \033[0m > /dev/stderr') }}
{% for secret_entry in lookup('community.hashi_vault.hashi_vault_list', 'path=' + opsPathPasswordsConfKV_2, namespace=namespace_id,token=lookup('custom_vars', credId)).split(',') %}
{% if not secret_entry.endswith('/') %}
{{ print(secret_entry,credId) }}
{% set results=lookup('community.hashi_vault.hashi_vault', 'secret=' + opsPathPasswordsConfKV_2 +'/data/' + secret_entry, namespace=namespace_id,token=lookup('custom_vars', credId)) %}
{% for key, value in results.items() %}
{{ print(opsPathPasswordsConfKV_2 + '/' + secret_entry ,credId) }}
{{ key }}={{ value }}
{% endfor %}
{% endif %}
{% endfor %}
Для получения списка секретов в подкаталоге нужно использовать плагин community.hashi_vault.hashi_vault, добавив в запрос инфикс /metadata/ и параметр list=true в конце.
Инфикс добавляется после корневого каталога хранилища, перед дочерними путями внутри хранилища:
{%- macro print(secret, token) -%}
{% if lookup('env', 'HASHI_VAULT_DEBUG') == 'true' %}
{{ lookup('pipe', 'echo \033[32m Обработка секрета path=' + secret + ' token=' + token + ' \033[0m > /dev/stderr') }}
{% endif %}
{%- endmacro -%}
# Объявление переменных для удобства
{% set namespace_id = lookup('custom_vars', 'global.hashicorp.opsPathCommon').split('/')[1] %}
{% set credId = lookup('custom_vars','global.hashicorp.opsHashiCorpCred') %}
{% set opsPathPasswordsConfKV_2 = lookup('custom_vars', 'global.hashicorp.opsPathPasswordsConfKV_2') %}
## где global.hashicorp.opsPathPasswordsConfKV_2=/<путь до хранилища kv2>/KV2 задан в _global.hashicorp.conf
{{ lookup('pipe', 'echo \033[32m Обрабатывается секрет в kv2 engine \033[0m > /dev/stderr') }}
{% for secret_entry in lookup('community.hashi_vault.hashi_vault', 'secret=' + opsPathPasswordsConfKV_2 + '/metadata/folder_with_secrets/?list=true', namespace=namespace_id, token=lookup('custom_vars', credId)).data.keys %}
{% if not secret_entry.endswith('/') %}
{{ print(secret_entry,credId) }}
{% set results=lookup('community.hashi_vault.hashi_vault', 'secret=' + opsPathPasswordsConfKV_2 + '/data/' + secret_entry, namespace=namespace_id,token=lookup('custom_vars', credId)) %}
{% for key, value in results.items() %}
{{ print(opsPathPasswordsConfKV_2 + '/' + secret_entry ,credId) }}
{{ key }}={{ value }}
{% endfor %}
{% endif %}
{% endfor %}