Putting Encrypted Secrets in the Repository
Goal
You get hands-on practice with a flow in which secrets are kept inside the repository but not in plaintext, and are decrypted only at run time.
Why it matters
The standard in secrets management is not "is it encrypted?" but "how many exposure paths are there, and how many minutes do revocation and replacement take?" If secrets are in the same repository as the code, you can count them and they go through review, so you can answer those two questions. Conversely, if they are scattered across .env files, chat, and wikis, revocation itself becomes impossible. Pay particular attention to two things in the lab. Keep the password file outside the repository or inside .gitignore, with permission 600, and attach no_log to tasks that handle secrets. Encrypting with effort and then printing the value in plaintext in the execution log is meaningless.
Steps
- Create
/root/ans/vault/.vault_passwith at least 8 bytes and set its permission to600. Add.vault_passto/root/ans/vault/.gitignore. - Copy
/opt/lab/fixtures/ansible/vault-secrets.plain.ymlto/root/ans/vault/vars/secrets.ymland encrypt it. The first line must be the vault header, and no plaintext password may be visible. - Create
/root/ans/vault/vars/inline.ymland put in it the value only of theregistry_tokenkey, encrypted. The value can be any string starting withghp_. The file itself must be plaintext. - In
/root/ans/vault/site.yml, read the encrypted variable to create/root/ans/vault/artifacts/app.env. Its content must includeDB_PASSWORD=labhub-Pr0d-2026, and its permission is600. - Attach
no_logto the tasks that handle secrets, and save the execution log to/root/ans/vault/out/run.txt. The password must not remain in the log. - Create
/root/ans/vault/.vault_pass_newand rekeysecrets.yml. It must open with the new password and must not open with the old one. - Create
/root/ans/vault/.vault_pass_prodand encrypt/root/ans/vault/vars/prod.ymlwith a vault-id labeledprod. The header must be$ANSIBLE_VAULT;1.2;AES256;prod. - Create
/root/ans/vault/out/audit.json. It holds three keys:encrypted_files(at least 3 encrypted file paths),plaintext_leaks(0 entries), andverdict("clean").
Notes
- Lab Pods start fresh for every lab. If
/root/ans/inventory/hosts.iniis missing, first recreate the same inventory you made in the first lab (web1, web2, db1,ansible_host=127.0.0.1,ansible_port=2222,ansible_user=root, with web and db in[prod:children]). For the structure, refer to/opt/lab/fixtures/ansible/inventory.sample.ini. - When you run, add
--vault-password-file /root/ans/vault/.vault_pass. - With
ansible-vault view 파일(the file name goes in the placeholder), you can check only the decrypted result (the file stays as it is). - Common mistake 1: the file does not open because of a newline at the end of the password file. Keep only the password, on a single line, in the file.
- Common mistake 2: not attaching
no_log, so that secrets are printed as they are indebugoutput or module results.
Create the password file and lock it down
Create /root/ans/vault/.vault_pass with at least 8 bytes and set its permission to 600. Add .vault_pass to /root/ans/vault/.gitignore.
Make it at least 8 characters and set the permission to 600. And this file must never be committed.
Encrypt a whole variables file
Copy /opt/lab/fixtures/ansible/vault-secrets.plain.yml to /root/ans/vault/vars/secrets.yml and encrypt it. The first line must be the vault header, and no plaintext password may be visible.
Copy the plaintext file from the fixture and then encrypt it. The first line must change into the vault header.
Encrypt just one value inline
Create /root/ans/vault/vars/inline.yml and put in it the value only of the registry_token key, encrypted. The value can be any string starting with ghp_. The file itself must be plaintext.
Paste the output of encrypt_string into the YAML file. The file itself is plaintext and only the value is ciphertext.
Use the decrypted value in a playbook
In /root/ans/vault/site.yml, read the encrypted variable to create /root/ans/vault/artifacts/app.env. Its content must include DB_PASSWORD=labhub-Pr0d-2026, and its permission is 600.
Read the encrypted file with vars_files and run with --vault-password-file. The permission of the resulting file is 600.
Keep secrets out of the log
Attach no_log to the tasks that handle secrets, and save the execution log to /root/ans/vault/out/run.txt. The password must not remain in the log.
Attach no_log to tasks that handle secrets, and check for yourself that the value is not in the execution log.
Replace the password
Create /root/ans/vault/.vault_pass_new and rekey secrets.yml. It must open with the new password and must not open with the old one.
After a rekey, the old password must not open the file. Create the new password file separately.
Distinguish keys with a vault-id label
Create /root/ans/vault/.vault_pass_prod and encrypt /root/ans/vault/vars/prod.yml with a vault-id labeled prod. The header must be $ANSIBLE_VAULT;1.2;AES256;prod.
The form is --vault-id 라벨@파일 (a label and a file name go in the Korean placeholders). Using a label changes the header version to 1.2 and embeds the label.
Produce a repository secrets audit report
Create /root/ans/vault/out/audit.json. It holds three keys: encrypted_files (at least 3 encrypted file paths), plaintext_leaks (0 entries), and verdict ("clean").
Organize the list of encrypted files and the list of plaintext leaks as JSON. The number of leaks must be 0.