HashiCorp Vault — Production Exercises
Practice production operations with these exercises.
Exercise 1 — Raft Snapshot and Restore
Task: Backup and restore Vault data using Raft snapshots.
- Store some test secrets in KV
- Take a Raft snapshot
- Add more secrets
- Restore the snapshot
- Verify only the original secrets exist
Show Answer
# Store initial secrets
vault kv put secret/app1 key=original-value-1
vault kv put secret/app2 key=original-value-2
# Take a snapshot
vault operator raft snapshot save test-backup.snap
ls -lh test-backup.snap
# Add more secrets AFTER the snapshot
vault kv put secret/app3 key=post-snapshot-value
# Verify app3 exists
vault kv get secret/app3 # ✅ exists
# Restore the snapshot
vault operator raft snapshot restore -force test-backup.snap
# Verify: app1 and app2 should exist, app3 should not
vault kv get secret/app1 # ✅ exists
vault kv get secret/app2 # ✅ exists
vault kv get secret/app3 # ❌ gone (restored to pre-snapshot state)
Exercise 2 — Root Token Generation
Task: Practice the emergency root token generation workflow.
Show Answer
# In dev mode, you already have a root token
# In production, simulate the generation process:
# Initialize
INIT_OUTPUT=$(vault operator generate-root -init -format=json)
NONCE=$(echo "$INIT_OUTPUT" | jq -r '.nonce')
OTP=$(echo "$INIT_OUTPUT" | jq -r '.otp')
echo "Nonce: $NONCE"
echo "OTP: $OTP"
# Provide unseal key(s) — in dev mode there's only one
# vault operator generate-root -nonce=$NONCE
# Enter unseal key when prompted
# After threshold is met:
# ENCODED_TOKEN is returned
# vault operator generate-root -decode=$ENCODED_TOKEN -otp=$OTP
# Returns the root token
# IMPORTANT: Use it for the emergency task, then revoke it
# vault token revoke $ROOT_TOKEN
Key points:
- Requires coordination among unseal key holders
- The OTP is single-use
- Always revoke the root token after emergency use
Exercise 3 — Hardening Audit
Task: Audit your dev Vault for hardening gaps and fix them.
- Check if audit logging is enabled
- Check which auth methods are enabled
- Disable any unnecessary auth methods
- Enable an audit device
- Verify audit logs are being written
Show Answer
# Check audit devices
vault audit list
# Likely empty in dev mode
# Check auth methods
vault auth list
# Look for anything unnecessary
# Enable file audit
vault audit enable file file_path=/tmp/vault-audit.log
# Verify it's enabled
vault audit list
# Perform an action (generates audit log)
vault kv put secret/test-audit key=value
# Check the audit log
cat /tmp/vault-audit.log | jq '.type'
# Should show "request" and "response" entries
# Disable unused auth methods (example)
# vault auth disable approle/
# Check seal status and config
vault status
Exercise 4 — Lease Management
Task: Create dynamic database credentials and practice lease management.
Show Answer
# Assuming database secrets engine is configured
# (See Chapter 6 for setup)
# Generate credentials
vault read database/creds/readonly
# Note the lease_id
# List active leases
vault list sys/leases/lookup/database/creds/readonly/
# Renew a lease
vault lease renew database/creds/readonly/<lease-id>
# Revoke a specific lease
vault lease revoke database/creds/readonly/<lease-id>
# Generate more credentials
vault read database/creds/readonly
vault read database/creds/readonly
vault read database/creds/readonly
# Revoke ALL leases under this path
vault lease revoke -prefix database/creds/readonly/
# Verify no active leases
vault list sys/leases/lookup/database/creds/readonly/
Exercise 5 — Operational Health Script
Task: Write a health check script that validates your Vault deployment.
Show Answer
#!/bin/bash
# vault-health-check.sh
set -euo pipefail
VAULT_ADDR="${VAULT_ADDR:-http://127.0.0.1:8200}"
ERRORS=0
echo "=== Vault Health Check ==="
echo "Target: $VAULT_ADDR"
echo ""
# 1. Check if Vault is reachable
echo -n "Vault reachable: "
if curl -s "$VAULT_ADDR/v1/sys/health" > /dev/null 2>&1; then
echo "✅"
else
echo "❌ Cannot reach Vault"
ERRORS=$((ERRORS + 1))
fi
# 2. Check seal status
echo -n "Seal status: "
SEALED=$(vault status -format=json 2>/dev/null | jq -r '.sealed')
if [ "$SEALED" = "false" ]; then
echo "✅ Unsealed"
else
echo "❌ SEALED"
ERRORS=$((ERRORS + 1))
fi
# 3. Check HA status
echo -n "HA mode: "
vault status -format=json 2>/dev/null | jq -r '.ha_enabled'
# 4. Check audit devices
echo -n "Audit devices: "
AUDIT_COUNT=$(vault audit list -format=json 2>/dev/null | jq 'length')
if [ "$AUDIT_COUNT" -gt 0 ]; then
echo "✅ $AUDIT_COUNT enabled"
else
echo "⚠️ No audit devices (recommended: at least 2)"
fi
# 5. Check Vault version
echo -n "Version: "
vault status -format=json 2>/dev/null | jq -r '.version'
echo ""
echo "=== Check Complete ($ERRORS errors) ==="
exit $ERRORS
chmod +x vault-health-check.sh
./vault-health-check.sh
What’s Next?
Production operations covered. Now let’s build complete projects that combine everything you’ve learned.
Next Chapter: Practice Projects