I just had the same want for my personal learning experience (home-lab). What I found was the .git/hooks/pre-commit would help. I have not automated the process, so for your inspiration here are the parts I have.
The .git/hooks/pre-commit is a bash script. The FILE_PATTERN variable determines the files I want to find and warn about are not ansible-vault encrypted. FOr me that would be all yaml files containing variables I don't want to share.
#!/bin/sh
#
# Ansible Vault Secrets Git Hook
#
# Hook to check if an un-encrypted FILE_PATTERN file is being commited. Useful if secrets
# are retained in ansible vault encrypted file(s) that should never be committed to the repository
# un-encrypted. Contact a repository owner for the ansible vault password.
#
# Put this file in .git/hooks/pre-commit
# set -o xtrace
set -o nounset
FILE_PATTERN="my_secrets_file.yaml\|vars/"
ENCRYPTED_PATTERN="\$ANSIBLE_VAULT"
is_encrypted() {
local file=$1
if ! git show :"$file" | grep --quiet "^${ENCRYPTED_PATTERN}"; then
echo "Located a staged file that should be encrypted:\n> ${file}\n"
echo "Please un-stage this file. If you are adding or updating this file, please encrypt it before staging."
echo "Alternatively, you can git checkout the latest encrypted version of the file before committing.\n"
echo "Remember... Only YOU Can Prevent Secret Leakage."
exit 1
fi
}
echo "Running pre-commit checks..."
git diff --cached --name-only | grep "${FILE_PATTERN}" | while IFS= read -r line; do
is_encrypted "${line}"
done
This solves part 1 - i.e. letting me know that I have secrets about to get committed and stopping the misery right there. A simple "git commit" will get this caught.~
The 2nd part is encrypting the necessary files. This is simply a matter of again finding the relevant files and encrypting these. I have made this script to put some convenience into this. The 'files' variable contains the (same) patterns to look for the files.
#!/bin/bash
# If number of arguments is 0
if [ $# -eq 0 ]
then
echo "This script will encrypt of decrypt all files containing secrets."
echo "There are all files in vars as well as all secrets.yaml files under each service."
echo "Specify 'decrypt' or 'encrypt' as argument"
echo "If you put the vault password in a password file named .vault_password, the script will not ask for a password."
exit 1
fi
files=`find . -type f -name "me_secrets_file.yaml"`
files="$files vars/*"
password_type=--ask-vault-password
if [ -f ".vault_password" ]
then
if [ `stat -c %a .vault_password` != "600" ]
then
echo ".vault_password file has bad permissions; fixing this to 600"
chmod 600 .vault_password
fi
password_type="--vault-password-file .vault_password"
fi
if [ $1 == "encrypt" ]
then
ansible-vault encrypt $password_type $files
for value in $files; do
echo $value;
done
elif [ $1 == "decrypt" ]
then
ansible-vault decrypt $password_type $files
for value in $files; do
echo $value;
done
else
echo "Wrong argument supplied. Run without arguments to see allowed ones."
fi
Used as:
./vault.sh {encrypt|decrypt}
This solves part 2 - encryption/decryption of the necessary files.
I am sure these two parts can be combined so that encryption happens as part of the pre-commit hook on any file which is not already encrypted.
Improve by putting -´.vault_password in ~/.vault_password and so on.
The pre-commit script is not originally of my doing, but I did not save the reference.