91

I have been waiting for ansible 2.3 as it was going to introduce encrypt_string feature.

Unfortuately I'm not sure how can I read the encrypted string.

I did try decrypt_string, decrypt (the file), view (the file) and nothing works.

cat test.yml 
---
test: !vault |
     $ANSIBLE_VAULT;1.1;AES256
     37366638363362303836383335623066343562666662386233306537333232396637346463376430
     3664323265333036663736383837326263376637616466610a383430623562633235616531303861
     66313432303063343230613665323930386138613334303839626131373033656463303736366166
     6635346135636437360a313031376566303238303835353364313434363163343066363932346165
     6136

The error I'm geeting is ERROR! input is not vault encrypted data for test.yml

How can I decrypt the string so I know what it's value without the need to run the play?

techraf
  • 64,883
  • 27
  • 193
  • 198
MMT
  • 1,931
  • 3
  • 19
  • 35
  • 3
    You can extract the encrypted part and pipe it to stdin of `ansible-vault decrypt`, but I guess a play would still be easier. – techraf Apr 18 '17 at 08:43
  • 5
    Vote for https://github.com/ansible/ansible/issues/26190 to allow `ansible-vault decrypt` to handle inline encrypted variables. – Shane Sep 27 '17 at 20:01
  • What's the problem for which you're using inline vaulted text. I sense an X Y problem here. Also, why can't you run the play with a debug task (use no_log: true for the task(s) which expose sensitive data) if you just want to verify the crypted text? Another option would be to put the sensitive data into a var.yml file and vault that file. – Jeter-work Apr 13 '23 at 18:11

22 Answers22

64

You can also do with plain ansible command for respective host/group/inventory combination, e.g.:

$ ansible my_server -m debug -a 'var=my_secret'
my_server | SUCCESS => {
    "my_secret": "373861663362363036363361663037373661353137303762"
}
famousgarkin
  • 13,687
  • 5
  • 58
  • 74
  • 10
    Even easier is to just use `localhost` instead of `my_server`. – Welsh Oct 02 '17 at 17:57
  • 2
    @Welsh could be, depends on your group/host vars setup. – famousgarkin Oct 02 '17 at 18:07
  • In principle, this seems the simplest option. It avoids having to [copy text from the hosts/vars file, trim whitespace, and paste it into the terminal](https://stackoverflow.com/questions/43467180#comment83677346_45107666). Unfortunately, for me it resulted in `FAILED! => {"msg": "Attempting to decrypt but no vault secrets found"}`. Perhaps this is because the variable I want to decrypt was defined for a group rather than for a specific host? –  Feb 16 '18 at 22:01
  • 3
    @sampablokuper That error messge means that ansible can't find any passwords to use for decryption. You need to specify the path to a password file or use the `--ask-vault-pass` flag to make this command prompt you for the password. – Omn Jun 12 '18 at 22:13
  • 5
    If your encrypted variable is in a vars file, you can add a `-e '@path/to/vars/file'` option to your ansible command, for a final command of: `ansible localhost -e '@vars/file' --ask-vault-pass -m debug -a 'var=my_secret'` – wfaulk Apr 14 '20 at 21:48
  • Once again I'm reminded of why I prefer using a separate vault file over inline encrypted strings: wading through all of these techniques vs. `ansible-vault decrypt` – Joe Apr 18 '22 at 19:55
60

You can pipe the input then tell ansible-vault to output to stderr and then redirect the stdout to /dev/null since the tool prints Decryption successful.

The /dev/stdin/ part may not be needed in new Ansible versions.

Something like:

echo 'YOUR_SECRET_VALUE' | ansible-vault decrypt /dev/stdin --output=/dev/stderr > /dev/null

Here is a example:

echo '$ANSIBLE_VAULT;1.1;AES256
30636561663762383436386639353737363431353033326634623639666132623738643764366530
6332363635613832396361333634303135663735356134350a383265333537383739353864663136
30393363653361373738656361613435626237643633383261663138653466393332333036353737
3335396631613239380a616531626235346361333737353831376633633264326566623339663463
6235' | ansible-vault decrypt /dev/stdin --output=/dev/stderr > /dev/null

I hope they implement a simpler way of doing this.

Edit: Environment Variables as Input:

To have a similar behaviour with multi-line environment variables on bash use printf instead of echo

Example (password: 123):

export chiphertext='$ANSIBLE_VAULT;1.1;AES256
65333363656231663530393762613031336662613262326666386233643763636339366235626334
3236636366366131383962323463633861653061346538360a386566363337383133613761313566
31623761656437393862643936373564313565663633636366396231653131386364336534626338
3430343561626237660a333562616537623035396539343634656439356439616439376630396438
3730'

printf "%s\n" $chiphertext | ansible-vault decrypt /dev/stdin --output=/dev/stderr > /dev/null
Scudelletti
  • 1,470
  • 17
  • 19
  • 14
    For some reason `echo "$ciphertext" | ansible-vault decrypt /dev/stdin` would not work for me. I kept getting `ERROR! [Errno 2] No such file or directory: u'/proc/22899/fd/pipe:[39394403]'`. I had to pipe `$ciphertext` into a temporary file instead of using `/dev/stdin`. – Dave Jul 04 '17 at 12:09
  • @DaveParrish you have to use single quotes on the echo. Since the shell thinks `$ANSIBLE_VAULT` is a environment variable but it's not. Example: `export AAA=Wow` Then run `echo "$AAA"` will return `Wow`. `echo '$AAA'` will return `$AAA` – Scudelletti Jul 04 '17 at 15:24
  • do you have a solution for using a bash variable which contains the ciphertext then? Will `echo '$chiphertext' | ansible-vault decrypt /dev/stdin` work? – Dave Jul 05 '17 at 03:35
  • @DaveParrish I thought `$ciphertext` was a placeholder, a kind of abstraction not a env variable. Sorry for that. I noticed that I get a different result since I'm using `zsh`. You can try to use `printf` instead of `echo` adding a newline on the end of each line. The command will be something similar to `printf "%s\n" $chiphertext | ansible-vault decrypt /dev/stdin --output=/dev/stderr > /dev/null` I updated the answer with this info. – Scudelletti Jul 06 '17 at 07:52
  • `printf` doesn't work for me either. I'm really not sure why, but using a temporary file is a acceptable workaround for me. – Dave Jul 06 '17 at 14:09
  • There is an issue with Ansible 2.4.0+ https://github.com/ansible/ansible/issues/30550 – Eugene Song Dec 13 '17 at 22:50
  • 8
    @DaveParrish, with Ansible 2.4.2.0, `echo '$ciphertext' | ansible-vault decrypt /dev/stdin --output=/dev/stderr > /dev/null` gave me `ERROR! [Errno 2] No such file or directory: u'/proc/24569/fd/pipe:[1371726]'` (actual numbers changed for privacy). However, `echo '$ciphertext' | ansible-vault decrypt - --output=/dev/stderr > /dev/null` worked fine, as did `echo '$ciphertext' | ansible-vault decrypt` per Coleman Corrigan's [answer](https://stackoverflow.com/a/45107666). –  Feb 16 '18 at 19:04
  • (N.B. In my comment above, I am using `$ciphertext` as a placeholder, *not* as a Bash variable. I believe this is different to the way @DaveParrish used it further above. Sorry if this confuses anyone!) –  Feb 16 '18 at 22:09
  • 4
    Worked for me when I took out the `/dev/stdin`. Recent versions probably detect whether it's receiving stdin so need for it. – Andrey Kaipov Aug 14 '20 at 18:08
38

since whole vault files do not play well with git histories, using vault strings within the variable files is the way to go, it also makes grepping out variables by name much clearer.

Here is a simple worked example:

I want to put fredsSecretString: value into vars.yml , (its value is fastfredfedfourfrankfurters but hush, don't let people know !!)

$ ansible-vault encrypt_string 'fastfredfedfourfrankfurters' -n fredsSecretString >> vars.yml
New Vault password: fred
Confirm New Vault password: fred
$ cat vars.yml
fredsSecretString: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          36643662303931336362356361373334663632343139383832626130636237333134373034326565
          3736626632306265393565653338356138626433333339310a323832663233316666353764373733
          30613239313731653932323536303537623362653464376365383963373366336335656635666637
          3238313530643164320a336337303734303930303163326235623834383337343363326461653162
          33353861663464313866353330376566346636303334353732383564633263373862

To decrypt the value feed the encrypted string back into ansible-vault as follows:

    $ echo '$ANSIBLE_VAULT;1.1;AES256
    36643662303931336362356361373334663632343139383832626130636237333134373034326565
    3736626632306265393565653338356138626433333339310a323832663233316666353764373733
    30613239313731653932323536303537623362653464376365383963373366336335656635666637
    3238313530643164320a336337303734303930303163326235623834383337343363326461653162
    33353861663464313866353330376566346636303334353732383564633263373862' |
 ansible-vault decrypt && echo
    Vault password: fred
    Decryption successful
    fastfredfedfourfrankfurters
    $
  • 3
    Fantastic! Thanks for showing that to us. For everyone attempting this please note that in order for it to work you have to remove whitespace from your ANSIBLE_VAULT string. This is something @coleman-corrigan shows above but I missed my first couple of tries. – Robert J Jan 19 '18 at 16:48
  • 6
    Had to replace newline with literal(\n) and enable interpretation of escape sequences `# echo -e '$ANSIBLE_VAULT;1.1;AES256\n34626638366161336437303439643066366466376431346336613332336433386539303737613663\n6639393965653239356435613038303030616163333565300a313932616365383336323839363935\n66363439666461323466343366343737373834353333363935346132356663346365386163323733\n3332316134323064310a386164373661323233333862643231303034663632363061383433616166\n62653564653035316165666363656461386632333738666663323664303963393437' | ansible-vault decrypt && echo Vault password: Decryption successful` – KVS Aug 29 '18 at 22:47
  • 11
    For decrypting, I added `tr -d ' '` to remove the whitespace so that I could copy the secret directly from my source code without having to manipulate it first. e.g. `echo '$ANSIBLE_VAULT;1.1;AES256 366436623039313363623563613733346636323431393838326261306...' | tr -d ' ' | ansible-vault decrypt && echo` – Joy Peterson Dec 13 '18 at 17:12
  • 1
    This is all very useful, but i can't believe how big of a pain this is... – user2490003 Sep 26 '19 at 03:29
  • i had some issue with spaces at the new lines - you have to remove them to execute successfully - otherwise you will get an error message: valt format unhexlify error: on-hexadecimal digit found for – fty4 Jan 15 '20 at 13:53
25

Did you try setting the encrypted string as a variable and then using -debug to get its decrypted output?

i.e.

Define your encrypted string as a variable test in your playbook and then do:

-debug: msg="My Secret value is {{test | replace('\n', '')}}"

in your playbook and then run the playbook:

$ ansible-playbook -i localhost YourPlaybook.yml --vault-password-file path/to/your/secret_key_file
lehins
  • 9,642
  • 2
  • 35
  • 49
NAF
  • 322
  • 5
  • 11
  • I did come up with similar solution i.e. `tasks: name: "{{ test_var }}"` however I was hoping for something more like with the **eyaml** encrypt/decrypt string options. – MMT Apr 18 '17 at 09:01
12

Here's another way to decrypt strings

$ ansible localhost \
       -m debug \
       -a "var=mysecret" \
       -e "@inventory/group_vars/master"
localhost | SUCCESS => {
"mysecret": "somesecret\n"
}

The trick here is we're passing a file with an Ansible vaulted secret, mysecret within it too ansible and it's able to decrypt it.

NOTE: If you do not have your password to decrypt the Ansible vaulted encrypted secret you can pass that in as well:

$ ansible localhost --vault-password-file=~/.vault_pass.txt \
       -m debug \
       -a "var=mysecret" \
       -e "@inventory/group_vars/master"
localhost | SUCCESS => {
"mysecret": "somesecret\n"
}
slm
  • 15,396
  • 12
  • 109
  • 124
8

yq extracts the encrypted var value, then will create a temporary file and use it with ansible-vault:

cat ansible_file.yml | yq -r ".variable_name" > tmp_file.txt

# you can also use 'ansible-vault decrypt'
ansible-vault view --ask-vault-pass tmp_file.txt
alfredocambera
  • 3,155
  • 34
  • 29
  • 2
    I like your answer. It is very simple and useful. I have couple of things to report. When installed via `brew` on OS X, the `yq` tool doesn't use `-r` but simple `r` for reading on certain path. Also, there is no need to cat & pipe, it has an option to read directly from file. And lastly, we can directly decrypt it without using temp file. – maricn Jun 25 '19 at 15:10
  • 2
    My suggestion would be: `yq -t r group_vars/staging.yml "app.super_secret_key" | ansible-vault decrypt --vault-password-file .vault_pass_staging` – maricn Jun 25 '19 at 15:11
  • Thanks didn't know that – alfredocambera Jun 25 '19 at 16:18
8

You can do it with a one-liner

ansible localhost -m debug -a var='NAME_OF_ENCRYPTED_VAR' \
-e "@PATH_TO_FILE_WITH_VARIABLE" --vault-id yourid@/path/to/file

or enter the password from command line

ansible localhost -m debug -a var='NAME_OF_ENCRYPTED_VAR' \
-e "@PATH_TO_FILE_WITH_VARIABLE" --ask-vault-pass
Robert Siemer
  • 32,405
  • 11
  • 84
  • 94
Evren Yurtesen
  • 2,267
  • 1
  • 22
  • 40
6

With this you can decrypt a file containing just an ansible vault string:

cat encrypted_vault_string | ansible-vault decrypt

output:

Vault passsword: <enter password, is not echoed to you>
Decryption successful
< decrypted string here>

An ansible vault string looks like:

$ANSIBE_VAULT;1.1;AES256
123456789...
123456789...
123456789...
1234

This also works without an intermediate file

echo -e '$ANSIBLE_VAULT;1.1;AES256\n123456789...789' | ansible-vault decrypt
Jens Timmerman
  • 9,316
  • 1
  • 42
  • 48
eludum
  • 61
  • 1
  • 1
5

Here is what works for me, similar to what Scudelletti does but passing in the vault pass i.e.

echo '$ANSIBLE_VAULT;1.1;AES256
31363861346536343331393539323936346464386534346337306565626466393764666366363637
6533373165656431393662653463646430663933363431380a336130363131373238326330393931
39343533396161323834613030383339653633393133393932613562396630303530393030396335
3630656237663038630a363032373633363161633464653431386237333262343231313830363965
31393930343532323133386536376637373463396534623631633234393565373337613530643031
38393862616635326339373731353465303364303365336132613566396666626536636533303839
393465653830393231636638643735313666' | ansible-vault decrypt --vault-password-file /path/to/your/.vault_pass.txt /dev/stdin --output=/dev/stderr > /dev/null && echo

The output will be on its own line for convenience, thanks to the trailing && echo. The permission of my vault pass is 644 if you run into any permission errors.

Hope it helps!

radtek
  • 34,210
  • 11
  • 144
  • 111
5

You can copy the encrypted string to a file but you need to only copy the encrypted part and not the other yml parts.

So you file need to change from:

test: !vault |
     $ANSIBLE_VAULT;1.1;AES256
     37366638363362303836383335623066343562666662386233306537333232396637346463376430
     3664323265333036663736383837326263376637616466610a383430623562633235616531303861
     66313432303063343230613665323930386138613334303839626131373033656463303736366166
     6635346135636437360a313031376566303238303835353364313434363163343066363932346165
     6136

to:

$ANSIBLE_VAULT;1.1;AES256
37366638363362303836383335623066343562666662386233306537333232396637346463376430
3664323265333036663736383837326263376637616466610a383430623562633235616531303861
66313432303063343230613665323930386138613334303839626131373033656463303736366166
6635346135636437360a313031376566303238303835353364313434363163343066363932346136

And you'll be able to decript or view with

ansible-vault decrypt --vault-password-file <path to passwordfile> test.yml

ansible-vault view --vault-password-file <path to passwordfile> test.yml

And perhaps drop the .yml because that doesn't make sense anymore.

softarn
  • 5,327
  • 3
  • 40
  • 54
4

Although, there is no problems showing encrypted string values with ansible debug messages or using ansible cli, there is one more solution that may be convenient for automation needs. You can utilize python libs from ansible and use them in your code (basically, all this located in ansible.parsing.*)

1) Provide vault password and generate "vault" with secrets.

# Load vault password and prepare secrets for decryption
loader = DataLoader()
secret = vault.get_file_vault_secret(filename=vault_password_file, loader=loader)
secret.load()
vault_secrets = [('default', secret)]
_vault = vault.VaultLib(vault_secrets)

2) Load yaml file with AnsibleLoader:

with codecs.open(input_file, 'r', encoding='utf-8') as f:
    loaded_yaml = AnsibleLoader(f, vault_secrets=_vault.secrets).get_single_data()

3) If you need to encrypt a new string and update your dictionary:

    new_encrypted_value = objects.AnsibleVaultEncryptedUnicode.from_plaintext(source_system_password, _vault, vault_secrets[0][1])
    loaded_yaml[target_env]['credentials'][external_system_name]['password'] = new_encrypted_variable

4) Once complete processing, write back with AnsibleDumper:

with open('new_variables.yml','w') as fd:
    yaml.dump(loaded_yaml, fd, Dumper=AnsibleDumper, encoding=None, default_flow_style=False)
andruhan
  • 41
  • 1
  • 1
    could you please include the corresponding `import`s. I'm trying to write a script to decrypt/encrypt individual vars from ansible vars files. I was parsing files using `yq` but this approach seems way better. – alfredocambera Apr 01 '19 at 23:22
  • `from ansible.parsing.dataloader import DataLoader from ansible.parsing.vault import get_file_vault_secret, VaultLib from ansible.parsing.yaml.loader import AnsibleLoader` – rawat Jul 31 '19 at 23:25
3

This one command extracts out just the encrypted data and passes it to decrypt. I like it a bit better, as you don't need to manually extract the data.

$ grep -v vault test.yml | awk '{$1=$1;print}' | ansible-vault decrypt
slm
  • 15,396
  • 12
  • 109
  • 124
Scott Carlson
  • 3,764
  • 1
  • 17
  • 11
2

For those who want to define an alias and forget about pipes and temp files, here is a solution which you can adopt:

function decrypt_ansible_vault_string() { 
   export FN=$1
   export KEY=$2
   ansible-vault view <(yq r $FN $KEY)
   }

Example usage:

$ head myrole/var/main.yml
# Variables here override defaults
website:
  server: 127.0.0.1
  port: 8081
  session:
    hash_key: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          33626439623630633332343836316334376637323738323061373334373733326566613262373036
          6632623432373263613139646432333331313731326232390a653031366564313235323065303865
          32383563393261326633306663663437386134666230373332646234656464356331646335636564

$ decrypt_ansible_vault_string myrole/vars/main.yml website.session.hash_key

This answer expands on the comment from @maricn Note, I am using this yq, but any yaml query tool can do. It's the principle of using subshell redirect that matters here (No temp files). Also note, you can add --ask-vault-password. However, using a secret encrypted with GPG is much nicer, since you don't have to type your password every time and this work flow is much better for teams (YMVV and IHMO). Here is a good tutorial on how to use GPG with ansible-vault.

Stick this in your .bashrc and enjoy it.

update

I got frustrated with ansible-vault encrypt\decrypt workflow. So, I created a wrapper for also decrypting strings in the var files. Check it out: https://github.com/oz123/ansible-vault-string-helper

oz123
  • 27,559
  • 27
  • 125
  • 187
2

I know it's been a while, but it worked for me when I piped it through ansible-vault decrypt without anything else, like this:

$ echo '$ANSIBLE_VAULT;1.1;AES256
38613538323065373061616466616334306237336461333935393261646131616232643238626635
3336633631366539383039343437306664336165326565650a353233303431613362653838643135
34363763366134393366356339343039313035366164636133326639376334313335316565373330
3435633463313334310a653239313039323135363865313933626464663363656164343662303763
34616663626530656630633839346531653862633332396365396432366234333861' | ansible-vault decrypt
Decryption successful
super-secret-string$ 

Just in case anyone is interested. I have ansible version 2.9.26

streetcornerlurker
  • 501
  • 1
  • 7
  • 14
2

Trying to decrypt /dev/stdin, as in ansible-vault decrypt /dev/stdin, or using --vault-password-file=/dev/stdin, like other commenters mention, also fails for me with errors like ERROR! [Errno 2] No such file or directory: '/proc/100/fd/pipe:[12930445]'.

However, --vault-password-file also takes an executable to produce the password on stdout, so you can actually use /bin/cat to pipe in the password:

echo password | ansible-vault decrypt --output - --vault-password-file=/bin/cat ./encrypted_vault_file

jonny
  • 4,264
  • 4
  • 22
  • 29
1

The most convenient way of doing it would be just adding a function to your ~/.bashrc or ~/.zshrc, imo.

vdecr() {
  unset IFS
  if [[ -n "$1" ]]; then
    if [[ -f "$1" ]]; then
      if [[ $(head -n1 "$1") == "\$ANSIBLE_VAULT;1.1;AES256" ]]; then
        cat "$1" | ansible-vault decrypt 2> /dev/null
        return 0
      fi
      printf 'Reading vault values from file...\n\n'
      IFS="#"
      for v in `grep "\!vault |" -A6 "$1" | sed 's/^--$/#/g' | sed -r 's/^(.*:)/#\n\1/g'`;do
        if [[ "$v" != "" ]]; then
          printf "$v" | grep -o "^.*: " | xargs && printf '  ' && vdecr "$v";
        fi ;
      done
      unset IFS
      return 0
    fi
    local str="$1"
  elif [[ ! -t 0 ]]; then
    local str=$(cat)
  else
    printf 'Interactive mode. Paste encrypted string and press Ctrl-D two times to confirm.\n'
    local str=$(cat)
    printf '\n'
  fi
  printf -- "$str" | sed 's/ /\n/g' | \
  sed '/---\|^.*:\|\!vault\||\|^$/d' | \
  ansible-vault decrypt 2> /dev/null | \
  tail -n1
  printf '\n'
}

It works in bash and zsh without any additional packages except ansible-vault itself. This function can accept input as an argument, from stdin, interactively or from file. It can work with many encrypted strings in file. I.e. if you feed group vars file to it, it will parse and decrypt all vault values from it. The function checks if it is fully vault-encrypted file and prints it's decrypted content.

  • First, test whether we deal with argument, file or if STDIN is not a terminal - let's make it versatile :-)
    if [[ -n "$1" ]], if [[ -f "$1" ]], [[ ! -t 0 ]]
  • If argument is a file, check if it is fully encrypted or not $(head -n1 "$1") == "\$ANSIBLE_VAULT;1.1;AES256". If it is fully encrypted just cat file into ansible-vault decrypt. If not - read vault values from it grep "\!vault |" -A6 "$1" and feed to vdecr one by one. grep uses -- as separator, and it can break variables with-names-like-this, when parsing, since IFS is only one character long. So sed ^--$ to # and specify new IFS. If vault-vars go one after another without space between, grep won't print separator, so add a line with separator in between sed -r 's/^(.*:)/#\n\1/g'. xargs just trims spaces.
  • $(cat) is just reading stdin
  • Assign a value to our variable and start parsing
  • Change all spaces to newlines, since newlines may get squashed when passing as an argument and vault needs them
    sed 's/ /\n/g'
  • Then delete !vault, |, ---, empty lines and var name (everything between start of string and colon)
    sed '/---\|^.*:\|\!vault\||\|^$/d'
  • Finally pass it to ansible-vault decrypt, redirecting all errors and warnings into /dev/null and taking just the last line of output, which will contain unencrypted text.
    ansible-vault decrypt 2> /dev/null | tail -n 1

And then add it to your ~/.bashrc or ~/.zshrc, source it and use it any way you want:

cat test.yml | vdecr
vdecr test.yml
vdecr path/to/group/vars.yml
vdecr path/to/encrypted/file
vdecr '!vault |
          $ANSIBLE_VAULT;1.1;AES256
          35346165343065373135616164383132636533366436623739373739613862376563653838313839
          3365393739626664336162353836643333323931626530310a343566643261363532316364383933
          36313462303031626139623666353764316330303862393538353138376564313262373365393735
          6662646438636332330a323061653966626234363530373039343837353062663762373734373235
          3864'
test_string=$(ansible-vault encrypt_string "HiddenText!"); vdecr "$test_string"
ansible-vault encrypt_string "HiddenText!" | vdecr

OR you can just run vdecr, paste the string and hit Ctrl-D.

If passing value as an argument, make sure to use it with single quotes so that $ANSIBLE_VAULT won't get expanded into nothing by bash.
If passing value as a var, quote the var.
When dealing with argument, function works with ! vault | prefix and without it.

Here is a bonus alias for generating ansible-vault-encrypted passwords

alias genpwdv="ansible-vault encrypt_string $(openssl rand -base64 25 | sed 's/[\/+=]//g' | cut -c 3-20) 2> /dev/null"
0

This is how I am encrypting and decrypting strings inline, additionally for use as environment variables.

yq is especially useful here for interpreting yaml input.

In one line if I were to test encrypt and decypt a string I would do this-

echo -n "test some input that will be encrypted and decrypted" | ansible-vault encrypt_string --vault-id $vault_key --stdin-name testvar_name | yq r - "testvar_name" | ansible-vault decrypt --vault-id $vault_key

I'm guessing that those usually interested in this are interested in decrypting environment variables. This is how I implement that use case, where testvar is the encrypted environment variable, and and $vault-id is the path to the key you are using to encrypt/decrypt.

testvar=$(echo -n "test some input that will be encrypted and stored as an env var" | ansible-vault encrypt_string --vault-id $vault_key --stdin-name testvar_name | base64 -w 0)
result=$(echo $testvar | base64 -d | /var/lib/snapd/snap/bin/yq r - "testvar_name" | ansible-vault decrypt --vault-id $vault_key); echo $result
openCivilisation
  • 796
  • 1
  • 8
  • 25
0

For a file like test.yml:

---
test: !vault |
     $ANSIBLE_VAULT;1.1;AES256
     37366638363362303836383335623066343562666662386233306537333232396637346463376430
     3664323265333036663736383837326263376637616466610a383430623562633235616531303861
     66313432303063343230613665323930386138613334303839626131373033656463303736366166
     6635346135636437360a313031376566303238303835353364313434363163343066363932346165
     6136

the following crude implementation (recomended only for some quick manual action obviously):

for row in $(cat test.yml | yq -c '.[]'); do
    decrypt() {
     printf "decrypting '%s'" $row | sed -e 's/^"//' -e 's/"$//'
     echo "---"
     printf $row | sed -e 's/^"//' -e 's/"$//' | ansible-vault decrypt -
    }
   echo -e "==\n: $(decrypt '.')"
done

should work, provided that you have the key that encrypted the data.

Stanislav
  • 2,629
  • 1
  • 29
  • 38
0

Coming across this question and the answers here, I'd just like to add a quick bash script i cooked together that reads through an entire yaml file hunting for strings that can be decrypted dumping to screen.

It's far from perfect and I'm not the hottest at bash but, hope this helps someone who was in the same situation as me wanting to do a general dump.

To use the following script, it is necessary to have your vault password in a file (current working path) called vault_pass, along with yq and jq installed. The file to be parsed should be first argument. e.g. ./vault_reader.sh group_vars/production.yml

#!/bin/bash
KEY_OR_VALUE=key
for row in $(yq read -j $1 | jq); do  
    if [ "$KEY_OR_VALUE" == "key" ]
    then
        KEY_OR_VALUE="value"
        echo $(sed -e "s/\"//g" -e "s/\://g" <<<$row)
    else
        KEY_OR_VALUE="key"
        ENC_VALUE=$(sed -e "s/\"//g" -e "s/\://g" -e"s/\,//g"<<<$row)
        if [[ $ENC_VALUE = '$ANSIBLE_VAULT'* ]]; then
            echo -e "$ENC_VALUE" | ansible-vault decrypt --vault-password-file vault_pass
        fi
        echo ""
    fi
done
Simon
  • 816
  • 2
  • 7
  • 16
0

Insane but elegant shell script to output a clean yaml file with decrypted inline vars (assumes that you have ANSIBLE_VAULT_PASSWORD_FILE set and yq v4 installed):

VARS_FILE=path/to/your/vars_file_with_encrypted_vars.yml
yq -P e "$(for v in $(grep '\!vault' $VARS_FILE | cut -d: -f1); do val=$(yq e .${v} $VARS_FILE | tr -d ' ' | ansible-vault decrypt); echo .$v = \"$val\" \|; done) null = null" $VARS_FILE
Shane
  • 4,179
  • 1
  • 28
  • 26
0

One more solution using AnsibleVaultLib:

pip install ansible-vault==2.1.0

from ansible_vault.parsing import AnsibleVaultLib


password = 'my_best_pass'
vault = AnsibleVaultLib(password.encode())
test_var = vault.encrypt('test')

print(f'decoded: {test_var.decode()}')
print(f'encoded: {vault.decrypt(test_var).decode()}')

Output:

decoded: $ANSIBLE_VAULT;1.1;AES256
36653462643432376538383166343333613736373363376331656532326237353664373933616565
3435366262393165393536396431316439383036326364640a366633303130613763393630303837
36376564336565656665633935653734616365626165343332393066396662363937383934323736
3037613133356339330a656333396333656365383237633232396461356431653664356463623731
3633

encoded: test
Danila Ganchar
  • 10,266
  • 13
  • 49
  • 75
0

This is a decent one-liner using yq, if you have a file you need to read a variable from:

cat file_with_passwords.yml | yq -r ".var_name" | ansible-vault decrypt --vault-password-file ...

dessalines
  • 6,352
  • 5
  • 42
  • 59