diff --git a/terraform/Dockerfile b/terraform/Dockerfile
new file mode 100644
index 0000000..09e40bd
--- /dev/null
+++ b/terraform/Dockerfile
@@ -0,0 +1,28 @@
+# Use Python 3.11 slim image
+FROM python:3.11-slim
+
+# Set working directory
+WORKDIR /app
+
+# Copy requirements first for better layer caching
+COPY requirements.txt .
+
+# Install dependencies
+RUN pip install --no-cache-dir -r requirements.txt
+
+# Copy application code
+COPY . .
+
+# Create non-root user (security best practice)
+RUN useradd -m -u 1000 appuser && chown -R appuser:appuser /app
+USER appuser
+
+# Expose port
+EXPOSE 5000
+
+# Health check
+HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
+ CMD curl -f http://localhost:5000/ || exit 1
+
+# Run the application
+CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "2", "--timeout", "120", "app:app"]
\ No newline at end of file
diff --git a/terraform/FIREBASE_AUTH.md b/terraform/FIREBASE_AUTH.md
new file mode 100644
index 0000000..183f8fc
--- /dev/null
+++ b/terraform/FIREBASE_AUTH.md
@@ -0,0 +1,262 @@
+# Firebase Authentication Automation with Terraform
+
+This guide explains how Firebase Authentication settings are automated in the Rothbard Law Group deployment.
+
+## 🚀 What's Automated
+
+### 1. Authentication Providers
+- **Email/Password**: Enabled by default
+- **Google Sign-In**: Optional (controlled by `enable_google_signin` variable)
+- **Phone, Facebook, Apple**: Disabled for security
+
+### 2. Email Templates
+- **Password Reset**: Professional HTML and text templates
+- **Email Verification**: Welcome templates with branding
+- **Customizable**: From address, name, and reply-to settings
+
+### 3. Security Rules
+- **Firestore Rules**: Users can only access their own data
+- **Authentication Required**: All database operations require auth
+- **Profile Access**: Users can read/write their own profile only
+
+### 4. Firebase Hosting
+- **Static Asset Hosting**: Optional for CSS, JS, images
+- **Caching Headers**: Optimized performance
+- **URL Rewrites**: Proper routing for SPA
+
+## 📋 Configuration Variables
+
+Add these to your `terraform.tfvars`:
+
+```hcl
+# Authentication Settings
+enable_google_signin = false # Set to true to enable Google Sign-In
+
+# Email Configuration
+auth_from_email = "noreply@rothbardlaw.com"
+auth_from_name = "Rothbard Law Group"
+auth_reply_to = "support@rothbardlaw.com"
+```
+
+## 🔧 Authentication Provider Setup
+
+### Email/Password (Default)
+```hcl
+sign_in_options {
+ email {
+ enabled = true
+ password_required = true
+ }
+}
+```
+
+### Google Sign-In (Optional)
+To enable Google Sign-In:
+
+1. **Set variable**:
+ ```hcl
+ enable_google_signin = true
+ ```
+
+2. **Configure OAuth in Google Cloud**:
+ ```bash
+ # Enable Google+ API
+ gcloud services enable plus.googleapis.com
+
+ # Create OAuth consent screen
+ gcloud alpha iap oauth-clients create \
+ --display-name="Rothbard Portal" \
+ --brand="Rothbard Law Group"
+ ```
+
+3. **Update Firebase Console**:
+ - Go to Firebase Console → Authentication → Sign-in method
+ - Enable Google provider
+ - Add your OAuth client ID and secret
+
+## 📧 Email Template Customization
+
+### Template Files
+- `templates/reset_password.html` - Password reset HTML
+- `templates/reset_password.txt` - Password reset text
+- `templates/email_verification.html` - Email verification HTML
+- `templates/email_verification.txt` - Email verification text
+
+### Customization Options
+- **Branding**: Update colors, logos in HTML templates
+- **Contact Info**: Change address, phone numbers
+- **Content**: Modify welcome messages and instructions
+
+### Email Variables Available
+- `{{ resetLink }}` - Password reset URL
+- `{{ verificationLink }}` - Email verification URL
+- `{{ userEmail }}` - User's email address
+
+## 🔒 Security Rules Explained
+
+### Firestore Rules
+```javascript
+// Users can only access their own profile
+match /users/{userId} {
+ allow read, write: if request.auth.uid == userId;
+}
+
+// All other collections require authentication
+match /{collection=**} {
+ allow read, write: if request.auth != null;
+}
+```
+
+### Security Features
+- **User Isolation**: Users can't access other users' data
+- **Authentication Required**: No anonymous access
+- **Self-Service**: Users can only modify their own profiles
+
+## 🛠️ Advanced Configuration
+
+### Multi-Factor Authentication
+Currently disabled for simplicity. To enable:
+
+```hcl
+multi_factor_auth {
+ enabled = true
+ provider_configs {
+ phone {
+ enabled = true
+ }
+ }
+}
+```
+
+### Custom Email Templates
+For more advanced templates, you can use Firebase Admin SDK:
+
+```python
+# In your Flask app
+from firebase_admin import auth
+
+def send_custom_email(user_email, template_name):
+ # Custom email sending logic
+ pass
+```
+
+### Domain Restrictions
+To restrict authentication to specific domains:
+
+```javascript
+// In Firebase Auth security rules
+rules_version = '2';
+service cloud.firestore {
+ match /users/{userId} {
+ allow read, write: if
+ request.auth != null &&
+ request.auth.token.email.matches('.*@rothbardlaw\\.com$');
+ }
+}
+```
+
+## 📊 Monitoring and Analytics
+
+### Authentication Events
+Track these events in your application:
+
+```python
+# Log authentication events
+def log_auth_event(event_type, user_id, details=None):
+ db.collection('auth_logs').add({
+ 'event_type': event_type,
+ 'user_id': user_id,
+ 'timestamp': firestore.SERVER_TIMESTAMP,
+ 'details': details or {}
+ })
+```
+
+### Key Events to Monitor
+- User registrations
+- Password resets
+- Failed login attempts
+- Email verifications
+
+## 🔄 Updates and Maintenance
+
+### Updating Email Templates
+1. Edit template files in `terraform/templates/`
+2. Run `terraform apply` to update
+3. Changes apply to new emails immediately
+
+### Adding New Providers
+1. Update `google_identitytoolkit_config` in `main.tf`
+2. Add provider-specific variables
+3. Configure OAuth credentials in Google Cloud
+4. Apply Terraform changes
+
+### Security Rule Updates
+1. Modify `google_firestore_security_policy` in `main.tf`
+2. Test rules in Firebase Console first
+3. Apply with Terraform
+
+## 🚨 Troubleshooting
+
+### Common Issues
+
+1. **Email Templates Not Working**
+ - Check template file paths
+ - Verify template syntax
+ - Check email provider settings
+
+2. **Authentication Provider Not Working**
+ - Verify API credentials
+ - Check provider configuration
+ - Review Firebase Console settings
+
+3. **Security Rules Blocking Access**
+ - Test rules in Firebase Console
+ - Check user authentication status
+ - Verify collection/document paths
+
+### Debug Commands
+
+```bash
+# Check Firebase Auth configuration
+gcloud auth troubleshoot
+
+# Test authentication flow
+curl -X POST "https://identitytoolkit.googleapis.com/v1/accounts:signIn?key=YOUR_API_KEY" \
+ -H "Content-Type: application/json" \
+ -d '{"email":"user@example.com","password":"password","returnSecureToken":true}'
+
+# Check Firestore rules
+gcloud firestore databases rules describe \
+ --project=your-project-id
+```
+
+## 📚 Additional Resources
+
+- [Firebase Authentication Documentation](https://firebase.google.com/docs/auth)
+- [Terraform Google Provider](https://registry.terraform.io/providers/hashicorp/google/latest/docs)
+- [Firestore Security Rules](https://firebase.google.com/docs/firestore/security/get-started)
+- [Firebase Email Templates](https://firebase.google.com/docs/auth/custom-email-templates)
+
+## 🎯 Best Practices
+
+1. **Security First**
+ - Use HTTPS everywhere
+ - Implement proper session management
+ - Regular security audits
+
+2. **User Experience**
+ - Clear error messages
+ - Professional email templates
+ - Mobile-responsive design
+
+3. **Maintenance**
+ - Regular backups
+ - Monitoring and alerts
+ - Documentation updates
+
+4. **Compliance**
+ - GDPR compliance for EU users
+ - Data retention policies
+ - Privacy policy alignment
+
+This automation ensures your Firebase Authentication is secure, professional, and maintainable while following industry best practices for legal client portals.
\ No newline at end of file
diff --git a/terraform/README.md b/terraform/README.md
new file mode 100644
index 0000000..d2cd4f9
--- /dev/null
+++ b/terraform/README.md
@@ -0,0 +1,297 @@
+# Rothbard Law Group - Terraform Deployment
+
+This Terraform configuration deploys the Rothbard Law Group client portal to Google Cloud Platform with Firebase backend.
+
+## Architecture Overview
+
+```
+┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
+│ Firebase App │ │ Firestore │ │ Cloud Run │
+│ (Client Auth) │◄──►│ (User Data) │◄──►│ (Flask App) │
+└─────────────────┘ └─────────────────┘ └─────────────────┘
+ │
+ ▼
+ ┌─────────────────┐
+ │ Filevine API │
+ │ (Case Data) │
+ └─────────────────┘
+```
+
+## Hosting Options
+
+### 1. Cloud Run (Recommended)
+- **Best for production use**
+- Container-based deployment
+- Scales from 0 to N instances
+- Cost-effective (pay-per-use)
+- Full control over environment
+
+### 2. App Engine
+- Platform-as-a-service
+- Built-in scaling
+- Slightly more restrictive
+- Good for simpler deployments
+
+## Prerequisites
+
+1. **Google Cloud SDK**
+ ```bash
+ curl https://sdk.cloud.google.com | bash
+ gcloud init
+ ```
+
+2. **Terraform**
+ ```bash
+ # macOS
+ brew install terraform
+
+ # Linux
+ sudo apt-get install terraform
+ ```
+
+3. **Docker** (for Cloud Run)
+ ```bash
+ # macOS
+ brew install docker
+
+ # Linux
+ sudo apt-get install docker.io
+ ```
+
+## Setup Instructions
+
+### 1. Configure Terraform Variables
+
+Copy the example variables file:
+```bash
+cp terraform.tfvars.example terraform.tfvars
+```
+
+Edit `terraform.tfvars` with your values:
+```hcl
+gcp_project_id = "your-gcp-project-id"
+domain_name = "rothbard.yourdomain.com"
+hosting_option = "cloud_run" # or "app_engine"
+```
+
+### 2. Set Environment Variables
+
+Create a `.env` file for sensitive data:
+```bash
+# Flask Configuration
+FLASK_SECRET_KEY=your-super-secret-key
+
+# Firebase Configuration
+FIREBASE_API_KEY=your-firebase-api-key
+FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
+FIREBASE_PROJECT_ID=your-gcp-project-id
+FIREBASE_APP_ID=your-firebase-app-id
+
+# Service Account (optional - can use gcloud auth)
+FIREBASE_SERVICE_ACCOUNT_JSON='{"type":"service_account",...}'
+
+# Filevine API Configuration
+FILEVINE_CLIENT_ID=your-filevine-client-id
+FILEVINE_CLIENT_SECRET=your-filevine-client-secret
+FILEVINE_PERSONAL_ACCESS_TOKEN=your-filevine-pat
+FILEVINE_ORG_ID=your-filevine-org-id
+FILEVINE_USER_ID=your-filevine-user-id
+```
+
+### 3. Deploy with Cloud Run (Recommended)
+
+#### Step 1: Build and Push Docker Image
+```bash
+# Set your project ID
+export PROJECT_ID=your-gcp-project-id
+
+# Build the Docker image
+docker build -t gcr.io/$PROJECT_ID/rothbard-portal:latest .
+
+# Push to Google Container Registry
+docker push gcr.io/$PROJECT_ID/rothbard-portal:latest
+```
+
+#### Step 2: Deploy Infrastructure
+```bash
+cd terraform
+
+# Initialize Terraform
+terraform init
+
+# Plan the deployment
+terraform plan
+
+# Apply the changes
+terraform apply
+```
+
+#### Step 3: Update Container Image Variable
+After the first deployment, update your `terraform.tfvars`:
+```hcl
+container_image = "gcr.io/your-gcp-project-id/rothbard-portal:latest"
+```
+
+Then run `terraform apply` again.
+
+### 4. Deploy with App Engine
+
+#### Step 1: Create Source Package
+```bash
+# Copy app files and create zip
+cp app.py requirements.txt templates/ app-engine/
+cd app-engine
+zip -r ../app-source.zip .
+cd ..
+```
+
+#### Step 2: Deploy Infrastructure
+```bash
+cd terraform
+
+# Set hosting option to app_engine
+# Edit terraform.tfvars: hosting_option = "app_engine"
+
+# Initialize and apply
+terraform init
+terraform plan
+terraform apply
+```
+
+## Post-Deployment Setup
+
+### 1. Firebase Configuration
+
+After deployment, you'll need to:
+
+1. **Configure Firebase Authentication**:
+ - Go to Firebase Console → Authentication
+ - Enable Email/Password provider
+ - Add your domain to authorized domains
+
+2. **Set up Firestore Rules**:
+ ```javascript
+ rules_version = '2';
+ service cloud.firestore {
+ match /databases/{database}/documents {
+ match /users/{userId} {
+ allow read, write: if request.auth != null && request.auth.uid == userId;
+ }
+ }
+ }
+ ```
+
+### 2. Enable Users
+
+Users need to be manually enabled in Firestore:
+
+```javascript
+// In Firebase Console → Firestore Database
+// Create document in collection 'users' with document ID = Firebase UID
+{
+ enabled: true,
+ caseEmail: "user@example.com", // This filters Filevine projects
+ name: "Client Name"
+}
+```
+
+### 3. Custom Domain (Optional)
+
+For Cloud Run with custom domain:
+
+```bash
+# Map your domain to the Cloud Run service
+gcloud run services add-iam-policy-binding rothbard-portal-service \
+ --member="allUsers" \
+ --role="roles/run.invoker"
+
+# Set up domain mapping
+gcloud run domain-mappings create \
+ --domain=rothbard.yourdomain.com \
+ --service=rothbard-portal-service
+```
+
+## Monitoring and Maintenance
+
+### View Logs
+```bash
+# Cloud Run logs
+gcloud logs read "resource.type=cloud_run_revision" --limit 50
+
+# App Engine logs
+gcloud app logs tail -s default
+```
+
+### Scale Configuration
+
+For Cloud Run, you can adjust scaling in `terraform/modules/cloud_run/main.tf`:
+```hcl
+metadata {
+ annotations = {
+ "autoscaling.knative.dev/maxScale" = "10" # Max instances
+ "autoscaling.knative.dev/minScale" = "1" # Min instances
+ }
+}
+```
+
+### Updates
+
+To update the application:
+
+1. **Cloud Run**: Build and push new Docker image, then update the `container_image` variable
+2. **App Engine**: Update source code, create new zip, and redeploy
+
+## Costs
+
+### Cloud Run (Recommended)
+- **Free tier**: 180,000 vCPU-seconds, 360,000 GiB-seconds memory per month
+- **Beyond free tier**: ~$0.000024 per vCPU-second, $0.0000025 per GiB-second
+- **Typical cost**: $5-20/month for low traffic client portal
+
+### App Engine
+- **Free tier**: 28 instance-hours per day
+- **Beyond free tier**: ~$0.05 per instance-hour
+- **Typical cost**: $10-50/month depending on traffic
+
+### Firebase
+- **Spark plan**: Free for most use cases
+- **Blaze plan**: Pay-as-you-go for high usage
+- **Typical cost**: $0-25/month depending on authentication usage
+
+## Security Considerations
+
+1. **Service Account**: Minimal permissions granted (Firestore and Firebase Admin)
+2. **Secret Management**: Sensitive data stored in Secret Manager
+3. **HTTPS**: All traffic encrypted with TLS
+4. **Authentication**: Firebase ID tokens verified server-side
+5. **Access Control**: User access controlled through Firestore profiles
+
+## Troubleshooting
+
+### Common Issues
+
+1. **Build failures**: Check Dockerfile and requirements.txt
+2. **Permission errors**: Verify service account has correct IAM roles
+3. **Firebase connection**: Ensure service account key is properly formatted
+4. **CORS errors**: Configure Firebase Auth domain correctly
+
+### Debug Commands
+
+```bash
+# Check Cloud Run service status
+gcloud run services describe rothbard-portal-service
+
+# Test service locally
+docker run -p 5000:5000 gcr.io/$PROJECT_ID/rothbard-portal:latest
+
+# Check Terraform state
+terraform show
+```
+
+## Support
+
+For issues with:
+- **Terraform deployment**: Check Terraform logs and state
+- **Cloud Run**: View Cloud Run logs in Google Console
+- **Firebase**: Check Firebase Console for configuration issues
+- **Application**: Review Flask application logs
\ No newline at end of file
diff --git a/terraform/app.yaml b/terraform/app.yaml
new file mode 100644
index 0000000..7cf3513
--- /dev/null
+++ b/terraform/app.yaml
@@ -0,0 +1,29 @@
+# App Engine configuration file
+runtime: python311
+
+instance_class: F1
+automatic_scaling:
+ min_idle_instances: automatic
+ max_idle_instances: 1
+ min_pending_latency: automatic
+ max_pending_latency: automatic
+
+# Environment variables
+env_variables:
+ FLASK_ENV: production
+ PORT: 8080
+
+# Handlers
+handlers:
+- url: /.*
+ script: auto
+ secure: always
+
+# Health check
+health_check:
+ enable_health_check: true
+ check_path: "/"
+
+# Runtime configuration
+runtime_config:
+ python_version: 3
\ No newline at end of file
diff --git a/terraform/deploy.sh b/terraform/deploy.sh
new file mode 100755
index 0000000..3686313
--- /dev/null
+++ b/terraform/deploy.sh
@@ -0,0 +1,229 @@
+#!/bin/bash
+
+# Rothbard Law Group Deployment Script
+# This script automates the deployment process for Cloud Run
+
+set -e
+
+# Colors for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+NC='\033[0m' # No Color
+
+# Configuration
+PROJECT_ID=""
+DOMAIN_NAME=""
+HOSTING_OPTION="cloud_run"
+
+# Helper functions
+log_info() {
+ echo -e "${GREEN}[INFO]${NC} $1"
+}
+
+log_warn() {
+ echo -e "${YELLOW}[WARN]${NC} $1"
+}
+
+log_error() {
+ echo -e "${RED}[ERROR]${NC} $1"
+}
+
+# Check prerequisites
+check_prerequisites() {
+ log_info "Checking prerequisites..."
+
+ # Check gcloud
+ if ! command -v gcloud &> /dev/null; then
+ log_error "gcloud is not installed. Please install Google Cloud SDK."
+ exit 1
+ fi
+
+ # Check terraform
+ if ! command -v terraform &> /dev/null; then
+ log_error "terraform is not installed. Please install Terraform."
+ exit 1
+ fi
+
+ # Check docker (for Cloud Run)
+ if [ "$HOSTING_OPTION" = "cloud_run" ] && ! command -v docker &> /dev/null; then
+ log_error "docker is not installed. Please install Docker for Cloud Run deployment."
+ exit 1
+ fi
+
+ log_info "Prerequisites check passed!"
+}
+
+# Setup project
+setup_project() {
+ log_info "Setting up Google Cloud project..."
+
+ if [ -z "$PROJECT_ID" ]; then
+ read -p "Enter your GCP Project ID: " PROJECT_ID
+ fi
+
+ # Set the project
+ gcloud config set project "$PROJECT_ID"
+
+ # Enable required APIs
+ log_info "Enabling required APIs..."
+ gcloud services enable run.googleapis.com
+ gcloud services enable cloudbuild.googleapis.com
+ gcloud services enable firestore.googleapis.com
+ gcloud services enable firebase.googleapis.com
+ gcloud services enable secretmanager.googleapis.com
+
+ log_info "Project setup completed!"
+}
+
+# Build and push Docker image (Cloud Run)
+build_and_push_image() {
+ if [ "$HOSTING_OPTION" != "cloud_run" ]; then
+ return
+ fi
+
+ log_info "Building Docker image..."
+
+ # Build the image
+ docker build -t gcr.io/$PROJECT_ID/rothbard-portal:latest .
+
+ log_info "Pushing Docker image to Google Container Registry..."
+
+ # Configure Docker to use gcloud as a credential helper
+ gcloud auth configure-docker
+
+ # Push the image
+ docker push gcr.io/$PROJECT_ID/rothbard-portal:latest
+
+ log_info "Docker image pushed successfully!"
+}
+
+# Deploy infrastructure with Terraform
+deploy_infrastructure() {
+ log_info "Deploying infrastructure with Terraform..."
+
+ cd terraform
+
+ # Create terraform.tfvars if it doesn't exist
+ if [ ! -f "terraform.tfvars" ]; then
+ log_warn "terraform.tfvars not found. Creating from example..."
+ cp terraform.tfvars.example terraform.tfvars
+
+ # Update with project ID
+ sed -i "s/your-gcp-project-id/$PROJECT_ID/g" terraform.tfvars
+
+ if [ -n "$DOMAIN_NAME" ]; then
+ sed -i "s/rothbard-portal.example.com/$DOMAIN_NAME/g" terraform.tfvars
+ fi
+
+ log_warn "Please edit terraform/terraform.tfvars with your specific configuration before continuing."
+ read -p "Press Enter to continue after editing..."
+ fi
+
+ # Initialize Terraform
+ terraform init
+
+ # Plan deployment
+ log_info "Planning Terraform deployment..."
+ terraform plan
+
+ # Apply deployment
+ log_info "Applying Terraform configuration..."
+ terraform apply -auto-approve
+
+ # Get the output URL
+ APP_URL=$(terraform output -raw application_url)
+
+ cd ..
+
+ log_info "Infrastructure deployed successfully!"
+ log_info "Application URL: $APP_URL"
+}
+
+# Create service account key for local development
+create_service_account_key() {
+ log_info "Creating service account key for development..."
+
+ SA_NAME="rothbard-flask-app"
+ SA_EMAIL="$SA_NAME@$PROJECT_ID.iam.gserviceaccount.com"
+
+ # Create service account if it doesn't exist
+ if ! gcloud iam service-accounts describe "$SA_EMAIL" &> /dev/null; then
+ gcloud iam service-accounts create "$SA_NAME" \
+ --display-name="Rothbard Flask App Service Account"
+ fi
+
+ # Grant necessary roles
+ gcloud projects add-iam-policy-binding "$PROJECT_ID" \
+ --member="serviceAccount:$SA_EMAIL" \
+ --role="roles/datastore.user"
+
+ gcloud projects add-iam-policy-binding "$PROJECT_ID" \
+ --member="serviceAccount:$SA_EMAIL" \
+ --role="roles/firebase.admin"
+
+ # Create key
+ gcloud iam service-accounts keys create ~/rothbard-service-account.json \
+ --iam-account="$SA_EMAIL"
+
+ log_info "Service account key created at ~/rothbard-service-account.json"
+ log_warn "Add this to your environment: export GOOGLE_APPLICATION_CREDENTIALS=~/rothbard-service-account.json"
+}
+
+# Main deployment function
+main() {
+ log_info "Starting Rothbard Law Group deployment..."
+
+ # Parse command line arguments
+ while [[ $# -gt 0 ]]; do
+ case $1 in
+ -p|--project)
+ PROJECT_ID="$2"
+ shift 2
+ ;;
+ -d|--domain)
+ DOMAIN_NAME="$2"
+ shift 2
+ ;;
+ -o|--option)
+ HOSTING_OPTION="$2"
+ shift 2
+ ;;
+ -h|--help)
+ echo "Usage: $0 [OPTIONS]"
+ echo "Options:"
+ echo " -p, --project PROJECT_ID GCP Project ID"
+ echo " -d, --domain DOMAIN_NAME Domain name (optional)"
+ echo " -o, --option HOSTING_OPTION Hosting option (cloud_run or app_engine)"
+ echo " -h, --help Show this help message"
+ exit 0
+ ;;
+ *)
+ log_error "Unknown option: $1"
+ exit 1
+ ;;
+ esac
+ done
+
+ # Validate hosting option
+ if [[ ! "$HOSTING_OPTION" =~ ^(cloud_run|app_engine)$ ]]; then
+ log_error "Invalid hosting option. Use 'cloud_run' or 'app_engine'."
+ exit 1
+ fi
+
+ check_prerequisites
+ setup_project
+ build_and_push_image
+ deploy_infrastructure
+ create_service_account_key
+
+ log_info "Deployment completed successfully!"
+ log_info "Next steps:"
+ log_info "1. Configure Firebase Authentication in the Firebase Console"
+ log_info "2. Set up Firestore security rules"
+ log_info "3. Enable user accounts in Firestore"
+ log_info "4. Configure your custom domain (if applicable)"
+}
+
+# Run main function
+main "$@"
\ No newline at end of file
diff --git a/terraform/deployment.tf b/terraform/deployment.tf
new file mode 100644
index 0000000..67123ba
--- /dev/null
+++ b/terraform/deployment.tf
@@ -0,0 +1,99 @@
+variable "hosting_option" {
+ description = "Hosting option for the Flask app"
+ type = string
+ default = "cloud_run"
+ validation {
+ condition = contains(["cloud_run", "app_engine"], var.hosting_option)
+ error_message = "The hosting_option must be one of: cloud_run, app_engine."
+ }
+}
+
+# Select hosting option based on variable
+module "hosting" {
+ source = "./modules/${var.hosting_option}"
+
+ # Common variables
+ app_name = "rothbard-portal"
+ gcp_project_id = var.gcp_project_id
+ gcp_region = var.gcp_region
+ firebase_project_id = google_firebase_project.default.project
+ flask_secret_key = var.flask_secret_key
+ service_account_email = google_service_account.flask_app.email
+ service_account_key_data = var.service_account_key_data
+
+ # Filevine credentials
+ filevine_client_id = var.filevine_client_id
+ filevine_client_secret = var.filevine_client_secret
+ filevine_pat = var.filevine_pat
+ filevine_org_id = var.filevine_org_id
+ filevine_user_id = var.filevine_user_id
+
+ # Module-specific variables
+ container_image = var.hosting_option == "cloud_run" ? var.container_image : null
+ app_source_zip_path = var.hosting_option == "app_engine" ? var.app_source_zip_path : null
+}
+
+# Additional variables for hosting options
+variable "flask_secret_key" {
+ description = "Flask secret key"
+ type = string
+ sensitive = true
+}
+
+variable "service_account_key_data" {
+ description = "Service account key JSON data"
+ type = string
+ sensitive = true
+}
+
+variable "container_image" {
+ description = "Docker image for Cloud Run deployment"
+ type = string
+ default = "gcr.io/your-project/rothbard-portal:latest"
+}
+
+variable "app_source_zip_path" {
+ description = "Path to App Engine source zip"
+ type = string
+ default = "./app-source.zip"
+}
+
+
+# Filevine credentials
+variable "filevine_client_id" {
+ description = "Filevine client ID"
+ type = string
+ sensitive = true
+}
+
+variable "filevine_client_secret" {
+ description = "Filevine client secret"
+ type = string
+ sensitive = true
+}
+
+variable "filevine_pat" {
+ description = "Filevine personal access token"
+ type = string
+ sensitive = true
+}
+
+variable "filevine_org_id" {
+ description = "Filevine organization ID"
+ type = string
+ sensitive = true
+}
+
+variable "filevine_user_id" {
+ description = "Filevine user ID"
+ type = string
+ sensitive = true
+}
+
+# Output hosting-specific URLs
+output "application_url" {
+ description = "URL of the deployed application"
+ value = var.hosting_option == "cloud_run" ? module.hosting.service_url :
+ var.hosting_option == "app_engine" ? module.hosting.app_url :
+ null
+}
\ No newline at end of file
diff --git a/terraform/main.tf b/terraform/main.tf
new file mode 100644
index 0000000..610eca4
--- /dev/null
+++ b/terraform/main.tf
@@ -0,0 +1,241 @@
+terraform {
+ required_providers {
+ google = {
+ source = "hashicorp/google"
+ version = "~> 5.0"
+ }
+ firebase = {
+ source = "terraform-google-modules/firebase/google"
+ version = "~> 13.0"
+ }
+ }
+
+ required_version = ">= 1.0"
+}
+
+provider "google" {
+ project = var.gcp_project_id
+ region = var.gcp_region
+}
+
+provider "firebase" {
+ project = var.gcp_project_id
+}
+
+# Firebase Project Setup
+resource "google_firebase_project" "default" {
+ provider = google-beta
+ project = var.gcp_project_id
+}
+
+# Firebase Web App
+resource "google_firebase_web_app" "rothbard_portal" {
+ provider = google-beta
+ project = google_firebase_project.default.project
+ display_name = "Rothbard Client Portal"
+
+ app_url = "https://${var.domain_name}"
+
+ # Handle OAuth redirect
+ oauth_config {
+ client_id = var.oauth_client_id
+ client_secret = var.oauth_client_secret
+ }
+}
+
+# Firestore Database
+resource "google_firestore_database" "default" {
+ provider = google-beta
+ project = var.gcp_project_id
+ name = "(default)"
+ location_id = var.firestore_location
+ type = "FIRESTORE_NATIVE"
+
+ delete_protection_state = "DISABLED"
+}
+
+# Firebase Authentication - Complete Configuration
+resource "google_identitytoolkit_config" "default" {
+ provider = google-beta
+ project = var.gcp_project_id
+
+ sign_in_options {
+ email {
+ enabled = true
+ password_required = true
+ }
+
+ # Disable other providers for security
+ phone {
+ enabled = false
+ }
+
+ google {
+ enabled = var.enable_google_signin
+ }
+
+ facebook {
+ enabled = false
+ }
+
+ apple {
+ enabled = false
+ }
+ }
+
+ # Email configuration
+ email {
+ reset_password_template {
+ from_email_address = var.auth_from_email
+ from_display_name = var.auth_from_name
+ reply_to = var.auth_reply_to
+ subject = "Reset your Rothbard Law Group password"
+ html = file("${path.module}/templates/reset_password.html")
+ text = file("${path.module}/templates/reset_password.txt")
+ }
+
+ email_verification_template {
+ from_email_address = var.auth_from_email
+ from_display_name = var.auth_from_name
+ reply_to = var.auth_reply_to
+ subject = "Verify your Rothbard Law Group account"
+ html = file("${path.module}/templates/email_verification.html")
+ text = file("${path.module}/templates/email_verification.txt")
+ }
+ }
+
+ # Security settings
+ sign_in {
+ allow_duplicate_emails = false
+ }
+
+ # Multi-factor authentication (disabled for simplicity)
+ multi_factor_auth {
+ enabled = false
+ }
+
+ # Anonymous user access (disabled)
+ anonymous {
+ enabled = false
+ }
+}
+
+# Service Account for the Flask App
+resource "google_service_account" "flask_app" {
+ account_id = "rothbard-flask-app"
+ display_name = "Rothbard Flask App Service Account"
+}
+
+# IAM permissions for the Flask App
+resource "google_project_iam_member" "firestore_access" {
+ project = var.gcp_project_id
+ role = "roles/datastore.user"
+ member = "serviceAccount:${google_service_account.flask_app.email}"
+}
+
+resource "google_project_iam_member" "firebase_admin" {
+ project = var.gcp_project_id
+ role = "roles/firebase.admin"
+ member = "serviceAccount:${google_service_account.flask_app.email}"
+}
+
+# Firestore Security Rules
+resource "google_firestore_security_policy" "default" {
+ project = var.gcp_project_id
+ policy = {
+ rules = [
+ {
+ description = "Allow users to read/write their own profile"
+ match = {
+ collection = "users"
+ document = "{userId}"
+ }
+ allow = [
+ {
+ resource = "read"
+ condition = {
+ name = "request.auth.uid == userId"
+ }
+ },
+ {
+ resource = "write"
+ condition = {
+ name = "request.auth.uid == userId"
+ }
+ }
+ ]
+ },
+ {
+ description = "Only authenticated users can access the database"
+ match = {
+ collection = "{collection=**}"
+ }
+ allow = [
+ {
+ resource = "read"
+ condition = {
+ name = "request.auth != null"
+ }
+ },
+ {
+ resource = "write"
+ condition = {
+ name = "request.auth != null"
+ }
+ }
+ ]
+ }
+ ]
+ }
+}
+
+# Firebase Hosting (optional - for static assets)
+resource "google_firebase_hosting_site" "default" {
+ provider = google-beta
+ project = var.gcp_project_id
+ site_id = "rothbard-portal"
+
+ # Default configuration for hosting
+ config {
+ public_root_dir = "public"
+ headers = [
+ {
+ headers = ["Cache-Control: public, max-age=31536000"]
+ glob = "**/*.@(jpg|jpeg|gif|png|svg|webp)"
+ },
+ {
+ headers = ["Cache-Control: public, max-age=86400"]
+ glob = "**/*.@(css|js)"
+ }
+ ]
+ redirects = [
+ {
+ status_code = 302
+ path = "/login"
+ location = "/login.html"
+ }
+ ]
+ rewrites = [
+ {
+ glob = "**"
+ path = "/index.html"
+ }
+ ]
+ }
+}
+
+# Output important values
+output "firebase_web_app_id" {
+ description = "Firebase Web App ID"
+ value = google_firebase_web_app.rothbard_portal.app_id
+}
+
+output "firebase_project_id" {
+ description = "Firebase Project ID"
+ value = google_firebase_project.default.project
+}
+
+output "service_account_email" {
+ description = "Service account email for Flask app"
+ value = google_service_account.flask_app.email
+}
\ No newline at end of file
diff --git a/terraform/modules/app_engine/main.tf b/terraform/modules/app_engine/main.tf
new file mode 100644
index 0000000..a86a907
--- /dev/null
+++ b/terraform/modules/app_engine/main.tf
@@ -0,0 +1,118 @@
+# Enable App Engine Admin API
+resource "google_project_service" "appengine" {
+ project = var.gcp_project_id
+ service = "appengine.googleapis.com"
+}
+
+# App Engine Application
+resource "google_app_engine_application" "app" {
+ project = var.gcp_project_id
+ location_id = var.gcp_region
+ depends_on = [google_project_service.appengine]
+}
+
+# App Engine Service for Flask app
+resource "google_app_engine_standard_app_version" "flask_app" {
+ project = var.gcp_project_id
+ service = "default"
+ version_id = "${var.app_name}-v1"
+
+ runtime = "python311"
+
+ entrypoint {
+ command = "gunicorn -b :$PORT app:app"
+ }
+
+ deployment {
+ zip {
+ source_url = google_storage_bucket_object.app_source_zip.output_uri
+ }
+ }
+
+ env_variables = {
+ FLASK_SECRET_KEY = var.flask_secret_key
+ FIREBASE_PROJECT_ID = var.firebase_project_id
+ GOOGLE_APPLICATION_CREDENTIALS = "/etc/secrets/service-account.json"
+ FILEVINE_CLIENT_ID = var.filevine_client_id
+ FILEVINE_CLIENT_SECRET = var.filevine_client_secret
+ FILEVINE_PERSONAL_ACCESS_TOKEN = var.filevine_pat
+ FILEVINE_ORG_ID = var.filevine_org_id
+ FILEVINE_USER_ID = var.filevine_user_id
+ }
+
+ # Service account
+ service_account = var.service_account_email
+
+ # Resources
+ resources {
+ cpu = 1
+ memory_gb = 0.5
+ disk_gb = 0.5
+ }
+
+ # Automatic scaling
+ automatic_scaling {
+ min_idle_instances = 0
+ max_idle_instances = 1
+ min_pending_latency = "automatic"
+ max_pending_latency = "automatic"
+ max_concurrent_requests = 80
+ }
+
+ # Health check
+ health_check {
+ enable_health_check = true
+ check_path = "/"
+ }
+
+ depends_on = [
+ google_storage_bucket_object.app_source_zip,
+ google_secret_manager_secret_version.service_account_key
+ ]
+}
+
+# Make App Engine service publicly accessible
+resource "google_app_engine_firewall_rule" "allow_all" {
+ project = var.gcp_project_id
+ action = "ALLOW"
+ priority = "1"
+
+ source_range = "*"
+}
+
+# Cloud Storage bucket for app source code
+resource "google_storage_bucket" "app_source" {
+ name = "${var.app_name}-source-${var.gcp_project_id}"
+ location = var.gcp_region
+ force_destroy = true
+
+ uniform_bucket_level_access = true
+}
+
+# Upload app source code
+resource "google_storage_bucket_object" "app_source_zip" {
+ name = "app-source.zip"
+ bucket = google_storage_bucket.app_source.name
+ source = var.app_source_zip_path
+}
+
+# Store service account key in Secret Manager
+resource "google_secret_manager_secret" "service_account_key" {
+ project = var.gcp_project_id
+ secret_id = "${var.app_name}-service-account-key"
+
+ replication {
+ automatic = true
+ }
+}
+
+resource "google_secret_manager_secret_version" "service_account_key" {
+ secret = google_secret_manager_secret.service_account_key.id
+ secret_data = var.service_account_key_data
+}
+
+# Output the app URL
+output "app_url" {
+ description = "App Engine application URL"
+ value = "https://${google_app_engine_application.app.default_hostname}"
+}
\ No newline at end of file
diff --git a/terraform/modules/app_engine/variables.tf b/terraform/modules/app_engine/variables.tf
new file mode 100644
index 0000000..9c758de
--- /dev/null
+++ b/terraform/modules/app_engine/variables.tf
@@ -0,0 +1,71 @@
+variable "app_name" {
+ description = "Name of the application"
+ type = string
+}
+
+variable "gcp_project_id" {
+ description = "GCP Project ID"
+ type = string
+}
+
+variable "gcp_region" {
+ description = "GCP region"
+ type = string
+}
+
+variable "app_source_zip_path" {
+ description = "Path to the app source code zip file"
+ type = string
+}
+
+variable "firebase_project_id" {
+ description = "Firebase project ID"
+ type = string
+}
+
+variable "flask_secret_key" {
+ description = "Flask secret key"
+ type = string
+ sensitive = true
+}
+
+variable "service_account_email" {
+ description = "Service account email for the App Engine service"
+ type = string
+}
+
+variable "service_account_key_data" {
+ description = "Service account key JSON data"
+ type = string
+ sensitive = true
+}
+
+variable "filevine_client_id" {
+ description = "Filevine client ID"
+ type = string
+ sensitive = true
+}
+
+variable "filevine_client_secret" {
+ description = "Filevine client secret"
+ type = string
+ sensitive = true
+}
+
+variable "filevine_pat" {
+ description = "Filevine personal access token"
+ type = string
+ sensitive = true
+}
+
+variable "filevine_org_id" {
+ description = "Filevine organization ID"
+ type = string
+ sensitive = true
+}
+
+variable "filevine_user_id" {
+ description = "Filevine user ID"
+ type = string
+ sensitive = true
+}
\ No newline at end of file
diff --git a/terraform/modules/cloud_run/main.tf b/terraform/modules/cloud_run/main.tf
new file mode 100644
index 0000000..0cefd56
--- /dev/null
+++ b/terraform/modules/cloud_run/main.tf
@@ -0,0 +1,144 @@
+# Cloud Run Service for Flask App
+resource "google_cloud_run_service" "flask_app" {
+ name = "${var.app_name}-service"
+ location = var.gcp_region
+
+ template {
+ spec {
+ containers {
+ image = var.container_image
+
+ # Environment variables for the Flask app
+ env {
+ name = "FLASK_SECRET_KEY"
+ value = var.flask_secret_key
+ }
+
+ env {
+ name = "FIREBASE_PROJECT_ID"
+ value = var.firebase_project_id
+ }
+
+ env {
+ name = "GOOGLE_APPLICATION_CREDENTIALS"
+ value = "/etc/secrets/service-account.json"
+ }
+
+ # Filevine API credentials
+ env {
+ name = "FILEVINE_CLIENT_ID"
+ value = var.filevine_client_id
+ }
+
+ env {
+ name = "FILEVINE_CLIENT_SECRET"
+ value = var.filevine_client_secret
+ }
+
+ env {
+ name = "FILEVINE_PERSONAL_ACCESS_TOKEN"
+ value = var.filevine_pat
+ }
+
+ env {
+ name = "FILEVINE_ORG_ID"
+ value = var.filevine_org_id
+ }
+
+ env {
+ name = "FILEVINE_USER_ID"
+ value = var.filevine_user_id
+ }
+
+ # Memory and CPU limits
+ resources {
+ limits = {
+ cpu = "1000m"
+ memory = "512Mi"
+ }
+ }
+
+ # Mount service account key
+ volume_mount {
+ name = "service-account-key"
+ mount_path = "/etc/secrets"
+ read_only = true
+ }
+ }
+
+ # Service account for the container
+ service_account_name = var.service_account_email
+
+ # Volumes
+ volumes {
+ name = "service-account-key"
+ secret {
+ secret_name = google_secret_manager_secret.service_account_key.secret_id
+ items {
+ key = "latest"
+ path = "service-account.json"
+ }
+ }
+ }
+
+ # Allow unauthenticated access
+ container_concurrency = 100
+ timeout_seconds = 300
+ }
+
+ # Traffic settings
+ metadata {
+ annotations = {
+ "autoscaling.knative.dev/maxScale" = "10"
+ "autoscaling.knative.dev/minScale" = "1"
+ "run.googleapis.com/ingress" = "all"
+ }
+ }
+ }
+
+ traffic {
+ percent = 100
+ latest_revision = true
+ }
+
+ depends_on = [google_secret_manager_secret_version.service_account_key]
+}
+
+# Make Cloud Run service publicly accessible
+resource "google_cloud_run_service_iam_member" "public" {
+ location = google_cloud_run_service.flask_app.location
+ project = google_cloud_run_service.flask_app.project
+ service = google_cloud_run_service.flask_app.name
+ role = "roles/run.invoker"
+ member = "allUsers"
+}
+
+# Store service account key in Secret Manager
+resource "google_secret_manager_secret" "service_account_key" {
+ project = var.gcp_project_id
+ secret_id = "${var.app_name}-service-account-key"
+
+ replication {
+ automatic = true
+ }
+}
+
+resource "google_secret_manager_secret_version" "service_account_key" {
+ secret = google_secret_manager_secret.service_account_key.id
+ secret_data = var.service_account_key_data
+}
+
+# Cloud Storage bucket for container storage (if needed)
+resource "google_storage_bucket" "app_storage" {
+ name = "${var.app_name}-storage-${var.gcp_project_id}"
+ location = var.gcp_region
+ force_destroy = true
+
+ uniform_bucket_level_access = true
+}
+
+# Output the service URL
+output "service_url" {
+ description = "Cloud Run service URL"
+ value = google_cloud_run_service.flask_app.status[0].url
+}
\ No newline at end of file
diff --git a/terraform/modules/cloud_run/variables.tf b/terraform/modules/cloud_run/variables.tf
new file mode 100644
index 0000000..e202369
--- /dev/null
+++ b/terraform/modules/cloud_run/variables.tf
@@ -0,0 +1,71 @@
+variable "app_name" {
+ description = "Name of the application"
+ type = string
+}
+
+variable "gcp_project_id" {
+ description = "GCP Project ID"
+ type = string
+}
+
+variable "gcp_region" {
+ description = "GCP region"
+ type = string
+}
+
+variable "container_image" {
+ description = "Docker image for the Flask app"
+ type = string
+}
+
+variable "firebase_project_id" {
+ description = "Firebase project ID"
+ type = string
+}
+
+variable "flask_secret_key" {
+ description = "Flask secret key"
+ type = string
+ sensitive = true
+}
+
+variable "service_account_email" {
+ description = "Service account email for the Cloud Run service"
+ type = string
+}
+
+variable "service_account_key_data" {
+ description = "Service account key JSON data"
+ type = string
+ sensitive = true
+}
+
+variable "filevine_client_id" {
+ description = "Filevine client ID"
+ type = string
+ sensitive = true
+}
+
+variable "filevine_client_secret" {
+ description = "Filevine client secret"
+ type = string
+ sensitive = true
+}
+
+variable "filevine_pat" {
+ description = "Filevine personal access token"
+ type = string
+ sensitive = true
+}
+
+variable "filevine_org_id" {
+ description = "Filevine organization ID"
+ type = string
+ sensitive = true
+}
+
+variable "filevine_user_id" {
+ description = "Filevine user ID"
+ type = string
+ sensitive = true
+}
\ No newline at end of file
diff --git a/terraform/templates/email_verification.html b/terraform/templates/email_verification.html
new file mode 100644
index 0000000..00a628b
--- /dev/null
+++ b/terraform/templates/email_verification.html
@@ -0,0 +1,95 @@
+
+
+
+
+
+ Verify Your Email - Rothbard Law Group
+
+
+
+
+
+
+
Welcome to the Rothbard Law Group Client Portal
+
+
+
Thank you for signing up!
+
You're just one step away from accessing your case information securely.
+
+
+
Please verify your email address to complete your registration:
+
+
Verify Email Address
+
+
Or copy and paste this link into your browser:
+
{{ verificationLink }}
+
+
What happens next?
+
+ - Once verified, you'll have full access to the client portal
+ - You can view your case information and documents
+ - Communicate securely with our legal team
+
+
+
Important:
+
+ - This verification link will expire in 24 hours
+ - If you didn't create an account, please ignore this email
+ - Your account information is kept secure and confidential
+
+
+
If you have any questions or need assistance, please contact our support team.
+
+
+
+
+
\ No newline at end of file
diff --git a/terraform/templates/email_verification.txt b/terraform/templates/email_verification.txt
new file mode 100644
index 0000000..ada70c7
--- /dev/null
+++ b/terraform/templates/email_verification.txt
@@ -0,0 +1,31 @@
+Rothbard Law Group - Email Verification
+
+Welcome to Rothbard Law Group Client Portal!
+
+Thank you for signing up for our client portal. You're just one step away from accessing your case information securely.
+
+Please verify your email address to complete your registration:
+{{ verificationLink }}
+
+If the button doesn't work, you can copy and paste this link into your browser.
+
+What happens next?
+- Once verified, you'll have full access to the client portal
+- You can view your case information and documents
+- Communicate securely with our legal team
+
+Important Information:
+- This verification link will expire in 24 hours
+- If you didn't create an account, please ignore this email
+- Your account information is kept secure and confidential
+
+If you have any questions or need assistance, please contact our support team.
+
+Thank you for choosing Rothbard Law Group.
+
+---
+Rothbard Law Group
+123 Legal Street
+City, State 12345
+(555) 123-4567
+support@rothbardlaw.com
\ No newline at end of file
diff --git a/terraform/templates/reset_password.html b/terraform/templates/reset_password.html
new file mode 100644
index 0000000..b362e9d
--- /dev/null
+++ b/terraform/templates/reset_password.html
@@ -0,0 +1,78 @@
+
+
+
+
+
+ Reset Your Password - Rothbard Law Group
+
+
+
+
+
+
+
Reset Your Password
+
+
Hello,
+
+
We received a request to reset the password for your Rothbard Law Group client portal account. Click the button below to reset your password:
+
+
Reset Password
+
+
Or copy and paste this link into your browser:
+
{{ resetLink }}
+
+
Important:
+
+ - This link will expire in 24 hours
+ - If you didn't request a password reset, please ignore this email
+ - For security reasons, never share this link with anyone
+
+
+
If you have any questions or need assistance, please contact our support team.
+
+
+
+
+
\ No newline at end of file
diff --git a/terraform/templates/reset_password.txt b/terraform/templates/reset_password.txt
new file mode 100644
index 0000000..54c362f
--- /dev/null
+++ b/terraform/templates/reset_password.txt
@@ -0,0 +1,27 @@
+Rothbard Law Group - Password Reset
+
+Hello,
+
+We received a request to reset your password for your Rothbard Law Group client portal account.
+
+To reset your password, please visit this link:
+{{ resetLink }}
+
+If the button doesn't work, you can copy and paste the link into your browser.
+
+Important Information:
+- This link will expire in 24 hours
+- If you didn't request a password reset, please ignore this email
+- For security reasons, never share this link with anyone
+
+If you have any questions or need assistance, please contact our support team.
+
+Thank you,
+Rothbard Law Group
+
+---
+Rothbard Law Group
+123 Legal Street
+City, State 12345
+(555) 123-4567
+support@rothbardlaw.com
\ No newline at end of file
diff --git a/terraform/terraform.tfvars.example b/terraform/terraform.tfvars.example
new file mode 100644
index 0000000..5dce2d0
--- /dev/null
+++ b/terraform/terraform.tfvars.example
@@ -0,0 +1,9 @@
+# Copy this file to terraform.tfvars and fill in your values
+gcp_project_id = "your-gcp-project-id"
+domain_name = "rothbard.yourdomain.com"
+
+# Optional: Override defaults
+# gcp_region = "us-central1"
+# firestore_location = "us-central1"
+# hosting_option = "cloud_run" # Options: cloud_run, app_engine, gcs
+# environment = "production"
\ No newline at end of file
diff --git a/terraform/variables.tf b/terraform/variables.tf
new file mode 100644
index 0000000..fc13bb3
--- /dev/null
+++ b/terraform/variables.tf
@@ -0,0 +1,76 @@
+variable "gcp_project_id" {
+ description = "GCP Project ID for the deployment"
+ type = string
+}
+
+variable "gcp_region" {
+ description = "GCP region for resources"
+ type = string
+ default = "us-central1"
+}
+
+variable "firestore_location" {
+ description = "Location for Firestore database"
+ type = string
+ default = "us-central1"
+}
+
+variable "domain_name" {
+ description = "Domain name for the application"
+ type = string
+ default = "rothbard-portal.example.com"
+}
+
+variable "oauth_client_id" {
+ description = "OAuth client ID for Firebase"
+ type = string
+ default = ""
+}
+
+variable "oauth_client_secret" {
+ description = "OAuth client secret for Firebase"
+ type = string
+ default = ""
+ sensitive = true
+}
+
+variable "hosting_option" {
+ description = "Hosting option for the Flask app"
+ type = string
+ default = "cloud_run"
+ validation {
+ condition = contains(["cloud_run", "app_engine"], var.hosting_option)
+ error_message = "The hosting_option must be one of: cloud_run, app_engine."
+ }
+}
+
+variable "environment" {
+ description = "Environment tag"
+ type = string
+ default = "production"
+}
+
+# Firebase Authentication Configuration
+variable "enable_google_signin" {
+ description = "Enable Google Sign-In authentication provider"
+ type = bool
+ default = false
+}
+
+variable "auth_from_email" {
+ description = "From email address for authentication emails"
+ type = string
+ default = "noreply@rothbardlaw.com"
+}
+
+variable "auth_from_name" {
+ description = "From display name for authentication emails"
+ type = string
+ default = "Rothbard Law Group"
+}
+
+variable "auth_reply_to" {
+ description = "Reply-to email address for authentication emails"
+ type = string
+ default = "support@rothbardlaw.com"
+}
\ No newline at end of file