Overview
This guide covers the configuration of Multi-Cloud Manager beyond basic environment variables, including application settings, CORS policies, proxy configuration, and cloud provider integrations.
Application Configuration
Backend Configuration
The Flask backend is configured in project/backend/app.py:
from flask import Flask
from flask_cors import CORS
def create_app():
app = Flask(__name__)
app.secret_key = "super-secret-key"
CORS(app, supports_credentials=True, origins=["http://localhost:3000"])
# Register blueprints
from auth.routes import auth_bp
from azure_modules.routes import azure_bp_module
from gcp.routes import gcp_api
app.register_blueprint(gcp_api)
app.register_blueprint(auth_bp)
app.register_blueprint(azure_bp_module)
return app
if __name__ == "__main__":
app = create_app()
app.run(debug=True, host="0.0.0.0", port=5000)
Key Settings
Secret Key
The default secret key "super-secret-key" should be changed in production. Use a strong, random value.
Recommended production configuration:
import os
app.secret_key = os.getenv("FLASK_SECRET_KEY", "super-secret-key")
Add to .env:
FLASK_SECRET_KEY=your-very-long-random-secret-key-here
Generate a secure secret key:
python -c 'import secrets; print(secrets.token_hex(32))'
Debug Mode
- Development:
debug=True enables hot reload and detailed error messages
- Production: Set
debug=False to disable debug mode
app.run(debug=os.getenv("FLASK_DEBUG", "False") == "True", host="0.0.0.0", port=5000)
Host and Port
host="0.0.0.0": Allows external connections (required for Docker)
port=5000: Default backend port
Frontend Configuration
The React frontend is configured in project/frontend/package.json:
{
"name": "frontend",
"version": "0.1.0",
"private": true,
"proxy": "http://backend:5000",
"scripts": {
"start": "WATCHPACK_POLLING=true react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test"
}
}
Proxy Configuration
The proxy setting routes API requests from the frontend to the backend:
- Development (Docker):
"proxy": "http://backend:5000"
- Development (Local):
"proxy": "http://localhost:5000"
- Production: Configure reverse proxy or API gateway
Watch Polling
WATCHPACK_POLLING=true enables file watching in Docker containers for hot reload. This is necessary because Docker volume mounts may not properly trigger file system events.
CORS Configuration
Development CORS
The backend allows requests from http://localhost:3000 by default:
CORS(app, supports_credentials=True, origins=["http://localhost:3000"])
Production CORS
For production, configure allowed origins via environment variable:
import os
allowed_origins = os.getenv("CORS_ORIGINS", "http://localhost:3000").split(",")
CORS(app, supports_credentials=True, origins=allowed_origins)
Add to .env:
CORS_ORIGINS=https://app.example.com,https://www.example.com
CORS Settings Explained
supports_credentials=True: Allows cookies and authentication headers
origins: List of allowed origin URLs
- Wildcard (
*): Not recommended for production with credentials
Cloud Provider Configuration
Azure Configuration
Azure services are configured through multiple modules:
Authentication (auth/azure_auth.py)
AUTHORITY = f"https://login.microsoftonline.com/{os.getenv('AZURE_TENANT_ID')}"
CLIENT_ID = os.getenv("AZURE_CLIENT_ID")
CLIENT_SECRET = os.getenv("AZURE_CLIENT_SECRET")
APP_BASE_URL = os.getenv("APP_BASE_URL", "http://localhost:5000")
Resource Management (azure_modules/utils.py)
CLIENT_ID = os.getenv("AZURE_CLIENT_ID")
CLIENT_SECRET = os.getenv("AZURE_CLIENT_SECRET")
TENANT_ID = os.getenv("AZURE_TENANT_ID")
FRONTEND_URL = os.getenv("FRONTEND_URL", "http://localhost:3000")
Required Environment Variables:
AZURE_CLIENT_ID: Application ID from Azure AD
AZURE_CLIENT_SECRET: Client secret for authentication
AZURE_TENANT_ID: Azure AD tenant ID
APP_BASE_URL: Backend URL for OAuth callbacks
FRONTEND_URL: Frontend URL for redirects
GCP services are configured in multiple modules:
Authentication (auth/gcp_auth.py)
GOOGLE_CLIENT_ID = os.getenv("GOOGLE_CLIENT_ID")
GOOGLE_CLIENT_SECRET = os.getenv("GOOGLE_CLIENT_SECRET")
GOOGLE_REDIRECT_URI = os.getenv("GOOGLE_REDIRECT_URI")
API Integration (gcp/utils.py)
GOOGLE_CLIENT_ID = os.getenv("GOOGLE_CLIENT_ID")
GOOGLE_CLIENT_SECRET = os.getenv("GOOGLE_CLIENT_SECRET")
Required Environment Variables:
GOOGLE_CLIENT_ID: OAuth 2.0 client ID
GOOGLE_CLIENT_SECRET: OAuth 2.0 client secret
GOOGLE_REDIRECT_URI: OAuth callback URL
AWS Configuration
AWS services are configured using IAM credentials:
Authentication (auth/aws_auth.py)
AWS_SERVER_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID")
AWS_SERVER_SECRET_KEY = os.getenv("AWS_SECRET_ACCESS_KEY")
AWS_SERVER_ACCOUNT_ID = os.getenv("AWS_ACCOUNT_ID")
API Integration (aws/utils.py)
AWS_SERVER_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID")
AWS_SERVER_SECRET_KEY = os.getenv("AWS_SECRET_ACCESS_KEY")
Required Environment Variables:
AWS_ACCESS_KEY_ID: IAM user access key
AWS_SECRET_ACCESS_KEY: IAM user secret key
AWS_ACCOUNT_ID: AWS account identifier
Network Configuration
Docker Network
The application uses a bridge network for inter-container communication:
networks:
app-network:
driver: bridge
Benefits:
- Isolated network for application services
- Service discovery by container name
- Network-level security
Service Communication
Frontend communicates with backend using the service name:
"proxy": "http://backend:5000"
Docker’s DNS resolver automatically maps backend to the backend container’s IP address.
Dependencies Configuration
Backend Dependencies
Defined in project/backend/requirements.txt:
Core Framework:
flask: Web framework
flask_cors: CORS handling
python-dotenv: Environment variable loading
Azure SDK:
msal: Microsoft Authentication Library
azure-identity: Azure authentication
azure-mgmt-*: Azure service management clients
azure-monitor-query: Azure Monitor integration
azure-storage-blob: Blob storage operations
Google Cloud SDK:
google-auth: GCP authentication
google-auth-oauthlib: OAuth 2.0 flows
google-api-python-client: Google API client
google-cloud-*: GCP service clients
AWS SDK:
boto3: AWS SDK for Python
Utilities:
requests: HTTP client
six: Python 2/3 compatibility
packaging: Version parsing
pytz: Timezone handling
Frontend Dependencies
Defined in project/frontend/package.json:
Core Framework:
react: UI library (v19.1.1)
react-dom: React DOM renderer
react-scripts: Create React App scripts
Routing:
react-router-dom: Client-side routing (v7.8.2)
Visualization:
recharts: Chart components (v3.2.1)
Testing:
@testing-library/react: React testing utilities
@testing-library/jest-dom: Jest DOM matchers
@testing-library/user-event: User interaction simulation
Monitoring:
web-vitals: Performance metrics
Production Configuration
Environment-Specific Settings
Create separate configuration files:
.env.production
# Backend
FLASK_SECRET_KEY=your-production-secret-key
FLASK_DEBUG=False
APP_BASE_URL=https://api.yourdomain.com
FRONTEND_URL=https://app.yourdomain.com
CORS_ORIGINS=https://app.yourdomain.com
# Azure
AZURE_CLIENT_ID=prod-client-id
AZURE_CLIENT_SECRET=prod-client-secret
AZURE_TENANT_ID=prod-tenant-id
# Google Cloud
GOOGLE_CLIENT_ID=prod-client-id
GOOGLE_CLIENT_SECRET=prod-client-secret
GOOGLE_REDIRECT_URI=https://api.yourdomain.com/auth/google/callback
# AWS
AWS_ACCESS_KEY_ID=prod-access-key
AWS_SECRET_ACCESS_KEY=prod-secret-key
AWS_ACCOUNT_ID=123456789012
Reverse Proxy Configuration
Use Nginx or similar for production:
nginx.conf example:
server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://frontend:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /api {
proxy_pass http://backend:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
SSL/TLS Configuration
Use Let’s Encrypt or cloud provider certificates:
server {
listen 443 ssl http2;
server_name yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
# ... rest of configuration
}
Logging Configuration
Configure structured logging for production:
import logging
import os
if os.getenv("ENVIRONMENT") == "production":
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler("app.log"),
logging.StreamHandler()
]
)
else:
logging.basicConfig(level=logging.DEBUG)
Health Checks
Implement health check endpoints:
@app.route("/health")
def health_check():
return {"status": "healthy", "timestamp": datetime.utcnow().isoformat()}
@app.route("/readiness")
def readiness_check():
# Check database, external services, etc.
return {"ready": True}
Add to docker-compose.yml:
services:
backend:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
Monitoring and Observability
Application Metrics
Integrate with cloud provider monitoring:
- Azure: Azure Monitor and Application Insights
- GCP: Cloud Monitoring and Cloud Logging
- AWS: CloudWatch
Docker Logs
Configure log aggregation:
services:
backend:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
Troubleshooting
Check Configuration Loading
# View loaded environment variables
docker-compose exec backend python -c "import os; print(os.getenv('AZURE_CLIENT_ID'))"
Test Network Connectivity
# From frontend to backend
docker-compose exec frontend curl http://backend:5000/health
# From backend to frontend
docker-compose exec backend curl http://frontend:3000
Verify Dependencies
# Backend dependencies
docker-compose exec backend pip list
# Frontend dependencies
docker-compose exec frontend npm list
Next Steps