Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 15 commits into from
Feb 22, 2019
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 74 additions & 6 deletions docs/docsite/rst/user_guide/playbooks_vault.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,24 @@ 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.

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`.

.. note::
The :option:`--vault-id <ansible-playbook --vault-id>` flag is only avalibe in Ansible 2.4 or later.
acozine marked this conversation as resolved.
Show resolved Hide resolved
.. _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

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::

Expand All @@ -30,16 +34,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.

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::
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.


Multiple vault passwords
````````````````````````

orthanc marked this conversation as resolved.
Show resolved Hide resolved
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 the 'dev' password from a file and prompt for the 'prod' password:
orthanc marked this conversation as resolved.
Show resolved Hide resolved

.. 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 defaut the vault label (dev, prod etc.) is just a hint. Ansible will try to decrypt each
orthanc marked this conversation as resolved.
Show resolved Hide resolved
vault with every provided password.

Setting the config option :ref:`DEFAULT_VAULT_ID_MATCH` will change this behaiour so that each password
acozine marked this conversation as resolved.
Show resolved Hide resolved
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:`specifying_vault_ids` for a complete explanation of this topic.


.. _single_encrypted_variable:

Single Encrypted Variable
Expand Down
167 changes: 108 additions & 59 deletions docs/docsite/rst/user_guide/vault.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.

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`.

Expand All @@ -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.


.. _vault_ids:

Vault Ids and Multiple Vault Passwords
orthanc marked this conversation as resolved.
Show resolved Hide resolved
``````````````````````````````````````

*Available since Ansible 2.4*

A vault id is an identifier for one or more vault secrets. Since Ansible 2.4,
orthanc marked this conversation as resolved.
Show resolved Hide resolved
Ansible supports multiple vault passwords. Vault ids is a way to provide
orthanc marked this conversation as resolved.
Show resolved Hide resolved
a label for a particular vault password.
orthanc marked this conversation as resolved.
Show resolved Hide resolved

Vault encrypted content can specify which vault id it was encrypted with.
orthanc marked this conversation as resolved.
Show resolved Hide resolved

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.
orthanc marked this conversation as resolved.
Show resolved Hide resolved


.. _creating_files:

Creating Encrypted Files
Expand Down Expand Up @@ -125,7 +148,7 @@ To encrypt a string provided as a cli arg:

.. 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::

Expand All @@ -141,7 +164,7 @@ To use a vault-id label for 'dev' vault-id:

.. 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::

Expand All @@ -157,7 +180,7 @@ To encrypt a string read from stdin and name it 'db_password':

.. 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::

Expand All @@ -175,7 +198,7 @@ To be prompted for a string to encrypt, encrypt it, and give it the name 'new_us

.. 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::

Expand All @@ -196,120 +219,146 @@ Result::
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
`````````````````````````

Since Ansible 2.4, the recommended way to provide a vault password from the cli is
to use the :option:`--vault-id <ansible-playbook --vault-id>` cli option.
When all data is encrypted using a single password the :option:`--ask-vault-pass <ansible-playbook --ask-vault-pass>`
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`:

.. 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:

.. 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`:

.. 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.


.. _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
orthanc marked this conversation as resolved.
Show resolved Hide resolved
('dev', 'prod', 'cloud', etc) a password is for as well as how to source the password (prompt, a file path, etc).

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)
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
orthanc marked this conversation as resolved.
Show resolved Hide resolved
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':

.. code-block:: bash

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:
orthanc marked this conversation as resolved.
Show resolved Hide resolved

.. code-block:: bash

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`:
orthanc marked this conversation as resolved.
Show resolved Hide resolved

To be prompted for a vault password, use the :option:`--ask-vault-pass <ansible-playbook --vault-id>` cli option:
.. code-block:: bash

ansible-playbook --vault-id dev@my-vault-password.py

Since Ansible 2.5 a single executable script can be used to get different password for depending on the vault label. Scripts with
acozine marked this conversation as resolved.
Show resolved Hide resolved
names ending in ``-client`` are called with a ``--vault-id`` option indicating which vault to get the
password for. This is typically used when looking up passwords from a secret manager.
For example the :file:`contrib/vault/vault-keyring-client.py` script loads keys from the system keyring:

.. code-block:: bash

ansible-playbook --ask-vault-pass site.yml
ansible-playbook --vault-id dev@contrib/vault/vault-keyring-client.py

Will result in the :file:`vault-keyring-client.py` script being called as follows to get the dev key:

.. code-block:: bash

contrib/vault/vault-keyring-client.py --vault-id dev


The config option :ref:`DEFAULT_VAULT_IDENTITY_LIST` can be used to specify a default vault id and password source
orthanc marked this conversation as resolved.
Show resolved Hide resolved
so that the :option:`--vault-id <ansible-playbook --vault-id>` cli option does not have to be specified every time.

To specify a vault password in a text file 'dev-password', use the :option:`--vault-password-file <ansible-playbook --vault-password-file>` 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

ansible-playbook --vault-id dev-password site.yml

To prompt for the password:

.. code-block:: bash

ansible-playbook --vault-id @prompt site.yml

To get the password from an executable script :file:`my-vault-password.py`:

.. code-block:: bash

ansible-playbook --vault-password-file dev-password site.yml
ansible-playbook --vault-id my-vault-password.py

There is a config option (:ref:`DEFAULT_VAULT_PASSWORD_FILE`) to specify a vault password file to use
without requiring the :option:`--vault-password-file <ansible-playbook --vault-password-file>` cli option.
.. 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
^^^^^^^^^^^^^^^^^^^^^^^^

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.

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:

.. code-block:: bash

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
where Ansible doesn't know which vault id is used to encrypt something.
By default the vault id label (dev, prod etc.) are only hints, Ansible will attempt to decrypt vault content
orthanc marked this conversation as resolved.
Show resolved Hide resolved
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
vault id is stored with the vault content. When Ansible knows the right vault-id, it will try
the matching vault id's secret first before trying the rest of the vault-ids.
Where the encrypted data doesn't have a label, or the label doesn't match any of the provided labels, the
passwords will be tried in the order they are specified.

There is a config option (:ref:`DEFAULT_VAULT_ID_MATCH` ) to force the vault content's vault id label to match with one of
the provided vault ids. But the default is to try the matching id first, then try the other
vault ids in order.
In the above case, the 'dev' password will be tried first, then the 'prod' password for cases
where Ansible doesn't know which vault id is used to encrypt something.
orthanc marked this conversation as resolved.
Show resolved Hide resolved

There is also a config option (:ref:`DEFAULT_VAULT_IDENTITY_LIST`) to specify a default list of vault ids to
use. For example, instead of requiring the cli option on every use, the (:ref:`DEFAULT_VAULT_IDENTITY_LIST`) config option can be used:
To add a vault id label to the encrypted data use the :option:`--vault-id <ansible-vault --vault-id>` option
orthanc marked this conversation as resolved.
Show resolved Hide resolved
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,
or it can be used in combination with them.
Expand Down