3

I am using the following structure to separate my host_vars into plaintext and encrypted

ansible
├── ansible.cfg
├── host_vars
│   ├── host1
│   │   ├── vars
│   │   └── vault
│   └── host2
│       ├── vars
│       └── vault
├── inventory
├── site.yaml
└── vars
    └── ansible_vars.yaml

Is there a way, using ansible-vault to encrypt both files named vault or do I have to do them one by one?

Just asking since there are more to come, e.g. in future directories of group_vars etc.

I know this works

ansible-vault encrypt host_vars/host1/vault host_vars/host2/vault

just asking whether there is a more elegant / quick solution

pkaramol
  • 16,451
  • 43
  • 149
  • 324

2 Answers2

3

There are a lot of possibilities gives by shell expansions.

Here are two that would be interesting in your case:

  • The asterisk * expansion, that is used as a wildcard. Which means that host_vars/*/vault would match both host_vars/host1/vault and host_vars/host2/vault but any other in the future, too.
  • Mind that, if, in the future, you have a more complex folder hierarchy host_vars/*/vault will only match one folder level (e.g. it won't match host_vars/level1/host1/vault), but multiple folder levels can be achieved with a double asterisk (actually named globstar): host_vars/**/vault, will match host_vars/host1/vault as well as host_vars/level1/host1/vault
  • The brace expansion, on the other hands offer a more granular set of possibilities, for examples, if I have hosts names after the distributions like RedHat[1..5], Ubuntu[1..5] and Debian[1..5], I could target only the Debian and RedHat ones via host_vars/{Ubuntu*,RedHat*}/vault.
    Or only target the three first of them both with host_vars/{Ubuntu{1..3},RedHat{1..3}}/vault, or the three first of them all via host_vars/*{1..3}/vault

As a more practical example, if you where to handle SE via Ansible and would like to encrypt the the files for *.stackexchange.com and stackoverflow.com but not superuser.com or any other Q&A having a specific domain name, given that the hosts are named as their DNS name, you could do

ansible-vault host_vars/{stackoverflow.com,*.stackexchange.com}/vault
β.εηοιτ.βε
  • 33,893
  • 13
  • 69
  • 83
  • Thank you for wildcard. Forgot about it. But the issue rises if by some reason Ansible throws the error at specific file. I just tried to rekey bunch of files and it turned out that there where some vault file placeholders which was not encrypted. So the script stops at first error. I tried to `|| true` but with no luck. Anyways, thank you for taking your time to answer. – Dzintars Sep 07 '22 at 19:17
1

I will just throw in my quick super simple shell script which worked for my simple use case. For sure it can be improved but I think it's a good starting point. You could also utilize secret file via --vault-password-file parameter.

#!/bin/sh

echo "Choose the option:"
echo "(d) Decrypt all Ansible vault files"
echo "(e) Encrypt all Ansible vault files"
read option

function decrypt {
  ansible-vault decrypt --ask-vault-pass \
  ansible/*/environments/development/group_vars/*/vault.yaml \
  ansible/*/environments/development/host_vars/*/vault.yaml
}

function encrypt {
  ansible-vault encrypt --ask-vault-pass \
  ansible/*/environments/development/group_vars/*/vault.yaml \
  ansible/*/environments/development/host_vars/*/vault.yaml
}

case $option in
  d)
    decrypt
    ;;
  e)
    encrypt
    break
    ;;
  *)
    echo "Wrong option"
    ;;
esac
Dzintars
  • 1,410
  • 21
  • 29