
Пароли баз данных, API-ключи и токены в Ansible-плейбуках нельзя хранить открытым текстом — они попадут в Git-историю и будут видны всем участникам репозитория. Ansible Vault шифрует файлы с секретами алгоритмом AES-256. Зашифрованные файлы безопасно коммитить в Git, а пароль vault хранится отдельно. В статье разберём создание vault-файла, использование в playbook и best practices.
Установка Ansible
Если Ansible ещё не установлен:
# Ubuntu 22.04 / 24.04
sudo apt update
sudo apt install ansible -y
# Проверка версии
ansible --version
# ansible [core 2.16.3]Создание vault-файла
ansible-vault create
Создаём новый зашифрованный файл:
ansible-vault create group_vars/all/vault.yml
Vault запросит пароль дважды, затем откроет редактор (по умолчанию vi). Введите секреты в формате YAML:
# Содержимое vault.yml (до шифрования)
vault_db_password: "SuperSecretPassword123!"
vault_api_key: "sk-proj-abc123xyz456"
vault_smtp_password: "MailPass!99"
vault_redis_password: "RedisSecret2025"
После сохранения и выхода файл будет зашифрован. Содержимое файла:
$ANSIBLE_VAULT;1.1;AES256
36343161326533633037363032623437633861313839613932613465333632303034666130
3361613662336530306135356135313766636662303163610a333563616232353834373864
...

ansible-vault encrypt
Если файл уже существует в открытом виде — зашифровать его:
ansible-vault encrypt group_vars/all/vault.yml
Расшифровать для просмотра:
ansible-vault decrypt group_vars/all/vault.yml
# ОСТОРОЖНО: файл становится открытым на диске
Просмотреть без расшифровки на диске:
ansible-vault view group_vars/all/vault.yml
Редактировать зашифрованный файл:
ansible-vault edit group_vars/all/vault.yml
# Открывает редактор, шифрует обратно при сохранении
Сменить пароль vault:
ansible-vault rekey group_vars/all/vault.ymlСтруктура переменных
Рекомендуемая практика: хранить незашифрованные переменные в одном файле, зашифрованные в другом. Незашифрованный файл ссылается на переменные из vault.
Структура:
inventory/
group_vars/
all/
vars.yml <- открытые переменные
vault.yml <- зашифрованные секреты
webservers/
vars.yml
vault.yml
host_vars/
web-01/
vars.yml
vault.yml
Файл group_vars/all/vars.yml (открытый, коммитится в Git):
# Параметры БД
db_host: "db.internal.example.com"
db_port: 5432
db_name: "myapp_production"
db_user: "myapp"
db_password: "{{ vault_db_password }}"
# API
api_endpoint: "https://api.example.com/v2"
api_key: "{{ vault_api_key }}"
# SMTP
smtp_host: "smtp.sendgrid.net"
smtp_port: 587
smtp_user: "apikey"
smtp_password: "{{ vault_smtp_password }}"
Файл group_vars/all/vault.yml (зашифрованный):
vault_db_password: "SuperSecretPassword123!"
vault_api_key: "sk-proj-abc123xyz456"
vault_smtp_password: "MailPass!99"
Такой подход удобен: в vars.yml видна структура конфигурации (имена переменных, логика), а секреты изолированы в vault.yml.
Использование vault в playbook
Если vault-файлы находятся в group_vars/ или host_vars/, Ansible подхватывает их автоматически. Явно указывать через vars_files не нужно.
Playbook deploy.yml:
---
- name: Deploy application
hosts: webservers
become: yes
tasks:
- name: Install required packages
ansible.builtin.apt:
name:
- python3
- python3-pip
state: present
update_cache: yes
- name: Configure database connection
ansible.builtin.template:
src: templates/database.conf.j2
dest: /etc/myapp/database.conf
owner: myapp
group: myapp
mode: "0640"
notify: Restart application
- name: Set API key in environment
ansible.builtin.lineinfile:
path: /etc/myapp/environment
line: "API_KEY={{ api_key }}"
regexp: "^API_KEY="
create: yes
handlers:
- name: Restart application
ansible.builtin.systemd:
name: myapp
state: restarted
Шаблон templates/database.conf.j2:
[database]
host = {{ db_host }}
port = {{ db_port }}
name = {{ db_name }}
user = {{ db_user }}
password = {{ db_password }}
Переменная db_password подтянет значение из vault_db_password через цепочку в vars.yml.
Для явного указания vault-файла через vars_files:
- name: Deploy with explicit vault
hosts: webservers
vars_files:
- group_vars/all/vars.yml
- group_vars/all/vault.yml
tasks:
...

Хранение пароля vault в файле .vault_pass
Вводить пароль вручную при каждом запуске неудобно. Храним пароль в файле:
# Создаём файл с паролем
echo "ВашПарольVault2025" > ~/.vault_pass
chmod 600 ~/.vault_pass
Никогда не коммитьте .vault_pass в Git. Добавьте в .gitignore:
.vault_pass
*.vault_pass
Запуск playbook без ввода пароля вручную:
ansible-playbook deploy.yml --vault-password-file ~/.vault_pass
Или в ansible.cfg:
[defaults]
vault_password_file = ~/.vault_pass
inventory = inventory/
После этого команды работают без явного указания файла с паролем:
ansible-playbook deploy.yml
ansible-vault edit group_vars/all/vault.ymlНесколько vault-паролей
Ansible поддерживает несколько vault ID — для разных окружений или уровней секретности.
# Создаём vault с ID "production"
ansible-vault create --vault-id production@~/.vault_pass_production group_vars/production/vault.yml
# Создаём vault с ID "staging"
ansible-vault create --vault-id staging@~/.vault_pass_staging group_vars/staging/vault.yml
Запуск с несколькими vault:
ansible-playbook deploy.yml \
--vault-id production@~/.vault_pass_production \
--vault-id staging@~/.vault_pass_stagingCI/CD интеграция
В GitHub Actions / GitLab CI пароль vault передаётся через секрет репозитория:
# GitHub Actions
- name: Run Ansible playbook
run: |
echo "${{ secrets.VAULT_PASSWORD }}" > /tmp/.vault_pass
chmod 600 /tmp/.vault_pass
ansible-playbook deploy.yml --vault-password-file /tmp/.vault_pass
rm /tmp/.vault_pass
В GitLab CI:
deploy:
script:
- echo "$VAULT_PASSWORD" > /tmp/.vault_pass
- chmod 600 /tmp/.vault_pass
- ansible-playbook deploy.yml --vault-password-file /tmp/.vault_pass
- rm /tmp/.vault_pass

Шифрование отдельных строк
Иногда нужно зашифровать одно поле прямо в незашифрованном YAML-файле:
ansible-vault encrypt_string 'SuperSecret123' --name 'db_password'
Вывод:
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
61613962356633303031383339353233666239356435623362623061353766633337373761363863
...
Вставьте этот блок прямо в vars.yml. Файл остаётся незашифрованным, но конкретная переменная защищена.
Best practices
1. Называйте vault-переменные с префиксом vault_ Это сразу показывает что переменная из vault: vault_db_password вместо просто db_password.
2. Не шифруйте всё подряд Шифруйте только реальные секреты. Имена хостов, порты и имена пользователей — открытые данные, их шифровать не нужно.
3. Один vault-файл на окружение Разделяйте секреты production и staging. Если staging-ключ утечёт — production не пострадает.
4. Ротация паролей Меняйте vault-пароль при уходе сотрудника: ansible-vault rekey. Новый пароль рассылается только действующим членам команды.
5. Проверяйте что vault зашифрован перед коммитом Добавьте pre-commit hook:
# .git/hooks/pre-commit
#!/bin/bash
for file in $(git diff --cached --name-only | grep vault); do
if ! grep -q "ANSIBLE_VAULT" "$file"; then
echo "ERROR: $file is not encrypted!"
exit 1
fi
done
chmod +x .git/hooks/pre-commitИтог
Ansible Vault защищает секреты через AES-256 шифрование. Рабочая схема: секреты в vault.yml с префиксом vault_, открытые переменные в vars.yml со ссылками на vault-переменные, пароль vault в ~/.vault_pass с правами 600. В CI/CD пароль vault передаётся через секрет репозитория в переменную окружения.
Разделение на vars.yml + vault.yml удобнее чем шифрование всего файла целиком: видна структура конфигурации, легче ревьюить изменения.