Модуль 07 — Ansible Vault

Хранить пароли рядом с кодом, но так, чтобы репозиторий можно было показать

Прогресс курса Модуль 7 из 9

Что вы освоите в этом модуле

01

Пароль в репозитории

В модуле 06 пароль базы лежал открытым текстом:

$ cat group_vars/db.yml
postgres_database: price
postgres_user: price_app
# Пароль открытым текстом — так делать нельзя; в модуле 07 он уедет в Ansible Vault
postgres_password: Uchebnyi-Parol-2026

Проект живёт в Git. Значит, пароль видит каждый, у кого есть доступ к репозиторию, он остаётся в истории навсегда и уезжает на каждый ноутбук, где проект склонирован. Хранить секреты отдельно от проекта неудобно: плейбук без них не работает, и при каждом запуске их приходится откуда-то брать. Ansible Vault шифрует файлы и значения прямо в проекте. Без ключа зашифрованное — набор цифр, с ключом Ansible расшифровывает его на лету при прогоне.

02

vars и vault

Если зашифровать весь group_vars/db.yml, никто без ключа не увидит даже, какие переменные там есть, и поиск по проекту перестанет их находить. Поэтому принято делить переменные группы на два файла в каталоге group_vars/db/ — Ansible читает все файлы каталога:

$ mkdir group_vars/db && mv group_vars/db.yml group_vars/db/vars.yml
$ printf "vault_postgres_password: Uchebnyi-Parol-2026\n" > group_vars/db/vault.yml
$ sed -i "s/^postgres_password: .*/postgres_password: \"{{ vault_postgres_password }}\"/; /^# Пароль открытым/d" group_vars/db/vars.yml
$ cat group_vars/db/vars.yml
postgres_database: price
postgres_user: price_app
postgres_password: "{{ vault_postgres_password }}"

Теперь по открытому файлу видно, что пароль есть и откуда он берётся, а поиск vault_postgres_password сразу ведёт к зашифрованному файлу.

03

Ключ Vault

Шифровать нужно ключом — паролем Vault. Его можно вводить при каждом запуске (--ask-vault-pass), но удобнее держать в файле вне проекта с правами только для владельца:

$ printf "%s\n" "Uchebnyi-Kluch-Vault-2026" > ~/.vault_pass && chmod 600 ~/.vault_pass

В .gitignore проекта на всякий случай есть и .vault_pass — если кто-то положит ключ в каталог проекта, Git его не возьмёт:

# пароль Vault в репозиторий не кладут никогда
.vault_pass
*.retry

Ключ хранят в менеджере паролей команды и выдают тем, кому нужно запускать плейбуки. Длинный случайный ключ лучше придуманного: зашифрованные файлы лежат в репозитории, и их можно подбирать сколько угодно долго без всяких ограничений.

04

Зашифровать и посмотреть

$ ansible-vault encrypt --vault-password-file ~/.vault_pass group_vars/db/vault.yml
$ cat group_vars/db/vault.yml
$ANSIBLE_VAULT;1.1;AES256
62363965646533653866373734373932613561363935626464373137336562373961346464366132
3562373133316633653462383731653138323164666465620a623062666235353665663163306463
35633461303233323264323661396334613633623436366462376234623631613534356362393263
3130383261303833350a333132383237643031666531633237633931363061396530363831303635
38363263643264623838613839633063666161396635313965653338623533346533626562346464
3933623266363335366634363535343665316138643033323933
$ ansible-vault view --vault-password-file ~/.vault_pass group_vars/db/vault.yml
vault_postgres_password: Uchebnyi-Parol-2026

Первая строка — заголовок: формат Vault и алгоритм AES-256. Остальное — зашифрованное содержимое. Такой файл можно коммитить. Основные команды:

КомандаЧто делает
ansible-vault encrypt файлЗашифровать существующий файл на месте
ansible-vault view файлПоказать расшифрованное, не сохраняя на диск
ansible-vault edit файлОткрыть в редакторе и зашифровать обратно при сохранении
ansible-vault decrypt файлРасшифровать на месте — легко забыть зашифровать обратно и закоммитить
ansible-vault rekey файлПерешифровать новым ключом
ansible-vault encrypt_stringЗашифровать одно значение для вставки в обычный YAML

Править секреты — только через edit: расшифрованная копия не остаётся на диске и не попадёт в коммит.

05

Прогон с секретами

Без ключа Ansible не может прочитать vault.yml и останавливается сразу, ничего не сделав:

$ ansible-playbook site.yml --limit db1 2>&1 | grep -E "ERROR|vault" | head -2
[ERROR]: Attempting to decrypt but no vault secrets found.

С ключом всё работает как раньше:

$ ansible-playbook site.yml --limit db1 --vault-password-file ~/.vault_pass 2>&1 | grep -E "^db1 "
db1                        : ok=9    changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Чтобы не писать ключ в каждой команде, путь к файлу ключа задают в ansible.cfg (vault_password_file = ~/.vault_pass) или переменной окружения ANSIBLE_VAULT_PASSWORD_FILE. Вместо файла можно указать исполняемый скрипт — он вернёт ключ из менеджера паролей или системного хранилища. В конвейере CI ключ кладут в защищённую переменную-файл и передают тем же параметром (курс Основы CI/CD).

Если у окружений разные секреты, у них могут быть и разные ключи: --vault-id prod@~/.vault_prod --vault-id stage@~/.vault_stage. Тогда разработчик с ключом stage сможет запускать плейбуки на тестовых узлах, но не расшифрует пароли боя.

06

Одна переменная: encrypt_string

Когда секрет один, а файл с ним в основном открытый, шифруют только значение. Результат вставляют прямо в YAML:

$ ansible-vault encrypt_string --vault-password-file ~/.vault_pass --name smtp_password "Pochta-Uchebnaya-2026"
smtp_password: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          34666166613339353463333034313935656664376463653764656166646530323335353030373364
          3832326638393631363062323638633931613035373236650a336364343631383765333135396139
          38396134666531333631343464663636316534613961663539323434643061343031353163616662
          3834326561393838610a643234353233383634653432666264353235303232323533666166366361
          62616536343832343165393931313561646639313337353561323732336231333335

Минус — по такому файлу неудобно делать ревью: изменение секрета выглядит как замена одного блока цифр другим. Для нескольких секретов схема vars/vault из раздела 02 удобнее.

07

Чего Vault не защищает

Vault защищает секреты в репозитории. Во время прогона они расшифрованы и обычные переменные, которые можно вывести:

$ ansible db1 -m debug -a "var=postgres_password" --vault-password-file ~/.vault_pass
db1 | SUCCESS => {
    "postgres_password": "Uchebnyi-Parol-2026"
}

Поэтому задачи, в параметрах которых есть секреты, помечают no_log: true — как задачу создания пользователя базы в роли postgres. Даже с подробным выводом -v её результат скрыт:

$ ansible-playbook site.yml --limit db1 --vault-password-file ~/.vault_pass -v 2>&1 | grep -A2 "Пользователь приложения"
TASK [postgres : Пользователь приложения] **************************************
ok: [db1] => {"censored": "the output has been hidden due to the fact that 'no_log: true' was specified for this result", "changed": false}
08

Смена ключа

Ушёл сотрудник, у которого был ключ, — ключ меняют. rekey перешифровывает файлы новым ключом:

$ printf "%s\n" "Novyi-Kluch-Vault-2026" > ~/.vault_pass.new && chmod 600 ~/.vault_pass.new
$ ansible-vault rekey --vault-password-file ~/.vault_pass --new-vault-password-file ~/.vault_pass.new group_vars/db/vault.yml
Rekey successful
$ mv ~/.vault_pass.new ~/.vault_pass && ansible-vault view --vault-password-file ~/.vault_pass group_vars/db/vault.yml
vault_postgres_password: Uchebnyi-Parol-2026

Важно: старые версии зашифрованных файлов остались в истории Git, и бывший сотрудник со старым ключом расшифрует их. Поэтому вместе с ключом Vault меняют и сами секреты — пароли баз, токены, — а потом шифруют новые значения новым ключом.

Ключевые выводы модуля

Запомните главное

  • Секреты — в group_vars/группа/vault.yml с префиксом vault_; в vars.yml — ссылки на них
  • Ключ Vault — вне репозитория, файл с правами 600 или скрипт к менеджеру паролей; длинный и случайный
  • Править — ansible-vault edit, смотреть — view; decrypt на месте — путь к утечке
  • Разные окружения — разные ключи через --vault-id
  • Vault защищает репозиторий, а не вывод: задачи с секретами — no_log: true
  • Сменили ключ — смените и секреты: старые версии остались в истории Git
Практические задания — на учебном портале. Задания, критерии оценивания, сдача работ и оценки преподавателя — в курсе на portal.nevabit.ru. Учётную запись выдаёт преподаватель.
Модуль 06: Роли и коллекции Все модули Модуль 08: Проверка и отладка