#!/bin/bash set -e # Initialize Ansible Secrets # This script helps set up the Ansible vault file for the first time SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ANSIBLE_DIR="$(dirname "$SCRIPT_DIR")" SECRETS_DIR="$ANSIBLE_DIR/secrets" # Helper function to generate random passwords generate_password() { local length=${1:-32} openssl rand -base64 "$length" | tr -d "=+/" | cut -c1-"$length" } # Generate base64-encoded 32-byte key for APP_KEY generate_app_key() { openssl rand -base64 32 } echo "🔐 Ansible Secrets Initialization" echo "==================================" echo "" # Check if running from correct directory if [ ! -f "$ANSIBLE_DIR/ansible.cfg" ]; then echo "❌ Error: Must run from deployment/ansible directory" exit 1 fi # Step 1: Create vault password file echo "Step 1: Vault Password" echo "----------------------" if [ -f "$SECRETS_DIR/.vault_pass" ]; then echo "⚠️ Vault password file already exists: $SECRETS_DIR/.vault_pass" read -p "Do you want to replace it? (y/N): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo "Keeping existing vault password file." else rm "$SECRETS_DIR/.vault_pass" read -sp "Enter new vault password: " VAULT_PASS echo read -sp "Confirm vault password: " VAULT_PASS_CONFIRM echo if [ "$VAULT_PASS" != "$VAULT_PASS_CONFIRM" ]; then echo "❌ Passwords don't match!" exit 1 fi echo "$VAULT_PASS" > "$SECRETS_DIR/.vault_pass" chmod 600 "$SECRETS_DIR/.vault_pass" echo "✅ Vault password file created" fi else read -sp "Enter vault password: " VAULT_PASS echo read -sp "Confirm vault password: " VAULT_PASS_CONFIRM echo if [ "$VAULT_PASS" != "$VAULT_PASS_CONFIRM" ]; then echo "❌ Passwords don't match!" exit 1 fi echo "$VAULT_PASS" > "$SECRETS_DIR/.vault_pass" chmod 600 "$SECRETS_DIR/.vault_pass" echo "✅ Vault password file created" fi echo "" # Step 2: Create production vault file echo "Step 2: Production Vault File" echo "-----------------------------" if [ -f "$SECRETS_DIR/production.vault.yml" ]; then echo "⚠️ Production vault file already exists" read -p "Do you want to decrypt and edit it? (y/N): " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then ansible-vault edit "$SECRETS_DIR/production.vault.yml" \ --vault-password-file "$SECRETS_DIR/.vault_pass" echo "✅ Vault file updated" fi else echo "Creating new vault file from example..." cp "$SECRETS_DIR/production.vault.yml.example" "$SECRETS_DIR/production.vault.yml" echo "" echo "Generating secure passwords for all secrets..." # Generate all passwords DB_PASSWORD=$(generate_password 32) DB_ROOT_PASSWORD=$(generate_password 32) REDIS_PASSWORD=$(generate_password 32) APP_KEY=$(generate_app_key) JWT_SECRET=$(generate_password 32) MAIL_PASSWORD=$(generate_password 24) REGISTRY_PASSWORD=$(generate_password 32) ENCRYPTION_KEY=$(generate_password 32) SESSION_SECRET=$(generate_password 32) GRAFANA_PASSWORD=$(generate_password 24) PROMETHEUS_PASSWORD=$(generate_password 24) MINIO_PASSWORD=$(generate_password 32) # Replace all placeholders with generated passwords sed -i "s|change-me-secure-db-password|$DB_PASSWORD|g" "$SECRETS_DIR/production.vault.yml" sed -i "s|change-me-secure-root-password|$DB_ROOT_PASSWORD|g" "$SECRETS_DIR/production.vault.yml" sed -i "s|change-me-secure-redis-password|$REDIS_PASSWORD|g" "$SECRETS_DIR/production.vault.yml" sed -i "s|change-me-base64-encoded-32-byte-key|$APP_KEY|g" "$SECRETS_DIR/production.vault.yml" sed -i "s|change-me-jwt-signing-secret|$JWT_SECRET|g" "$SECRETS_DIR/production.vault.yml" sed -i "s|change-me-mail-password|$MAIL_PASSWORD|g" "$SECRETS_DIR/production.vault.yml" sed -i "s|change-me-registry-password|$REGISTRY_PASSWORD|g" "$SECRETS_DIR/production.vault.yml" sed -i "s|change-me-encryption-key|$ENCRYPTION_KEY|g" "$SECRETS_DIR/production.vault.yml" sed -i "s|change-me-session-secret|$SESSION_SECRET|g" "$SECRETS_DIR/production.vault.yml" sed -i "s|change-me-secure-grafana-password|$GRAFANA_PASSWORD|g" "$SECRETS_DIR/production.vault.yml" sed -i "s|change-me-secure-prometheus-password|$PROMETHEUS_PASSWORD|g" "$SECRETS_DIR/production.vault.yml" sed -i "s|change-me-secure-minio-password|$MINIO_PASSWORD|g" "$SECRETS_DIR/production.vault.yml" # Replace Git Token placeholder with empty string first (will be set to actual token or stay empty) sed -i "s|change-me-gitea-personal-access-token||g" "$SECRETS_DIR/production.vault.yml" echo "✅ All passwords generated and replaced" echo "" # Optional: Ask for Git Token read -p "Do you have a Gitea Personal Access Token? (y/N): " -n 1 -r echo GIT_TOKEN_SET=false if [[ $REPLY =~ ^[Yy]$ ]]; then read -sp "Enter Git Token: " GIT_TOKEN echo # Replace empty value with actual token sed -i "s|vault_git_token: \"\"|vault_git_token: \"$GIT_TOKEN\"|g" "$SECRETS_DIR/production.vault.yml" echo "✅ Git Token set" GIT_TOKEN_SET=true else echo "⚠️ Git Token not set. You can add it later with: ansible-vault edit secrets/production.vault.yml" fi echo "" echo "Encrypting vault file..." ansible-vault encrypt "$SECRETS_DIR/production.vault.yml" \ --vault-password-file "$SECRETS_DIR/.vault_pass" echo "✅ Production vault file created and encrypted" # Save passwords to file (gitignored) for reference PASSWORDS_FILE="$SECRETS_DIR/.vault-passwords.txt" cat > "$PASSWORDS_FILE" <> "$PASSWORDS_FILE" else echo "vault_git_token: (not set)" >> "$PASSWORDS_FILE" fi chmod 600 "$PASSWORDS_FILE" echo "✅ Passwords saved to $PASSWORDS_FILE (for reference only - DO NOT COMMIT!)" fi echo "" # Step 3: Verify vault file echo "Step 3: Verification" echo "-------------------" echo "Testing vault decryption..." if ansible-vault view "$SECRETS_DIR/production.vault.yml" \ --vault-password-file "$SECRETS_DIR/.vault_pass" > /dev/null 2>&1; then echo "✅ Vault file can be decrypted successfully" else echo "❌ Failed to decrypt vault file!" exit 1 fi # Check for example values echo "Checking for unchanged example values..." EXAMPLE_VALUES=$(ansible-vault view "$SECRETS_DIR/production.vault.yml" \ --vault-password-file "$SECRETS_DIR/.vault_pass" | grep -c "change-me" || true) if [ "$EXAMPLE_VALUES" -gt 0 ]; then echo "⚠️ WARNING: Found $EXAMPLE_VALUES 'change-me' placeholder values!" echo " These should have been replaced automatically." echo " You may need to run the script again or edit manually." echo "" read -p "Do you want to edit the vault file now? (y/N): " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then ansible-vault edit "$SECRETS_DIR/production.vault.yml" \ --vault-password-file "$SECRETS_DIR/.vault_pass" fi else echo "✅ No placeholder values found - all secrets are set" fi echo "" # Step 4: Setup SSH key echo "Step 4: SSH Key Setup" echo "--------------------" SSH_KEY="$HOME/.ssh/production" if [ -f "$SSH_KEY" ]; then echo "✅ SSH key already exists: $SSH_KEY" else echo "SSH key not found. Creating new key..." ssh-keygen -t ed25519 -f "$SSH_KEY" -C "ansible-deploy" -N "" chmod 600 "$SSH_KEY" chmod 644 "$SSH_KEY.pub" echo "✅ SSH key created" echo "" echo "📋 Public key:" cat "$SSH_KEY.pub" echo "" echo "⚠️ You must add this public key to the production server:" echo " ssh-copy-id -i $SSH_KEY.pub deploy@94.16.110.151" echo "" read -p "Press ENTER to continue..." fi echo "" # Step 5: Test connection echo "Step 5: Connection Test" echo "----------------------" read -p "Do you want to test the connection to production? (y/N): " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then echo "Testing Ansible connection..." if ansible production -m ping 2>&1 | grep -q "SUCCESS"; then echo "✅ Connection successful!" else echo "❌ Connection failed!" echo "" echo "Troubleshooting steps:" echo "1. Verify SSH key is added to server: ssh-copy-id -i $SSH_KEY.pub deploy@94.16.110.151" echo "2. Test SSH manually: ssh -i $SSH_KEY deploy@94.16.110.151" echo "3. Check inventory file: cat $ANSIBLE_DIR/inventory/production.yml" fi fi echo "" echo "✅ Setup complete!" echo "" echo "Next steps:" echo "1. Review vault file: ansible-vault view secrets/production.vault.yml --vault-password-file secrets/.vault_pass" echo "2. Deploy secrets: ansible-playbook playbooks/setup-production-secrets.yml --vault-password-file secrets/.vault_pass" echo "3. Deploy application: See README.md for deployment instructions" echo "" echo "📖 For more information, see: deployment/ansible/README.md"