Начиная с версии 1.5 в Ansible была доабвлена возможность хранения секретных данных, таких как пароли или RSA ключи, в зашифрованных файлах — vault («хранилище»).
Для работы с такими хранилищами используется утилита ansible-vault
, которая принимает два основных аргумента — --ask-vault-pass
или --vault-password-file
, которые могут быть заданы через ansible.cfg.
Располагается в /usr/bin/ansible-vault
и представялет собой Python-скрипт.
Содержание
Шифрование файлов
Для создания хранилища — используется create
:
[simterm]
$ ansible-vault create file.yml
New Vault password:
Confirm New Vault password:
[/simterm]
После чего открывается редактор по умолчанию, что бы в файл можно было добавить данные.
Результат:
[simterm]
$ cat file.yml
$ANSIBLE_VAULT;1.1;AES256
32333262313562656230663934383566373966633138346137313937306230373633333730343839
6330346166626235376530333662663961636365393631340a623165306231383636643066306665
39303633623361643065636338326336333366656363313762316336623732626631643437336663
6466336232316131390a316464383837623361333964383235616365316263336565336136663063
6635
[/simterm]
Что бы зашифровать уже имеющий файл — используется encrypt
:
[simterm]
$ echo "data" > raw_file.txt $ ansible-vault encrypt raw_file.txt New Vault password: Confirm New Vault password: Encryption successful $ cat raw_file.txt $ANSIBLE_VAULT;1.1;AES256 65303737323263313938656134323635313039363131626331643835393034323335343432383438 3232643162313534643231613661623264656365663437650a353661376235346134313362653066 64393066333937373334353361623735366334666463346633613463373532646535636566663831 3434623235653933650a313038343833323236623061633065323266336237623461383930646662 6538
[/simterm]
Расшифровка файлов
Что бы зашифрованный файл снова вернуть в plaintext — используем decrypt
:
[simterm]
$ ansible-vault decrypt file.yml
Vault password:
Decryption successful
$ cat file.yml
test data
[/simterm]
Редактирование файлов
Используется ansible-vault edit
:
[simterm]
$ ansible-vault edit file.yml
Vault password:
[/simterm]
Файл расшифровывается во временный файл, открывается для редактирования, после завершения — снова шифруется и сохраняется в старом месте:
Просмотр файла
Что бы просто просмотреть содержимое хранилища — используем view
.
Шифруем файл опять:
[simterm]
$ ansible-vault encrypt file.yml
New Vault password:
Confirm New Vault password:
Encryption successful
[/simterm]
И проверяем содержимое:
[simterm]
$ ansible-vault view file.yml
Vault password:
test data
[/simterm]
Смена пароля
Для смены пароля используется rekey
, который можно применять к нескольким файлам сразу, если они зашифрованы одним ключём (паролем).
Создадим новый:
[simterm]
$ ansible-vault create file2.yml
New Vault password:
Confirm New Vault password:
[/simterm]
И меняем пароль для обоих файлов:
[simterm]
$ ansible-vault rekey file.yml file2.yml
Vault password:
New Vault password:
Confirm New Vault password:
Rekey successful
[/simterm]
Примеры
Прмиеры будем запускать на локальной машине.
Пример использования зашифрованного файла
Создаём простой плейбук helloworld.yml
:
--- - hosts: all tasks: - debug: msg: "hello world"
Проверяем:
[simterm]
$ ansible-playbook -i "localhost," -c local helloworld.yml PLAY [all] **** TASK [Gathering Facts] **** ok: [localhost] TASK [debug] **** ok: [localhost] => { "msg": "hello world" } PLAY RECAP **** localhost : ok=2 changed=0 unreachable=0 failed=0
[/simterm]
ОК, теперь добавим создание файла с текстом из зашифрованного файла в Ansible.
Создаём файл vars/exmple_text.yml
со строкой:
data_text: | some text data another text data
Создаём файл с паролем:
[simterm]
$ echo «MySuperPass» > ~/.ansible_pass.txt
[/simterm]
Шифруем файл vars/exmple_text.yml
:
[simterm]
$ ansible-vault encrypt vars/exmple_text.yml —vault-password-file ~/.ansible_pass.txt
Encryption successful
[/simterm]
Проверяем его:
[simterm]
$ head -n 2 vars/exmple_text.yml
$ANSIBLE_VAULT;1.1;AES256
33303034383034313365383135323837613963646235393533643361343061306336373236663837
[/simterm]
Обновляем наш helloworld.yml
, добавляем создание файла, который будет содержать текст :
--- - hosts: all tasks: - debug: msg: "hello world" - name: add var include_vars: file: exmple_text.yml - name: Add descrypted text from exmple_text.yml copy: content="{{ data_text }}" dest=/tmp/example_text_out.txt
Запускаем, передавая --vault-password-file
:
[simterm]
$ ansible-playbook -i "localhost," -c local helloworld.yml --vault-password-file ~/.ansible_pass.txt PLAY [all] **** TASK [Gathering Facts] **** ok: [localhost] TASK [debug] **** ok: [localhost] => { "msg": "hello world" } TASK [add var] **** ok: [localhost] TASK [Add descrypted text from exmple_text.yml] **** changed: [localhost] PLAY RECAP **** localhost : ok=4 changed=1 unreachable=0 failed=0
[/simterm]
Проверяем:
[simterm]
$ cat /tmp/example_text_out.txt
some text data
another text data
[/simterm]
Всё на месте.
Пример шифрования переменной
Кроме файла — можно зашифровать строку, например:
[simterm]
$ ansible-vault encrypt_string New Vault password: Confirm New Vault password: Reading plaintext input from stdin. (ctrl-d to end input) This is Text String !vault | $ANSIBLE_VAULT;1.1;AES256 38363965343563353962666264646337613464663263663632626264373563633430323633356639 3737333233393662336533376661333163653035333334370a373565343330633537363563656430 37363632636664353864353532633030326231356238643634623033396539656164666437343565 3964653033343136620a356438316635663561313665323739353766383233656261646538616165 66313237633635646265653633323635333861636539313937343363666539366465 Encryption successful
[/simterm]
Либо выполнить одной командой:
[simterm]
$ ansible-vault encrypt_string "This is Text String" --name "encrypted_data_string" --vault-password-file ~/.ansible_pass.txt encrypted_data_string: !vault | $ANSIBLE_VAULT;1.1;AES256 36653162656434373362396464353061343337343866323436366138636266666165636163623337 3339343833383064303036346661616235396563356362630a363430313566323537363964663636 32303931333561633632323265346136323139616536343466663736666138333638306133653935 3066643730653831300a663735333639343064666636336139336536353734343963313032373338 35643639643136623163346662623763633763366462396433323133306532663038 Encryption successful
[/simterm]
Далее эта строка может использоваться в переменной.
Добавим новый файл vars/strings.yml
с переменной encrypted_data_string
:
--- encrypted_data_string: !vault | $ANSIBLE_VAULT;1.1;AES256 36653162656434373362396464353061343337343866323436366138636266666165636163623337 3339343833383064303036346661616235396563356362630a363430313566323537363964663636 32303931333561633632323265346136323139616536343466663736666138333638306133653935 3066643730653831300a663735333639343064666636336139336536353734343963313032373338 35643639643136623163346662623763633763366462396433323133306532663038
Обновим плейбук:
--- - hosts: all tasks: - debug: msg: "hello world" - name: add vars include_vars: file: exmple_text.yml - name: add another vars include_vars: file: strings.yml - name: Add decrypted text from exmple_text.yml copy: content="{{ data_text }}" dest=/tmp/example_text_out.txt - name: Add another decrypted text from strings.yml copy: content="{{ encrypted_data_string }}" dest=/tmp/another_example_text_out.txt
Запускаем выполнение:
[simterm]
$ ansible-playbook -i "localhost," -c local helloworld.yml --vault-password-file ~/.ansible_pass.txt PLAY [all] **** TASK [Gathering Facts] **** ok: [localhost] TASK [debug] **** ok: [localhost] => { "msg": "hello world" } TASK [add vars] **** ok: [localhost] TASK [add another vars] **** ok: [localhost] TASK [Add decrypted text from exmple_text.yml] **** ok: [localhost] TASK [Add another decrypted text from strings.yml] **** changed: [localhost] PLAY RECAP **** localhost : ok=6 changed=1 unreachable=0 failed=0
[/simterm]
Проверяем:
[simterm]
$ cat /tmp/another_example_text_out.txt
This is Text String
[/simterm]
Или используя --ask-vault-pass
:
[simterm]
$ ansible-playbook -i «localhost,» -c local helloworld.yml —ask-vault-pass
Vault password:
…
[/simterm]
vault-id
В Ansible 2.4 и выше вместо --ask-vault-pass
и --vault-password-file
можно использовать --vault-id
, который позволяет использовать разные пароли для разных файлов.
Создадим новые файлы вместо exmple_text.yml
и strings.yml
, зашифруем их разными паролями.
Файлы паролей:
[simterm]
$ echo "pass1" > pass1.txt $ echo "pass2" > pass2.txt
[/simterm]
Создаём файл vars/data_text1.yml
с переменной data_text1
:
[simterm]
$ echo «data_text1: Data Text One» > vars/data_text1.yml
[/simterm]
Шифруем его паролем из файла pass1.txt
:
[simterm]
$ ansible-vault —vault-id pass1.txt encrypt vars/data_text1.yml
Encryption successful
[/simterm]
Аналогично — второй файл:
[simterm]
$ echo «data_text2: Data Text Two» > vars/data_text2.yml
[/simterm]
И тоже шифруем его, вторым паролем:
[simterm]
$ ansible-vault —vault-id pass2.txt encrypt vars/data_text2.yml
Encryption successful
[/simterm]
Обновим плейбук:
--- - hosts: all tasks: - debug: msg: "hello world" - name: add data_text1.yml include_vars: file: data_text1.yml - name: add data_text2.yml include_vars: file: data_text2.yml - name: Add decrypted data_text1 copy: content="{{ data_text1 }}" dest=/tmp/data_text1_out.txt - name: Add decrypted data_text2 copy: content="{{ data_text2 }}" dest=/tmp/data_text2_out.txt
И запускаем его:
[simterm]
$ ansible-playbook -i "localhost," -c local --vault-id pass1.txt --vault-id pass2.txt helloworld.yml PLAY [all] **** TASK [Gathering Facts] **** ok: [localhost] TASK [debug] **** ok: [localhost] => { "msg": "hello world" } TASK [add data_text1.yml] **** ok: [localhost] TASK [add data_text2.yml] **** ok: [localhost] TASK [Add decrypted data_text1] **** changed: [localhost] TASK [Add decrypted data_text2] **** changed: [localhost] PLAY RECAP **** localhost : ok=6 changed=2 unreachable=0 failed=0
[/simterm]
Проверяем:
[simterm]
$ cat /tmp/data_text*
Data Text OneData Text Two
[/simterm]
Так же --vault-id
можно использовать вместе с --vault-password-file
:
[simterm]
$ rm /tmp/data_text*
$ ansible-playbook -i "localhost," -c local --vault-id pass1.txt --vault-password-file pass2.txt helloworld.yml ... localhost : ok=6 changed=2 unreachable=0 failed=0
[/simterm]
Либо использовать --ask-vault-pass
вместо указания файла:
[simterm]
$ rm /tmp/data_text* $ ansible-playbook -i "localhost," -c local --vault-id pass1.txt --ask-vault-pass helloworld.yml Vault password: ... localhost : ok=6 changed=2 unreachable=0 failed=0
[/simterm]
Сам --vault-password-file
тоже можно использовать несколько раз:
[simterm]
$ ansible-playbook -i "localhost," -c local --vault-password-file pass1.txt --vault-password-file pass2.txt helloworld.yml
[/simterm]
Ansible попробует каждый из переданных паролей, пока один из них не сработает для зашированного файла.
Ссылки по теме
2.4 support for multiple vault passwords, looking for feedback