- Remove KCL ecosystem (~220 files deleted) - Migrate all infrastructure to Nickel schema system - Consolidate documentation: legacy docs → provisioning/docs/src/ - Add CI/CD workflows (.github/) and Rust build config (.cargo/) - Update core system for Nickel schema parsing - Update README.md and CHANGES.md for v5.0.0 release - Fix pre-commit hooks: end-of-file, trailing-whitespace - Breaking changes: KCL workspaces require migration - Migration bridge available in docs/src/development/
467 lines
12 KiB
Plaintext
467 lines
12 KiB
Plaintext
# Cost-Optimized Multi-Provider Workspace
|
|
# Architecture: Hetzner (compute) + AWS (managed services) + DigitalOcean (CDN)
|
|
#
|
|
# Strategy:
|
|
# - Hetzner CPX21 servers: Best price/performance for compute (€20.90/month each)
|
|
# - AWS RDS: Managed database with automatic failover
|
|
# - AWS ElastiCache: Redis cache for performance
|
|
# - AWS SQS: Managed message queue
|
|
# - DigitalOcean CDN + Spaces: Object storage and content delivery
|
|
#
|
|
# Estimated Monthly Cost: ~$280
|
|
# All-AWS equivalent: ~$600+/month
|
|
|
|
let hetzner = import "../../../extensions/providers/hetzner/nickel/main.ncl" in
|
|
let aws = import "../../../extensions/providers/aws/nickel/main.ncl" in
|
|
let digitalocean = import "../../../extensions/providers/digitalocean/nickel/main.ncl" in
|
|
|
|
{
|
|
workspace_name = "cost-optimized",
|
|
description = "Cost-optimized deployment using provider specialization",
|
|
version = "1.0",
|
|
|
|
environment = "production",
|
|
owner = "platform-team",
|
|
|
|
tags = {
|
|
"project" = "cost-optimized-app",
|
|
"deployment" = "multi-provider",
|
|
"environment" = "production",
|
|
"cost_optimization" = "enabled"
|
|
},
|
|
|
|
# =============================================================================
|
|
# Provider Configuration
|
|
# =============================================================================
|
|
|
|
providers = {
|
|
hetzner = "primary_compute",
|
|
aws = "managed_services",
|
|
digitalocean = "cdn_and_storage"
|
|
},
|
|
|
|
# =============================================================================
|
|
# Networking Infrastructure
|
|
# =============================================================================
|
|
|
|
networking = {
|
|
# Hetzner Private Network (10.0.0.0/16)
|
|
hetzner_network = hetzner.Network & {
|
|
name = "compute-network",
|
|
ip_range = "10.0.0.0/16",
|
|
labels = { "tier" = "compute" }
|
|
},
|
|
|
|
# Hetzner Subnet
|
|
hetzner_subnet = hetzner.Subnet & {
|
|
network = "compute-network",
|
|
network_zone = "eu-central",
|
|
ip_range = "10.0.1.0/24"
|
|
},
|
|
|
|
# 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,
|
|
tags = [
|
|
{ key = "Name", value = "managed-services-vpc" }
|
|
]
|
|
},
|
|
|
|
# AWS Private Subnet for RDS
|
|
aws_db_subnet = aws.Subnet & {
|
|
vpc_id = "{{ networking.aws_vpc.id }}",
|
|
cidr_block = "10.1.1.0/24",
|
|
availability_zone = "us-east-1a",
|
|
map_public_ip_on_launch = false,
|
|
tags = [
|
|
{ key = "Name", value = "db-subnet" }
|
|
]
|
|
}
|
|
},
|
|
|
|
# =============================================================================
|
|
# Hetzner: Compute Tier (Best Price/Performance)
|
|
# CPX21: 4 vCPU, 8GB RAM, 10Gbps, €20.90/month each = €62.70 for 3 servers
|
|
# =============================================================================
|
|
|
|
compute_tier = {
|
|
# Primary application servers
|
|
primary_servers = hetzner.Server & {
|
|
name = "app",
|
|
server_type = "cpx21",
|
|
image = "ubuntu-22.04",
|
|
location = "nbg1",
|
|
count = 3,
|
|
networks = [
|
|
{
|
|
network_name = "compute-network",
|
|
ip = "10.0.1.10"
|
|
}
|
|
],
|
|
labels = {
|
|
"tier" = "application",
|
|
"cost_center" = "compute",
|
|
"provider" = "hetzner"
|
|
}
|
|
},
|
|
|
|
# Load Balancer for compute tier
|
|
load_balancer = hetzner.LoadBalancer & {
|
|
name = "app-lb",
|
|
load_balancer_type = "lb21",
|
|
location = "nbg1",
|
|
services = [
|
|
{
|
|
protocol = "http",
|
|
listen_port = 80,
|
|
destination_port = 8080,
|
|
health_check = {
|
|
protocol = "http",
|
|
port = 8080,
|
|
interval = 10,
|
|
timeout = 5
|
|
}
|
|
},
|
|
{
|
|
protocol = "https",
|
|
listen_port = 443,
|
|
destination_port = 8080,
|
|
health_check = {
|
|
protocol = "http",
|
|
port = 8080,
|
|
interval = 10,
|
|
timeout = 5
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
|
|
# =============================================================================
|
|
# AWS: Managed Services Tier
|
|
# RDS ($60/month) + ElastiCache ($25/month) + SQS ($15/month)
|
|
# =============================================================================
|
|
|
|
managed_services = {
|
|
# Security Group for RDS access from Hetzner
|
|
database_sg = aws.SecurityGroup & {
|
|
name = "rds-access-sg",
|
|
description = "Allow database access from Hetzner compute tier",
|
|
vpc_id = "{{ networking.aws_vpc.id }}",
|
|
ingress_rules = [
|
|
{
|
|
protocol = "tcp",
|
|
from_port = 5432,
|
|
to_port = 5432,
|
|
cidr_blocks = ["10.0.0.0/16"]
|
|
}
|
|
]
|
|
},
|
|
|
|
# Managed PostgreSQL Database
|
|
database = aws.RDS & {
|
|
identifier = "app-db",
|
|
engine = "postgres",
|
|
engine_version = "14.6",
|
|
instance_class = "db.t3.small",
|
|
allocated_storage = 100,
|
|
storage_type = "gp3",
|
|
storage_iops = 3000,
|
|
storage_throughput = 125,
|
|
|
|
# High Availability
|
|
multi_az = true,
|
|
publicly_accessible = false,
|
|
db_subnet_group_name = "default",
|
|
vpc_security_group_ids = ["{{ managed_services.database_sg.id }}"],
|
|
|
|
# Backups
|
|
backup_retention_days = 30,
|
|
backup_window = "03:00-04:00",
|
|
maintenance_window = "sun:04:00-sun:05:00",
|
|
skip_final_snapshot = false,
|
|
|
|
# Monitoring
|
|
enable_cloudwatch_logs_exports = ["postgresql"],
|
|
enable_enhanced_monitoring = true,
|
|
monitoring_interval = 60,
|
|
|
|
# Encryption
|
|
storage_encrypted = true,
|
|
|
|
tags = [
|
|
{ key = "Environment", value = "production" },
|
|
{ key = "Provider", value = "aws" },
|
|
{ key = "Cost", value = "optimized" }
|
|
]
|
|
},
|
|
|
|
# Redis Cache for performance
|
|
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,
|
|
multi_az_enabled = true,
|
|
subnet_group_name = "default",
|
|
|
|
# Performance
|
|
snapshot_retention_limit = 5,
|
|
snapshot_window = "03:00-05:00",
|
|
|
|
tags = [
|
|
{ key = "Environment", value = "production" },
|
|
{ key = "Purpose", value = "caching" }
|
|
]
|
|
},
|
|
|
|
# Message Queue for async operations
|
|
queue = aws.SQS & {
|
|
queue_name = "app-queue",
|
|
visibility_timeout_seconds = 300,
|
|
message_retention_seconds = 1209600,
|
|
receive_wait_time_seconds = 20,
|
|
|
|
# Encryption
|
|
kms_master_key_id = "alias/aws/sqs",
|
|
|
|
tags = {
|
|
"Environment" = "production",
|
|
"Purpose" = "async-operations"
|
|
}
|
|
}
|
|
},
|
|
|
|
# =============================================================================
|
|
# DigitalOcean: CDN and Object Storage Tier
|
|
# CDN ($25/month) + Edge nodes ($24/month) + Spaces ($15/month)
|
|
# =============================================================================
|
|
|
|
cdn_tier = {
|
|
# Object Storage (Spaces) for application assets
|
|
object_storage = {
|
|
provider = "digitalocean",
|
|
space_name = "app-content",
|
|
region = "nyc3",
|
|
versioning = true,
|
|
cors_enabled = true,
|
|
|
|
lifecycle_rules = [
|
|
{
|
|
id = "delete-old-temp-files",
|
|
days = 30,
|
|
action = "delete",
|
|
prefix = "temp/"
|
|
},
|
|
{
|
|
id = "archive-old-logs",
|
|
days = 90,
|
|
action = "transition",
|
|
prefix = "logs/",
|
|
storage_class = "standard-ia"
|
|
}
|
|
]
|
|
},
|
|
|
|
# CDN distribution for content delivery
|
|
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"],
|
|
size = "s-1vcpu-1gb",
|
|
image = "ubuntu-22-04-x64",
|
|
count = 1,
|
|
backups = false,
|
|
monitoring = true,
|
|
tags = ["edge", "cdn", "cost-optimized"]
|
|
}
|
|
},
|
|
|
|
# =============================================================================
|
|
# Networking Configuration - VPN Tunnel
|
|
# =============================================================================
|
|
|
|
vpn_tunnel = {
|
|
hetzner_to_aws = {
|
|
name = "hetzner-aws-vpn",
|
|
protocol = "ipsec",
|
|
source_network = "10.0.0.0/16",
|
|
destination_network = "10.1.0.0/16",
|
|
encryption = "aes-256",
|
|
authentication = "sha256",
|
|
description = "IPSec tunnel from Hetzner compute to AWS managed services"
|
|
}
|
|
},
|
|
|
|
# =============================================================================
|
|
# Deployment Configuration
|
|
# =============================================================================
|
|
|
|
deployment = {
|
|
strategy = "rolling",
|
|
batch_size = 1,
|
|
health_check_wait = 60,
|
|
rollback_on_failure = true,
|
|
|
|
# Deployment order: Infrastructure → Compute → Services
|
|
order = [
|
|
"networking",
|
|
"compute_tier",
|
|
"managed_services",
|
|
"cdn_tier"
|
|
]
|
|
},
|
|
|
|
# =============================================================================
|
|
# Monitoring and Alerts
|
|
# =============================================================================
|
|
|
|
monitoring = {
|
|
enabled = true,
|
|
|
|
# Hetzner metrics
|
|
hetzner_metrics = {
|
|
cpu_threshold = 80,
|
|
memory_threshold = 85,
|
|
disk_threshold = 90,
|
|
network_threshold = 1000
|
|
},
|
|
|
|
# AWS CloudWatch metrics
|
|
aws_metrics = {
|
|
database_cpu = 75,
|
|
database_connections = 100,
|
|
database_disk = 90,
|
|
cache_cpu = 80,
|
|
queue_depth = 1000
|
|
},
|
|
|
|
# DigitalOcean metrics
|
|
do_metrics = {
|
|
cpu_threshold = 80,
|
|
memory_threshold = 85,
|
|
bandwidth_threshold = 500
|
|
},
|
|
|
|
# Alerting
|
|
alerts = [
|
|
{
|
|
name = "high-compute-cpu",
|
|
condition = "compute_cpu > 80%",
|
|
action = "scale_up",
|
|
severity = "warning"
|
|
},
|
|
{
|
|
name = "high-database-connections",
|
|
condition = "database_connections > 100",
|
|
action = "alert",
|
|
severity = "warning"
|
|
},
|
|
{
|
|
name = "high-queue-depth",
|
|
condition = "queue_depth > 1000",
|
|
action = "alert",
|
|
severity = "critical"
|
|
},
|
|
{
|
|
name = "cache-eviction",
|
|
condition = "cache_eviction_rate > 10%",
|
|
action = "alert",
|
|
severity = "warning"
|
|
}
|
|
]
|
|
},
|
|
|
|
# =============================================================================
|
|
# Backup and Disaster Recovery
|
|
# =============================================================================
|
|
|
|
backup_strategy = {
|
|
frequency = "daily",
|
|
retention_days = 30,
|
|
compression = true,
|
|
encryption = true,
|
|
|
|
procedures = [
|
|
{
|
|
name = "rds-automated-backup",
|
|
type = "aws-rds",
|
|
frequency = "daily",
|
|
retention = "30-days",
|
|
description = "AWS RDS automated backups with point-in-time recovery"
|
|
},
|
|
{
|
|
name = "application-snapshot",
|
|
type = "hetzner-volume",
|
|
frequency = "weekly",
|
|
retention = "12-weeks",
|
|
description = "Weekly snapshots of application state"
|
|
},
|
|
{
|
|
name = "cdn-content-backup",
|
|
type = "digitalocean-spaces",
|
|
frequency = "weekly",
|
|
retention = "90-days",
|
|
description = "Backup of CDN/Spaces content to secondary region"
|
|
}
|
|
]
|
|
},
|
|
|
|
# =============================================================================
|
|
# Cost Estimation
|
|
# =============================================================================
|
|
|
|
cost_estimate = {
|
|
monthly_breakdown = {
|
|
hetzner = {
|
|
compute_servers = "€62.70",
|
|
load_balancer = "€10.00",
|
|
subtotal = "€72.70"
|
|
},
|
|
|
|
aws = {
|
|
rds_database = "$60.00",
|
|
elasticache_redis = "$25.00",
|
|
sqs_queue = "$15.00",
|
|
data_transfer = "$10.00",
|
|
cloudwatch = "$5.00",
|
|
subtotal = "$115.00"
|
|
},
|
|
|
|
digitalocean = {
|
|
cdn = "$25.00",
|
|
edge_nodes = "$24.00",
|
|
spaces_storage = "$15.00",
|
|
subtotal = "$64.00"
|
|
},
|
|
|
|
total_usd = "€72.70 + $115 + $64 ≈ $280/month",
|
|
total_annual = "~$3,360/year",
|
|
|
|
comparison = {
|
|
all_aws_equivalent = "~$600+/month",
|
|
savings = "~$320/month (53% reduction)"
|
|
}
|
|
}
|
|
}
|
|
}
|