Update vault docs for client scripts, multiple keys and misc (#43993)

* Fix and update vault docs, add and clarify examples and options, introduce the concept of labeling a vault for clarity even if only a single password is in use for a given run, rework multi-password section to align to these concepts.

* Document -client scripts for ansible vault.

Co-Authored-By: orthanc <orthanc@users.noreply.github.com>
pull/52866/head
Ed Costello 6 years ago committed by Alicia Cozine
parent fb97204291
commit 0e467be0f1

@ -7,20 +7,21 @@ Using Vault in playbooks
The "Vault" is a feature of Ansible that allows you to keep sensitive data such as passwords or keys in encrypted files, rather than as plaintext in playbooks or roles. These vault files can then be distributed or placed in source control. The "Vault" is a feature of Ansible that allows you to keep sensitive data such as passwords or keys in encrypted files, rather than as plaintext in playbooks or roles. These vault files can then be distributed or placed in source control.
To enable this feature, a command line tool, :ref:`ansible-vault` is used to edit files, and a command line flag :option:`--ask-vault-pass <ansible-vault --ask-vault-pass>` or :option:`--vault-password-file <ansible-vault --vault-password-file>` is used. You can also modify your ``ansible.cfg`` file to specify the location of a password file or configure Ansible to always prompt for the password. These options require no command line flag usage. To enable this feature, a command line tool, :ref:`ansible-vault` is used to edit files, and a command line flag :option:`--ask-vault-pass <ansible-vault --ask-vault-pass>`, :option:`--vault-password-file <ansible-vault --vault-password-file>` or :option:`--vault-id <ansible-playbook --vault-id>` is used. You can also modify your ``ansible.cfg`` file to specify the location of a password file or configure Ansible to always prompt for the password. These options require no command line flag usage.
For best practices advice, refer to :ref:`best_practices_for_variables_and_vaults`. For best practices advice, refer to :ref:`best_practices_for_variables_and_vaults`.
.. _running_a_playbook_with_vault:
Running a Playbook With Vault Running a Playbook With Vault
````````````````````````````` `````````````````````````````
To run a playbook that contains vault-encrypted data files, you must pass one of two flags. To specify the vault-password interactively:: To run a playbook that contains vault-encrypted data files, you must provide the vault password.
To specify the vault-password interactively::
ansible-playbook site.yml --ask-vault-pass ansible-playbook site.yml --ask-vault-pass
This prompt will then be used to decrypt (in memory only) any vault encrypted files that are accessed. Currently this requires that all files be encrypted with the same password. This prompt will then be used to decrypt (in memory only) any vault encrypted files that are accessed.
Alternatively, passwords can be specified with a file or a script (the script version will require Ansible 1.7 or later). When using this flag, ensure permissions on the file are such that no one else can access your key and do not add your key to source control:: Alternatively, passwords can be specified with a file or a script (the script version will require Ansible 1.7 or later). When using this flag, ensure permissions on the file are such that no one else can access your key and do not add your key to source control::
@ -30,16 +31,80 @@ Alternatively, passwords can be specified with a file or a script (the script ve
The password should be a string stored as a single line in the file. The password should be a string stored as a single line in the file.
If you are using a script instead of a flat file, ensure that it is marked as executable, and that the password is printed to standard output. If your script needs to prompt for data, prompts can be sent to standard error.
.. note:: .. note::
You can also set :envvar:`ANSIBLE_VAULT_PASSWORD_FILE` environment variable, e.g. ``ANSIBLE_VAULT_PASSWORD_FILE=~/.vault_pass.txt`` and Ansible will automatically search for the password in that file. You can also set :envvar:`ANSIBLE_VAULT_PASSWORD_FILE` environment variable, e.g. ``ANSIBLE_VAULT_PASSWORD_FILE=~/.vault_pass.txt`` and Ansible will automatically search for the password in that file.
If you are using a script instead of a flat file, ensure that it is marked as executable, and that the password is printed to standard output. If your script needs to prompt for data, prompts can be sent to standard error. This is something you may wish to do if using Ansible from a continuous integration system like Jenkins.
This is something you may wish to do if using Ansible from a continuous integration system like Jenkins.
The :option:`--vault-password-file <ansible-pull --vault-password-file>` option can also be used with the :ref:`ansible-pull` command if you wish, though this would require distributing the keys to your nodes, so understand the implications -- vault is more intended for push mode. The :option:`--vault-password-file <ansible-pull --vault-password-file>` option can also be used with the :ref:`ansible-pull` command if you wish, though this would require distributing the keys to your nodes, so understand the implications -- vault is more intended for push mode.
Multiple Vault Passwords
````````````````````````
Ansible 2.4 and later support the concept of multiple vaults that are encrypted with different passwords
Different vaults can be given a label to distinguish them (generally values like dev, prod etc.).
The :option:`--ask-vault-pass <ansible-playbook --ask-vault-pass>` and
:option:`--vault-password-file <ansible-playbook --vault-password-file>` options can be used as long as
only a single password is needed for any given run.
Alternatively the :option:`--vault-id <ansible-playbook --vault-id>` option can be used to provide the
password and indicate which vault label it's for. This can be clearer when multiple vaults are used within
a single inventory. For example:
To be prompted for the 'dev' password:
.. code-block:: bash
ansible-playbook site.yml --vault-id dev@prompt
To get the 'dev' password from a file or script:
.. code-block:: bash
ansible-playbook site.yml --vault-id dev@~/.vault_pass.txt
ansible-playbook site.yml --vault-id dev@~/.vault_pass.py
If multiple vault passwords are required for a single run, :option:`--vault-id <ansible-playbook --vault-id>` must
be used as it can be specified multiple times to provide the multiple passwords. For example:
To read the 'dev' password from a file and prompt for the 'prod' password:
.. code-block:: bash
ansible-playbook site.yml --vault-id dev@~/.vault_pass.txt --vault-id prod@prompt
The :option:`--ask-vault-pass <ansible-playbook --ask-vault-pass>` or
:option:`--vault-password-file <ansible-playbook --vault-password-file>` options can be used to specify one of
the passwords, but it's generally cleaner to avoid mixing these with :option:`--vault-id <ansible-playbook --vault-id>`.
.. note::
By default the vault label (dev, prod etc.) is just a hint. Ansible will try to decrypt each
vault with every provided password.
Setting the config option :ref:`DEFAULT_VAULT_ID_MATCH` will change this behavior so that each password
is only used to decrypt data that was encrypted with the same label. See :ref:`specifying_vault_ids`
for more details.
Vault Password Client Scripts
`````````````````````````````
Ansible 2.5 and later support using a single executable script to get different passwords depending on the
vault label. These client scripts must have a file name that ends with :file:`-client`. For example:
To get the dev password from the system keyring using the :file:`contrib/vault/vault-keyring-client.py` script:
.. code-block:: bash
ansible-playbook --vault-id dev@contrib/vault/vault-keyring-client.py
See :ref:`vault_password_client_scripts` for a complete explanation of this topic.
.. _single_encrypted_variable: .. _single_encrypted_variable:
Single Encrypted Variable Single Encrypted Variable

@ -5,7 +5,7 @@ Ansible Vault
Ansible Vault is a feature of ansible that allows you to keep sensitive data such as passwords or keys in encrypted files, rather than as plaintext in playbooks or roles. These vault files can then be distributed or placed in source control. Ansible Vault is a feature of ansible that allows you to keep sensitive data such as passwords or keys in encrypted files, rather than as plaintext in playbooks or roles. These vault files can then be distributed or placed in source control.
To enable this feature, a command line tool - :ref:`ansible-vault` - is used to edit files, and a command line flag (:option:`--ask-vault-pass <ansible-playbook --ask-vault-pass>` or :option:`--vault-password-file <ansible-playbook --vault-password-file>`) is used. Alternately, you may specify the location of a password file or command Ansible to always prompt for the password in your ansible.cfg file. These options require no command line flag usage. To enable this feature, a command line tool - :ref:`ansible-vault` - is used to edit files, and a command line flag (:option:`--ask-vault-pass <ansible-playbook --ask-vault-pass>`, :option:`--vault-password-file <ansible-playbook --vault-password-file>` or :option:`--vault-id <ansible-playbook --vault-id>`) is used. Alternately, you may specify the location of a password file or command Ansible to always prompt for the password in your ansible.cfg file. These options require no command line flag usage.
For best practices advice, refer to :ref:`best_practices_for_variables_and_vaults`. For best practices advice, refer to :ref:`best_practices_for_variables_and_vaults`.
@ -27,6 +27,29 @@ given as the ``src`` argument to the :ref:`copy <copy_module>`, :ref:`template <
As of version 2.3, Ansible supports encrypting single values inside a YAML file, using the `!vault` tag to let YAML and Ansible know it uses special processing. This feature is covered in more details below. As of version 2.3, Ansible supports encrypting single values inside a YAML file, using the `!vault` tag to let YAML and Ansible know it uses special processing. This feature is covered in more details below.
.. _vault_ids:
Vault IDs and Multiple Vault Passwords
``````````````````````````````````````
*Available since Ansible 2.4*
A vault ID is an identifier for one or more vault secrets. Since Ansible 2.4,
Ansible supports multiple vault passwords. Vault IDs provide
labels for individual vault passwords.
Vault-encrypted content can specify which vault ID it was encrypted with.
Prior to Ansible 2.4, only one vault password could be used at a time, So any
vault files or vars that needed to be decrypted all had to use the same password.
Since Ansible 2.4, vault files or vars that are encrypted with different
passwords can be used at the same time.
For example, a playbook can now include a vars file encrypted with a 'dev' vault
ID and a 'prod' vault ID.
.. _creating_files: .. _creating_files:
Creating Encrypted Files Creating Encrypted Files
@ -123,7 +146,7 @@ To encrypt a string provided as a cli arg:
.. code-block:: bash .. code-block:: bash
ansible-vault encrypt_string --vault-id a_password_file 'foobar' --name 'the_secret' ansible-vault encrypt_string --vault-password-file a_password_file 'foobar' --name 'the_secret'
Result:: Result::
@ -139,7 +162,7 @@ To use a vault-id label for 'dev' vault-id:
.. code-block:: bash .. code-block:: bash
ansible-vault encrypt_string --vault-id dev@password 'foooodev' --name 'the_dev_secret' ansible-vault encrypt_string --vault-id dev@a_password_file 'foooodev' --name 'the_dev_secret'
Result:: Result::
@ -155,7 +178,7 @@ To encrypt a string read from stdin and name it 'db_password':
.. code-block:: bash .. code-block:: bash
echo -n 'letmein' | ansible-vault encrypt_string --vault-id dev@password --stdin-name 'db_password' echo -n 'letmein' | ansible-vault encrypt_string --vault-id dev@a_password_file --stdin-name 'db_password'
Result:: Result::
@ -173,7 +196,7 @@ To be prompted for a string to encrypt, encrypt it, and give it the name 'new_us
.. code-block:: bash .. code-block:: bash
ansible-vault encrypt_string --vault-id dev@./password --stdin-name 'new_user_password' ansible-vault encrypt_string --vault-id dev@a_password_file --stdin-name 'new_user_password'
Output:: Output::
@ -194,57 +217,49 @@ Result::
See also :ref:`single_encrypted_variable` See also :ref:`single_encrypted_variable`
.. _vault_ids:
Vault Ids and Multiple Vault Passwords
``````````````````````````````````````
*Available since Ansible 2.4*
A vault id is an identifier for one or more vault secrets. Since Ansible 2.4,
Ansible supports multiple vault passwords. Vault ids is a way to provide
a label for a particular vault password.
Vault encrypted content can specify which vault id it was encrypted with.
Prior to Ansible 2.4, only one vault password could be used at a time. Post
Ansible 2.4, multiple vault passwords can be used each time Ansible runs, so any
vault files or vars that needed to be decrypted all had to use the same password.
Since Ansible 2.4, vault files or vars that are encrypted with different
passwords can be used at the same time.
For example, a playbook can now include a vars file encrypted with a 'dev' vault
id and a 'prod' vault id.
.. _providing_vault_passwords: .. _providing_vault_passwords:
Providing Vault Passwords Providing Vault Passwords
````````````````````````` `````````````````````````
Since Ansible 2.4, the recommended way to provide a vault password from the cli is When all data is encrypted using a single password the :option:`--ask-vault-pass <ansible-playbook --ask-vault-pass>`
to use the :option:`--vault-id <ansible-playbook --vault-id>` cli option. or :option:`--vault-password-file <ansible-playbook --vault-password-file>` cli options should be used.
For example, to use a password store in the text file :file:`/path/to/my/vault-password-file`: For example, to use a password store in the text file :file:`/path/to/my/vault-password-file`:
.. code-block:: bash .. code-block:: bash
ansible-playbook --vault-id /path/to/my/vault-password-file site.yml ansible-playbook --vault-password-file /path/to/my/vault-password-file site.yml
To prompt for a password: To prompt for a password:
.. code-block:: bash .. code-block:: bash
ansible-playbook --vault-id @prompt site.yml ansible-playbook --ask-vault-pass site.yml
To get the password from a vault password executable script :file:`my-vault-password.py`: To get the password from a vault password executable script :file:`my-vault-password.py`:
.. code-block:: bash .. code-block:: bash
ansible-playbook --vault-id my-vault-password.py ansible-playbook --vault-password-file my-vault-password.py
The config option :ref:`DEFAULT_VAULT_PASSWORD_FILE` can be used to specify a vault password file so that the
:option:`--vault-password-file <ansible-playbook --vault-password-file>` cli option does not have to be
specified every time.
The value for :option:`--vault-id <ansible-playbook --vault-id>` can specify the type of vault id (prompt, a file path, etc)
and a label for the vault id ('dev', 'prod', 'cloud', etc) .. _specifying_vault_ids:
Labelling Vaults
^^^^^^^^^^^^^^^^
Since Ansible 2.4 the :option:`--vault-id <ansible-playbook --vault-id>` can be used to indicate which vault ID
('dev', 'prod', 'cloud', etc) a password is for as well as how to source the password (prompt, a file path, etc).
By default the vault-id label is only a hint, any values encrypted with the password will be decrypted.
The config option :ref:`DEFAULT_VAULT_ID_MATCH` can be set to require the vault id to match the vault ID
used when the value was encrypted.
This can reduce errors when different values are encrypted with different passwords.
For example, to use a password file :file:`dev-password` for the vault-id 'dev': For example, to use a password file :file:`dev-password` for the vault-id 'dev':
@ -252,62 +267,81 @@ For example, to use a password file :file:`dev-password` for the vault-id 'dev':
ansible-playbook --vault-id dev@dev-password site.yml ansible-playbook --vault-id dev@dev-password site.yml
To prompt for the 'dev' vault id: To prompt for the password for the 'dev' vault ID:
.. code-block:: bash .. code-block:: bash
ansible-playbook --vault-id dev@prompt site.yml ansible-playbook --vault-id dev@prompt site.yml
*Prior to Ansible 2.4* To get the 'dev' vault ID password from an executable script :file:`my-vault-password.py`:
.. code-block:: bash
ansible-playbook --vault-id dev@my-vault-password.py
The config option :ref:`DEFAULT_VAULT_IDENTITY_LIST` can be used to specify a default vault ID and password source
so that the :option:`--vault-id <ansible-playbook --vault-id>` cli option does not have to be specified every time.
To be prompted for a vault password, use the :option:`--ask-vault-pass <ansible-playbook --vault-id>` cli option:
The :option:`--vault-id <ansible-playbook --vault-id>` option can also be used without specifying a vault-id.
This behaviour is equivalent to :option:`--ask-vault-pass <ansible-playbook --ask-vault-pass>` or
:option:`--vault-password-file <ansible-playbook --vault-password-file>` so is rarely used.
For example, to use a password file :file:`dev-password`:
.. code-block:: bash .. code-block:: bash
ansible-playbook --ask-vault-pass site.yml ansible-playbook --vault-id dev-password site.yml
To specify a vault password in a text file 'dev-password', use the :option:`--vault-password-file <ansible-playbook --vault-password-file>` option: To prompt for the password:
.. code-block:: bash .. code-block:: bash
ansible-playbook --vault-password-file dev-password site.yml ansible-playbook --vault-id @prompt site.yml
There is a config option (:ref:`DEFAULT_VAULT_PASSWORD_FILE`) to specify a vault password file to use To get the password from an executable script :file:`my-vault-password.py`:
without requiring the :option:`--vault-password-file <ansible-playbook --vault-password-file>` cli option.
.. code-block:: bash
ansible-playbook --vault-id my-vault-password.py
.. note::
Prior to Ansible 2.4, the :option:`--vault-id <ansible-playbook --vault-id>` option is not supported
so :option:`--ask-vault-pass <ansible-playbook --ask-vault-pass>` or
:option:`--vault-password-file <ansible-playbook --vault-password-file>` must be used.
Multiple vault passwords
Multiple Vault Passwords
^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
Since Ansible 2.4 and later support using multiple vault passwords, :option:`--vault-id <ansible-playbook --vault-id>` can Ansible 2.4 and later support using multiple vault passwords, :option:`--vault-id <ansible-playbook --vault-id>` can
be provided multiple times. be provided multiple times.
If multiple vault passwords are provided, by default Ansible will attempt to decrypt vault content
by trying each vault secret in the order they were provided on the command line.
For example, to use a 'dev' password read from a file and to be prompted for the 'prod' password: For example, to use a 'dev' password read from a file and to be prompted for the 'prod' password:
.. code-block:: bash .. code-block:: bash
ansible-playbook --vault-id dev@dev-password --vault-id prod@prompt site.yml ansible-playbook --vault-id dev@dev-password --vault-id prod@prompt site.yml
In the above case, the 'dev' password will be tried first, then the 'prod' password for cases By default the vault ID labels (dev, prod etc.) are only hints, Ansible will attempt to decrypt vault content
where Ansible doesn't know which vault id is used to encrypt something. with each password. The password with the same label as the encrypted data will be tried first, after that
each vault secret will be tried in the order they were provided on the command line.
If the vault content was encrypted using a :option:`--vault-id <ansible-vault --vault-id>` option, then the label of the Where the encrypted data doesn't have a label, or the label doesn't match any of the provided labels, the
vault id is stored with the vault content. When Ansible knows the right vault-id, it will try passwords will be tried in the order they are specified.
the matching vault id's secret first before trying the rest of the vault-ids.
There is a config option (:ref:`DEFAULT_VAULT_ID_MATCH` ) to force the vault content's vault id label to match with one of In the above case, the 'dev' password will be tried first, then the 'prod' password for cases
the provided vault ids. But the default is to try the matching id first, then try the other where Ansible doesn't know which vault ID is used to encrypt something.
vault ids in order.
There is also a config option (:ref:`DEFAULT_VAULT_IDENTITY_LIST`) to specify a default list of vault ids to To add a vault ID label to the encrypted data use the :option:`--vault-id <ansible-vault --vault-id>` option
use. For example, instead of requiring the cli option on every use, the (:ref:`DEFAULT_VAULT_IDENTITY_LIST`) config option can be used: with a label when encrypting the data.
.. code-block:: bash The :ref:`DEFAULT_VAULT_ID_MATCH` config option can be set so that Ansible will only use the password with
the same label as the encrypted data. This is more efficient and may be more predictable when multiple
passwords are used.
ansible-playbook --vault-id dev@dev-password --vault-id prod@prompt site.yml The config option :ref:`DEFAULT_VAULT_IDENTITY_LIST` can have multiple values which is equivalent to multiple :option:`--vault-id <ansible-playbook --vault-id>` cli options.
The :option:`--vault-id <ansible-playbook --vault-id>` can be used in lieu of the :option:`--vault-password-file <ansible-playbook --vault-password-file>` or :option:`--ask-vault-pass <ansible-playbook --ask-vault-pass>` options, The :option:`--vault-id <ansible-playbook --vault-id>` can be used in lieu of the :option:`--vault-password-file <ansible-playbook --vault-password-file>` or :option:`--ask-vault-pass <ansible-playbook --ask-vault-pass>` options,
or it can be used in combination with them. or it can be used in combination with them.
@ -316,10 +350,33 @@ When using :ref:`ansible-vault` commands that encrypt content (:ref:`ansible-vau
only one vault-id can be used. only one vault-id can be used.
.. _vault_password_client_scripts:
.. note:: Vault Password Client Scripts
Prior to Ansible 2.4, only one vault password could be used in each Ansible run. The `````````````````````````````
:option:`--vault-id <ansible-playbook --vault-id>` option is not support prior to Ansible 2.4.
When implementing a script to obtain a vault password it may be convenient to know which vault ID label was
requested. For example a script loading passwords from a secret manager may want to use the vault ID label to pick
either the 'dev' or 'prod' password.
Since Ansible 2.5 this is supported through the use of Client Scripts. A Client Script is an executable script
with a name ending in ``-client``. Client Scripts are used to obtain vault passwords in the same way as any other
executable script. For example:
.. code-block:: bash
ansible-playbook --vault-id dev@contrib/vault/vault-keyring-client.py
The difference is in the implementation of the script. Client Scripts are executed with a ``--vault-id`` option
so they know which vault ID label was requested. So the above Ansible execution results in the below execution
of the Client Script:
.. code-block:: bash
contrib/vault/vault-keyring-client.py --vault-id dev
:file:`contrib/vault/vault-keyring-client.py` is an example of Client Script that loads passwords from the
system keyring.
.. _speeding_up_vault: .. _speeding_up_vault:

Loading…
Cancel
Save