- Introduced Aggregator.sol for Chainlink-compatible oracle functionality, including round-based updates and access control. - Added OracleWithCCIP.sol to extend Aggregator with CCIP cross-chain messaging capabilities. - Created .gitmodules to include OpenZeppelin contracts as a submodule. - Developed a comprehensive deployment guide in NEXT_STEPS_COMPLETE_GUIDE.md for Phase 2 and smart contract deployment. - Implemented Vite configuration for the orchestration portal, supporting both Vue and React frameworks. - Added server-side logic for the Multi-Cloud Orchestration Portal, including API endpoints for environment management and monitoring. - Created scripts for resource import and usage validation across non-US regions. - Added tests for CCIP error handling and integration to ensure robust functionality. - Included various new files and directories for the orchestration portal and deployment scripts.
241 lines
8.4 KiB
YAML
241 lines
8.4 KiB
YAML
#cloud-config
|
|
# Cloud-init configuration for Nginx Proxy Server
|
|
# Routes Cloudflare traffic to backend Besu VMs across 5 US regions
|
|
|
|
package_update: true
|
|
package_upgrade: true
|
|
|
|
packages:
|
|
- nginx
|
|
- certbot
|
|
- python3-certbot-nginx
|
|
- curl
|
|
- jq
|
|
- wget
|
|
- unzip
|
|
- cloudflared
|
|
|
|
write_files:
|
|
- path: /etc/nginx/nginx.conf
|
|
content: |
|
|
user www-data;
|
|
worker_processes auto;
|
|
pid /run/nginx.pid;
|
|
|
|
events {
|
|
worker_connections 1024;
|
|
use epoll;
|
|
}
|
|
|
|
http {
|
|
include /etc/nginx/mime.types;
|
|
default_type application/octet-stream;
|
|
|
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
|
'$status $body_bytes_sent "$http_referer" '
|
|
'"$http_user_agent" "$http_x_forwarded_for"';
|
|
|
|
access_log /var/log/nginx/access.log main;
|
|
error_log /var/log/nginx/error.log warn;
|
|
|
|
sendfile on;
|
|
tcp_nopush on;
|
|
tcp_nodelay on;
|
|
keepalive_timeout 65;
|
|
types_hash_max_size 2048;
|
|
client_max_body_size 20M;
|
|
|
|
# Gzip compression
|
|
gzip on;
|
|
gzip_vary on;
|
|
gzip_proxied any;
|
|
gzip_comp_level 6;
|
|
gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss;
|
|
|
|
# Upstream backend servers (load balancing across 5 US regions)
|
|
# NOTE: Backend VMs use private IPs only. Cross-region connectivity requires VPN/ExpressRoute
|
|
# or Cloudflare Tunnel agents on each backend VM. For Phase 1, configure VPN or use
|
|
# Cloudflare Tunnel on each backend VM to expose services.
|
|
upstream besu_rpc_backend {
|
|
least_conn; # Load balancing method
|
|
|
|
# Backend VMs from all regions (use private IPs - requires VPN/ExpressRoute for cross-region)
|
|
%{ if length([for region, vms in backend_vms : length(vms.private_ips) > 0 ? 1 : 0]) > 0 ~}
|
|
${join("\n ", [for region, vms in backend_vms : length(vms.private_ips) > 0 ? join("\n ", [for idx, ip in vms.private_ips : "server ${ip}:8545 max_fails=3 fail_timeout=30s;"]) : "# No backend VMs in ${region}"])}
|
|
%{ else ~}
|
|
# No backend VMs configured - add default backend or configure backends
|
|
server 127.0.0.1:8545 down; # Placeholder - will return 502
|
|
%{ endif ~}
|
|
}
|
|
|
|
upstream besu_ws_backend {
|
|
least_conn;
|
|
|
|
# Backend VMs from all regions (use private IPs - requires VPN/ExpressRoute for cross-region)
|
|
%{ if length([for region, vms in backend_vms : length(vms.private_ips) > 0 ? 1 : 0]) > 0 ~}
|
|
${join("\n ", [for region, vms in backend_vms : length(vms.private_ips) > 0 ? join("\n ", [for idx, ip in vms.private_ips : "server ${ip}:8546 max_fails=3 fail_timeout=30s;"]) : "# No backend VMs in ${region}"])}
|
|
%{ else ~}
|
|
# No backend VMs configured - add default backend or configure backends
|
|
server 127.0.0.1:8546 down; # Placeholder - will return 502
|
|
%{ endif ~}
|
|
}
|
|
|
|
# HTTP server (redirect to HTTPS)
|
|
server {
|
|
listen 80;
|
|
server_name _;
|
|
|
|
location /.well-known/acme-challenge/ {
|
|
root /var/www/html;
|
|
}
|
|
|
|
location / {
|
|
return 301 https://$host$request_uri;
|
|
}
|
|
}
|
|
|
|
# HTTPS server
|
|
server {
|
|
listen 443 ssl http2;
|
|
server_name _;
|
|
|
|
# SSL configuration (will be updated by certbot)
|
|
ssl_certificate /etc/letsencrypt/live/_/fullchain.pem;
|
|
ssl_certificate_key /etc/letsencrypt/live/_/privkey.pem;
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
|
ssl_prefer_server_ciphers on;
|
|
|
|
# Security headers
|
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
add_header X-XSS-Protection "1; mode=block" always;
|
|
|
|
# RPC HTTP endpoint
|
|
location /rpc {
|
|
proxy_pass http://besu_rpc_backend;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection 'upgrade';
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_cache_bypass $http_upgrade;
|
|
proxy_read_timeout 300s;
|
|
proxy_connect_timeout 75s;
|
|
}
|
|
|
|
# WebSocket endpoint
|
|
location /ws {
|
|
proxy_pass http://besu_ws_backend;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_read_timeout 3600s;
|
|
proxy_connect_timeout 75s;
|
|
}
|
|
|
|
# Health check endpoint
|
|
location /health {
|
|
access_log off;
|
|
return 200 "healthy\n";
|
|
add_header Content-Type text/plain;
|
|
}
|
|
|
|
# Metrics endpoint (if needed)
|
|
location /metrics {
|
|
deny all;
|
|
return 403;
|
|
}
|
|
}
|
|
permissions: '0644'
|
|
owner: root:root
|
|
|
|
- path: /opt/nginx/setup.sh
|
|
content: |
|
|
#!/bin/bash
|
|
set -e
|
|
|
|
ADMIN_USERNAME="${admin_username}"
|
|
|
|
echo "Setting up Nginx Proxy Server..."
|
|
|
|
# Create directories
|
|
mkdir -p /var/www/html
|
|
mkdir -p /etc/nginx/conf.d
|
|
mkdir -p /etc/cloudflared
|
|
|
|
# Test Nginx configuration
|
|
nginx -t
|
|
|
|
# Enable and start Nginx
|
|
systemctl enable nginx
|
|
systemctl restart nginx
|
|
|
|
# Cloudflare Tunnel setup
|
|
echo "Configuring Cloudflare Tunnel..."
|
|
echo "NOTE: You need to run 'cloudflared tunnel login' and 'cloudflared tunnel create <tunnel-name>'"
|
|
echo " Then configure /etc/cloudflared/config.yml with your tunnel ID and credentials"
|
|
echo " See: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/tunnel-guide/"
|
|
|
|
# Create Cloudflare Tunnel systemd service (will be enabled after manual configuration)
|
|
cat > /etc/systemd/system/cloudflared.service << 'EOF'
|
|
[Unit]
|
|
Description=Cloudflare Tunnel
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=root
|
|
ExecStart=/usr/bin/cloudflared tunnel --config /etc/cloudflared/config.yml run
|
|
Restart=on-failure
|
|
RestartSec=5s
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
# Create placeholder config file
|
|
cat > /etc/cloudflared/config.yml << 'EOF'
|
|
# Cloudflare Tunnel Configuration
|
|
# Replace with your actual tunnel ID and credentials after running:
|
|
# cloudflared tunnel login
|
|
# cloudflared tunnel create <tunnel-name>
|
|
#
|
|
# Example configuration:
|
|
# tunnel: <your-tunnel-id>
|
|
# credentials-file: /etc/cloudflared/<tunnel-id>.json
|
|
#
|
|
# ingress:
|
|
# - hostname: your-domain.com
|
|
# service: http://localhost:443
|
|
# - service: http_status:404
|
|
EOF
|
|
|
|
chmod 600 /etc/cloudflared/config.yml
|
|
|
|
echo "Nginx Proxy setup complete!"
|
|
echo "Backend regions configured: ${join(", ", keys(backend_vms))}"
|
|
echo ""
|
|
echo "Next steps:"
|
|
echo "1. SSH to this server: ssh ${admin_username}@<nginx-proxy-public-ip>"
|
|
echo "2. Run: cloudflared tunnel login"
|
|
echo "3. Run: cloudflared tunnel create <tunnel-name>"
|
|
echo "4. Update /etc/cloudflared/config.yml with tunnel ID and ingress rules"
|
|
echo "5. Enable and start: systemctl enable cloudflared && systemctl start cloudflared"
|
|
permissions: '0755'
|
|
owner: root:root
|
|
|
|
runcmd:
|
|
- /opt/nginx/setup.sh
|
|
- systemctl status nginx
|
|
|
|
final_message: "Nginx Proxy Server setup complete. Configure SSL with certbot after DNS is set up."
|
|
|