Комментарии 6
В плане написания playbook и использования ansible, можно сказать, что я совсем зеленый и могу не понимать некоторых концепций. Но поставленные задачи выполняются. Так же для понижения порога использования коллегами, была развернута Web-GUI обертка над ansible (awx).
И вот, я как то столкнулся с проблемой хранения и передачи пароля в playbook, например в виде аргумента какой-нибудь команды или в виде аргумента к модулю.
Путь 1 - записать пароль напрямую в playbook. В нашем случае доступ до ansible ограниченный и доступ имеет только наша группа. Не хорошо, но допустимо. Но пароль может поменяться.
Путь 2 - внести его в виде переменной и передавать в виде чем-то вроде --extra-vars. Думаю лучше, данная концепция отрабатывает сейчас.
Путь 3 - подумал попробовать освоить встроенные средства хранения паролей. В документации описано что-то вроде того, что и в данной статье. Но возник вопрос, который буквально лежит на поверхности -
Eсли использовать vault только для хранения пароля, то нужно вводить пароль для его расшифровки. Зачем мне его вообще выводить в хранилище, если требуется интерактивное вмешательство.
Но если хранить пароль в хранилище и расшифровывать его файлом с ключом в файле (без дополнительных телодвижений "по открытию/закрытию сейфа") - то какая принципиальная разница от того, что я бы хранил его в открытом виде в виде переменной?
Я в Ansible тоже отнюдь не гуру :) Но vault использую с первого своего плейбука, и вот почему.
Расположение переменных определяется структурой проекта - и какие-то пароли должны быть в ролях, какие-то - в host_vars и group_vars и т.п. Выносить "секретные" переменные в отдельное место - рушить эту структуру.
Но при этом весь проект Ansible коммитится в GitHub, где паролям, очевидно, не место. Даже если git локальный - всё равно хранить их там в plain-text виде не лучшая идея.
Посему все переменные с паролями и пр. шифруются ansible-vault, файлик с паролем к vault хранится вне основной папки проекта, в ansible.cfg забит путь к этому файлику, чтобы каждый раз в командную строку опцию не добавлять. Как-то так.
В целом можно расширить безопасность ещё дальше, если тот самый файлик с паролем будет не постоянно лежать на диске, а сам по себе расшифровываться/подмонтироваться откуда-то. Тут уже зависит от того, кто, откуда и как запускает плейбуки. Я пока что исключительно со своего ноута, у которого диск и так зашифрован, так что мне хватает перечисленного выше.
Благодарю за ответ! Раз уж зашла душещипательная для меня тема - а как использовать пароль из хранилища в самом playbook?
Например для модуля shell мне нужно подставить в команду логин/пароль. При использовании просто переменной я воспользуюсь {{ login }} / {{ pass }}. А как подставить пароль из ранее подключенного хранилища?
Можно у вас попросить написать микро-пример playbook, использующего пароль из хранилища в явном виде, например для shell модуля? Очень не хватает немногословных примеров по конкретным задачам
В плейбуке ровно так же используем переменную, как будто она не зашифрована. В определении переменной значение начинаем с селектора !vault и дальше всё то, что ansible-vault выдал нам при шифровании.
Ну вот, скажем, из живого плейбука, который SSL-сертификаты обновляет и распихивает по серверам. В tasks/main.yml соответствующей роли дёргаем API DNS-провайдера с секретным ключиком (который в данном случае нам надо в переменную окружения положить):
- name: Run acme.sh
ansible.builtin.command: "~/.acme.sh/acme.sh --issue {{ domain_list }} --server {{ acme_server_url }} -k 2048
--dns dns_vultr --force --log --cert-file ~/.certs/cert.cer --key-file ~/.certs/cert.key --ca-file ~/.certs/ca.cer
--fullchain-file ~/.certs/fullchain.cer"
environment:
VULTR_API_KEY: "{{ vultr_api_key }}"
args:
chdir: ~/.acme.sh/
Здесь на эту переменную vultr_api_key мы ссылаемся так же, как будто она у нас без всякого шифрования где-то лежит. А vars/main.yml она уже описана следующим образом:
vultr_api_key: !vault |
$ANSIBLE_VAULT;1.1;AES256
30376430623162316......
А вообще, эта статья и написание комментариев к ней натолкнули на мысль продвинуться ещё на шажок в этом направлении.
Все пароли и прочие секреты у меня так или иначе лежат в Bitwarden (точнее, в собственном Vaultwarden). Обновлять их ещё и в Ansible - двойная работа. Но к Ansible есть lookup plugin community.general.bitwarden, который данные оттуда напрямую и берёт. В результате остаётся только добавить в начало каждого плейбука ссылку на таск "разлочить vault" (bitwarden'овский), а в конец - на таск "залочить vault обратно", "секретные" переменные переопределить через соответствующий lookup, - и в ansible-vault можно хранить только реквизиты доступа к самому Bitwarden.
Надо сделать.
Если пароли хранятся во внешнем hashicorp vault, то можно использовать такую схему.
в конфиге ansible.cfg прописываем адрес хранилища
[lookup_hashi_vault]
url = https://vault.example.com
ставим один раз плагин, если используется старая версия ansible
ansible-galaxy collection install community.hashi_vault
pip3 install hvac
создаем файлик secrets.yaml для хоста или группы
Переменной postgres_password пользуемся как обычной переменной в ansible
---
#install to use
#ansible-galaxy collection install community.hashi_vault
#pip3 install hvac
#set ANSIBLE_HASHI_VAULT_USERNAME env var or ansible_hashi_vault_username ansible var for username option
#set ANSIBLE_HASHI_VAULT_PASSWORD env var or ansible_hashi_vault_password ansible var for password option
#set ANSIBLE_HASHI_VAULT_TOKEN env var or ansible_hashi_vault_token ansible var for token option
postgres_password: "{{ lookup('community.hashi_vault.hashi_vault', 'secret=infrastructure/data/Endpoints_Secrets:db01_postgres') }}"
Перед запуском плейбука указываем реквизиты доступа или токен к vault, например.
export ANSIBLE_HASHI_VAULT_TOKEN=blablalba
ansible-playbook myplay.yml -DC
Расширяем возможности Ansible: Ansible Vault