# Multi-Provider Infrastructure Examples # Nickel examples demonstrating multi-provider deployment patterns # References: multi-provider-deployment.md guide let hetzner = import "../../extensions/providers/hetzner/nickel/main.ncl" in let upcloud = import "../../extensions/providers/upcloud/nickel/main.ncl" in let aws = import "../../extensions/providers/aws/nickel/main.ncl" in let digitalocean = import "../../extensions/providers/digitalocean/nickel/main.ncl" in { # ============================================================================= # Example 1: Three-Provider Web Application # ============================================================================= # Architecture: # - DigitalOcean: Web servers (cost-effective compute) - NYC region # - AWS: Managed PostgreSQL database (high availability) - US-East region # - Hetzner: Backup storage volumes (low-cost data retention) - Germany # # Total Monthly Cost: ~$77 (vs $150+ for single provider) # Key Benefits: Cost optimization, compute specialization, managed database three_provider_web_app = { workspace_name = "three-provider-webapp", description = "Web application leveraging provider strengths", # Provider routing and configuration providers = { primary_compute = "digitalocean", database = "aws", backup = "hetzner" }, # ========================================================================== # Private Networks and VPN Tunnels # ========================================================================== networks = { # DigitalOcean VPC (10.0.0.0/16) do_vpc = digitalocean.VPC & { name = "webapp-vpc", region = "nyc3", ip_range = "10.0.0.0/16" }, # AWS VPC (10.1.0.0/16) aws_vpc = aws.VPC & { cidr_block = "10.1.0.0/16", enable_dns_hostnames = true, enable_dns_support = true }, # AWS DB Subnet aws_db_subnet = aws.Subnet & { vpc_id = "{{ networks.aws_vpc.id }}", cidr_block = "10.1.1.0/24", availability_zone = "us-east-1a" }, # Hetzner Private Network (10.2.0.0/16) hetzner_network = hetzner.Network & { name = "backup-network", ip_range = "10.2.0.0/16" } }, # VPN Tunnels for secure communication vpn_configuration = { do_to_aws_tunnel = { protocol = "ipsec", encryption = "aes-256", source_networks = ["10.0.0.0/16"], destination_networks = ["10.1.0.0/16"], description = "DO web tier to AWS database" }, aws_to_hetzner_tunnel = { protocol = "ipsec", encryption = "aes-256", source_networks = ["10.1.0.0/16"], destination_networks = ["10.2.0.0/16"], description = "AWS database to Hetzner backup" } }, # ========================================================================== # DigitalOcean: Web Tier (3 droplets with load balancer) # ========================================================================== web_tier = { # Application servers droplets = digitalocean.Droplet & { name = "web-server", region = "nyc3", size = "s-2vcpu-4gb", image = "ubuntu-22-04-x64", count = 3, vpc_uuid = "{{ networks.do_vpc.id }}", firewall = { inbound_rules = [ # SSH from management { protocol = "tcp", ports = "22", sources = { addresses = ["0.0.0.0/0"] } }, # HTTP from load balancer { protocol = "tcp", ports = "80", sources = { addresses = ["0.0.0.0/0"] } }, # HTTPS from load balancer { protocol = "tcp", ports = "443", sources = { addresses = ["0.0.0.0/0"] } }, # Database access to AWS RDS { protocol = "tcp", ports = "5432", sources = { addresses = ["10.0.0.0/8"] # AWS VPC CIDR } } ], outbound_rules = [ { protocol = "tcp", destinations = { addresses = ["0.0.0.0/0"] } }, { protocol = "udp", ports = "53", destinations = { addresses = ["8.8.8.8/32", "8.8.4.4/32"] } } ] }, tags = ["web", "production"] }, # Load balancer for web tier load_balancer = digitalocean.LoadBalancer & { name = "web-lb", algorithm = "round_robin", region = "nyc3", forwarding_rules = [ { entry_protocol = "http", entry_port = 80, target_protocol = "http", target_port = 80, certificate_id = null }, { entry_protocol = "https", entry_port = 443, target_protocol = "http", target_port = 80, certificate_id = "cert-id" } ], sticky_sessions = { type = "cookies", cookie_name = "LB_SESSION", cookie_ttl_seconds = 300 } } }, # ========================================================================== # AWS: Database Tier (Managed RDS PostgreSQL) # ========================================================================== # Create security group for RDS database_sg = aws.SecurityGroup & { name = "webapp-db-sg", description = "Security group for RDS database", vpc_id = "{{ networks.aws_vpc.id }}", ingress_rules = [ { protocol = "tcp", from_port = 5432, to_port = 5432, cidr_blocks = ["10.0.0.0/16"] # Allow from DO web tier via VPN } ] }, database_tier = aws.RDS & { identifier = "webapp-db", engine = "postgres", engine_version = "14.6", instance_class = "db.t3.medium", allocated_storage = 100, storage_type = "gp3", multi_az = true, publicly_accessible = false, db_subnet_group_name = "default", vpc_security_group_ids = ["{{ database_sg.id }}"], backup_retention_days = 30, skip_final_snapshot = false, tags = [ { key = "Environment", value = "production" }, { key = "Application", value = "webapp" }, { key = "Network", value = "private-vpc" } ] }, # ========================================================================== # Hetzner: Backup Storage (Volumes for periodic backups) # ========================================================================== backup_storage = hetzner.Volume & { name = "webapp-backups", size = 500, location = "nbg1", automount = false, format = "ext4", labels = { "purpose" = "backup" } } }, # ============================================================================= # Example 2: Multi-Region High Availability # ============================================================================= # Architecture: # - Region 1 (US): DigitalOcean NYC with primary database # - Region 2 (EU): Hetzner Germany with read replicas # - Region 3 (APAC): AWS Singapore with read replicas # # Features: # - Global load balancing with DNS failover # - Async database replication (300s lag) # - Geographic distribution for low latency # - Automatic failover to secondary regions multi_region_ha = { workspace_name = "multi-region-ha", description = "High availability across three geographic regions", global_config = { dns_provider = "route53", ttl = 60, health_check_interval = 30, failover_strategy = "geographic" }, # Primary Region: US East (DigitalOcean) region_us_east = { provider = "digitalocean", region_name = "us-east", location = "nyc3", servers = digitalocean.Droplet & { name = "us-app", region = "nyc3", size = "s-2vcpu-4gb", image = "ubuntu-22-04-x64", count = 3, tags = ["primary", "us-east"] }, database = digitalocean.Database & { name = "us-db", engine = "pg", version = "14", size = "db-s-2vcpu-4gb", region = "nyc3", num_nodes = 3, # 3-node cluster for HA multi_az = true } }, # Secondary Region: EU Central (Hetzner) region_eu_central = { provider = "hetzner", region_name = "eu-central", location = "nbg1", servers = hetzner.Server & { name = "eu-app", server_type = "cx31", image = "ubuntu-22.04", location = "nbg1", count = 3, labels = { "region" = "eu-central" } }, # Read-only replica database database_replica = { replication_lag_seconds = 300, read_only = true, replica_of = "region_us_east.database" } }, # Tertiary Region: APAC (AWS) region_asia_southeast = { provider = "aws", region_name = "asia-southeast", location = "ap-southeast-1", servers = aws.EC2 & { name = "asia-app", instance_type = "t3.medium", image_id = "ami-xxxxxxxxx", count = 3, region = "ap-southeast-1", tags = [ { key = "Region", value = "asia-southeast" } ] }, # Read-only replica database database_replica = { replication_lag_seconds = 300, read_only = true, replica_of = "region_us_east.database" } }, # Global DNS configuration global_load_balancing = { dns_zones = ["example.com"], records = [ { name = "us.example.com", type = "A", ttl = 60, failover_primary = true, health_check = { protocol = "HTTPS", path = "/health", interval = 30 } }, { name = "eu.example.com", type = "A", ttl = 60, failover_secondary = true, health_check = { protocol = "HTTPS", path = "/health", interval = 30 } }, { name = "asia.example.com", type = "A", ttl = 60, failover_tertiary = true, health_check = { protocol = "HTTPS", path = "/health", interval = 30 } } ], geolocation_routing = { north_america = "us.example.com", europe = "eu.example.com", asia_pacific = "asia.example.com" } } }, # ============================================================================= # Example 3: Cost-Optimized Deployment # ============================================================================= # Architecture: # - Hetzner: Application compute (best price/performance) # - AWS: Managed services (RDS, ElastiCache, SQS) # - DigitalOcean: CDN and edge locations (cost-effective distribution) # # Cost Optimization: # - Compute on Hetzner (€50/month vs $300 on AWS) # - Managed services on AWS (reliability + managed ops) # - CDN on DigitalOcean (cheaper than CloudFront) # # Monthly Cost Breakdown: # - Hetzner: €50 for 5 CPX21 servers # - AWS: $150 for RDS + ElastiCache + SQS # - DigitalOcean: $50 for CDN and edge nodes # Total: ~$250/month (vs $600+ for all-AWS) cost_optimized_deployment = { workspace_name = "cost-optimized", description = "Optimized deployment using provider strengths", # ========================================================================== # Hetzner: Application Tier (Best compute pricing) # ========================================================================== compute_tier = { # Main application servers primary_servers = hetzner.Server & { name = "app", server_type = "cpx21", # 4 vCPU, 8GB RAM, 10Gbps - €20.90/month image = "ubuntu-22.04", location = "nbg1", count = 3, labels = { "tier" = "application", "cost_center" = "compute" } }, # Storage node for shared data storage_node = hetzner.Server & { name = "storage", server_type = "cx41", # 4 vCPU, 16GB RAM image = "ubuntu-22.04", location = "nbg1", volumes = [ { size = 1000, format = "ext4", automount = true } ], labels = { "tier" = "storage", "cost_center" = "storage" } } }, # ========================================================================== # AWS: Managed Services Tier # ========================================================================== managed_services = { # Database database = aws.RDS & { identifier = "app-db", engine = "postgres", engine_version = "14.6", instance_class = "db.t3.small", allocated_storage = 100, multi_az = true }, # Cache cache = aws.ElastiCache & { cluster_id = "app-cache", engine = "redis", engine_version = "7.0", node_type = "cache.t3.small", num_cache_nodes = 2, automatic_failover_enabled = true }, # Message Queue queue = aws.SQS & { queue_name = "app-queue", visibility_timeout_seconds = 300, message_retention_seconds = 1209600 } }, # ========================================================================== # DigitalOcean: CDN and Edge Tier # ========================================================================== cdn_tier = { # CDN distribution cdn = { provider = "digitalocean", endpoints = [ { name = "app-cdn", origin = "content.example.com", regions = ["nyc1", "sfo1", "lon1", "sgp1", "blr1"], cache_control = { browser_cache_ttl = 3600, cdn_cache_ttl = 86400 } } ] }, # Edge nodes for regional content delivery edge_nodes = digitalocean.Droplet & { name = "edge-node", regions = ["nyc3", "sfo3", "lon1", "sgp1"], size = "s-1vcpu-1gb", image = "ubuntu-22-04-x64", count = 1, # 1 per region tags = ["edge", "cdn"] }, # Spaces for object storage object_storage = { provider = "digitalocean", space_name = "app-content", region = "nyc3", versioning = true, lifecycle_rules = [ { id = "delete-old-files", days = 90, action = "delete" } ] } }, # Cost model cost_model = { monthly_estimate = { hetzner = { primary_servers = "€62.70", # 3x CPX21 @ €20.90 storage_node = "€27.60", # 1x CX41 subtotal = "€90.30" }, aws = { database = "$60", cache = "$25", queue = "$15", subtotal = "$100" }, digitalocean = { cdn = "$25", edge_nodes = "$24", # 4x $6 droplets object_storage = "$15", subtotal = "$64" }, total = "€90.30 + $100 + $64 ≈ $280/month" } } } }