4

I have the ability to encrypt variables using another mechanism(Azure pipeline secret feature), so I would like to save an ansible-vault password there(in Azure pipeline) and pass it to playbook execution as an extra var.

May I know if it can be done so?

An example of what/how I'm expecting is

ansible-playbook --extra-vars "vault-password=${pipelinevariable}"
r0r0n0a
  • 173
  • 2
  • 2
  • 10
  • Did you consider using https://docs.ansible.com/ansible/latest/modules/azure_rm_keyvaultsecret_module.html ? – Zeitounator Jul 03 '20 at 07:21
  • Hi friend, could you please check if my workaround helps to resolve your issue? Feel free to let me know if I can help anything :) – LoLance Jul 09 '20 at 10:36
  • Thanks for your help, @Zeitounator, Lance Li-MSFT. I think put simply, I was looking for a straightforward way to pass the password as a variable, which Zeitounator stated cant be done. But thanks Lance Li for providing alternatives. I didn't try the suggestions, as I just moved forward with my task without a password, but was curious about the possibility in that implementation. – r0r0n0a Jul 11 '20 at 19:14

4 Answers4

8

Vault password cannot be passed as an extra var. There are several ways to provide it which are all covered in the documentation:

Very basically your options are:

  • providing it interactively passing the --ask-vault-pass option
  • reading it from a file (static or executable) by either:
    1. providing the --vault-password-file /path/to/vault option on the command line
    2. setting the ANSIBLE_VAULT_PASSWORD_FILE environment variable (e.g. export ANSIBLE_VAULT_PASSWORD_FILE=/path/to/vault).

There is much more to learn in the above doc, especially how to use several vault passwords with ids, how to use a client script to retrieve the password from a key store...

Zeitounator
  • 38,476
  • 7
  • 53
  • 66
  • Useful info (Vote for you)! Just confused about can I get a secret file via echo password>password.txt? (Not familiar with Ansible Vault) – LoLance Jul 03 '20 at 03:29
  • @LanceLi-MSFT You can echo the decrypted password into any file you later use on the command line. That works OK for a CI where your recycle your "runner" (or whatever you call those in azure). Meanwhile (disclaimer: I don't know azure at all....) I would prefer to declare as the vault-password-file an executable script which would directly retreive the password from the keystore. – Zeitounator Jul 03 '20 at 07:48
4

May I know if it can be done so?

Not familiar with Ansible Vault, but you have at least two directions based on the documents shared by Zeitounator.

1.Use a CMD task first to create a vault-password-file with plain-text content. (Not sure if the vault-password-file can be created in this way, it might not work.)

(echo $(SecretVariableName)>xxx.txt)

Then you may use the newly created xxx.txt file as input of ansible-playbook --vault-password-file /path/to/my/xxx.txt xxx.yml.

2.Create a corresponding vault-password-file before running the pipeline, add it to version control. (Same source repo of your current pipeline)

Then you can use ansible-playbook --vault-password-file easily when the vault-password-file is available. Also you can store the password file in private github repo, fetch the repo via git clone https://{userName}:{userPassword}@github.com/xxx/{RepoName}.git, copy the needed password file to the directory where you run the ansible-playbook commands via Copy Files task. This direction should work no matter if direction 1 is supported.

LoLance
  • 25,666
  • 1
  • 39
  • 73
  • 1
    Option 2b (seperate git repo) with a lot of security around can be used but I would personnaly not recommend. Option 2a looks totally a no-go to me: you get the encrypted data and the secret to decrypt it the same repo. In this case just don't encrypt anything, it will be easier. I guess you can use option 1 from an azure pipeline retreiving the needed password from its specific keystore. – Zeitounator Jul 03 '20 at 08:05
  • Yes, option1 is much more easier. I'm just not sure if it can work cause I'm not familiar with how content of vault-password-file should look like. I'm familiar with Azure Devops but not Ansible :( So I again provide option2 which should work for most scenarios though it's not that convenient. Thanks for the suggestion~ – LoLance Jul 03 '20 at 08:09
  • If the file is static, it should only contain the password on a single line (i.e.your above example looks quite good to me). If it is executable, it should only return the password itself. – Zeitounator Jul 03 '20 at 10:14
3

Although this doesn't use extra vars, I believe it fulfills what you were trying to do:

Optional/one-time only: ask for the password and set it as an environment variable:

read -s ansible_vault_pass && export ansible_vault_pass

Now use that variable in your ansible command:

ansible-playbook your-playbook.yml --vault-password-file <(cat <<<"$ansible_vault_pass")

Credits for, and explanation of the <(cat <<<"") technique are in this other StackOverflow answer: Forcing cURL to get a password from the environment.

EdwardTeach
  • 615
  • 6
  • 18
  • Nope does not work. Get this error when trying to use this method `ERROR! The vault password file /proc/2483888/fd/pipe:[10334948] was not found` – Dave Mar 09 '23 at 19:25
  • What shell and OS are you using? I've done this on Linux and OS X. I just tried it again, and it is working for me: `GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin22)` – EdwardTeach Apr 27 '23 at 14:57
  • I am not using apple/mac. Using Ubuntu server 20.04. Bash: `GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)`, Kernel: `5.4.0-148-generic`, What you shared appears to be for apple, what version are you using for pure linux not mac/apple? – Dave Apr 28 '23 at 12:14
3

None of these answers worked for me. I did find a answer that does work from the post here. From all the research I have done you cant actually pass the password in as an extra var and have it be used to as the vault password. You have to send your password in as stdin. The trick is to use --vault-password-file=/bin/cat. Now when you pass via stdin, --vault-password-file will look for a file, but you are passing a program, cat which will read the input of stdin and use it instead of using a static password file. Here is an example below:

echo 'mYP4s5w0rd' | ansible-playbook -i ./inventory.ini ./settings.yaml --vault-password-file=/bin/cat

This actually works, and doesn't create a static file that could be captured by someone.

Dave
  • 727
  • 1
  • 9
  • 20