0

I followed the tutorial provided here : Editing Ansible vault file from a playbook to create the ability to programmatically update my ansible vaults.

Let's say though this is part of a much larger pipeline, where it unreasonable to expect the end user to sit around waiting for the 3+ ansible-vault vault password prompts.

Is there a way to programmatically provide an ansible-vault call with the vault password such that it is automatically entered when it is required?

Ideally, the user at run-time would enter once the vault-password as part of the larger script, and then as the script encounters needs that require ansible-vault the password is provided as a variable as well so the user doesn't have to constantly check back to enter it.

rok
  • 9,403
  • 17
  • 70
  • 126
Jibril
  • 967
  • 2
  • 11
  • 29
  • 2
    As a very first thought: provide the password as prompt at play level, store that password in a temporary file and run your `ansible-vault` task setting the `ANSIBLE_VAULT_PASSWORD_FILE` environment var to that file. Also note that since the response you followed was given, ansible as gained since version 2.12 an [unvault lookup](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/unvault_lookup.html) and a [vault filter](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/vault_filter.html) you might want to consider. [Example](/questions/75336902/) – Zeitounator Feb 06 '23 at 17:48
  • Hm this could be a work around. I cant believe there isn't just a cleaner way of doing it for a purpose where you dont want a password sitting around in a plaintext file though. – Jibril Feb 07 '23 at 22:09

2 Answers2

0

Ansible can read Vault passwords from script output. You have to write a shell script with the name that ends with -client and make it executable. File name extensions like .py are supported after the -client part. Your script should accept --vault-id=<id> parameter where <id> is the id of the Vault or empty, and it must return the password corresponding the <id> via stdout.

In its simpliest form your script could, for example, echo a predefined environment variable that you set in the environment parameter of the playbook task. No command line parameter parsing needed if you work with just one Vault id at the time. However, if you need to provide different passwords for multiple Vault ids at the same time (multiple --vault-id parameters per Ansible command), then you must parse and process the --vault-id parameter accordingly.

All Ansible commands that accept --vault-id parameter support password entry via script. Syntax for the parameter is --vault-id <id>@<input method> where <input method> can be path to a static text file, path to an executable file, or prompt for keyboard-interactive password input.

If you specify a value for <id> then Ansible will call your script with parameter --vault-id=<id>. Otherwise the script will be called with parameter --vault-id=. When used with ansible-vault, <id> becomes the id of the resulting Vault. If no <id> is provided then the resulting Vault will not have an id.

Examples

This is a very simple password client script. To use this script, save it into a text file named example-client, make it executable, and store your Vault password into env VAULT_PASSWORD using your preferred method.

#!/usr/bin/bash
echo -n $VAULT_PASSWORD

You can then provide password for a Vault with id myvault like this:
ansible-playbook --vault-id myvault@example-client <other parameters>
or create a Vault without an id:
ansible-vault encrypt_string --vault-id @example-client

If you want to use Ansible playbook task to create an Ansible-compatible YAML file that can be later imported with include_vars – which supports Vault – you can add --stdin-name parameter and redirect output to a file:

- name: Create Vault progammatically
  environment:
    VAULT_PASSWORD: Pa$$word123
  shell:
    cmd: >
      ansible-vault encrypt_string
      --vault-id myvault@example-client
      --stdin-name password > /path/to/vault.yml
    stdin: This text will be stored in the Vault
    stdin_add_newline: false
  register: vault_result

You can provide the text to be vaulted via stdin but be sure to omit the trailing newline when piping or it will become part of the Vault content.

Source

Ansible docs, especially https://docs.ansible.com/ansible/2.9/user_guide/vault.html#vault-password-client-scripts

anttiah
  • 1
  • 1
0
  • You can provide vault password to ansible-vault. For example, ansible-vault decrypt vault.yml --vault-password-file multi_password_file.

  • In addition you can use ansible-vault Python package for reading the vault in Python:

vault = Vault((Path('multi_password_file').read_text()))
data = vault.load(open('vault.yml').read())

You can read more details about how to use Ansible Vault in Python.

Disclaimer: I wrote this article.

rok
  • 9,403
  • 17
  • 70
  • 126