# Deployment Strategies

Production deployment patterns and best practices.

## Blue-Green Deployment

Zero-downtime deployments with automatic rollback capability.

### Flow

```text
Before:  Users → [Blue Environment (Active)]
After:   Users → [Green Environment (Active)]
         [Blue Environment (Standby)]
```

### Implementation

```bash
#!/usr/bin/env nu

def blue-green-deploy [new-version] {
  # 1. Identify current active environment
  let current = (provisioning deployment current-env)
  let active = if $current == "blue" { "green" } else { "blue" }

  print $"Current: ($current), Deploying to: ($active)"

  # 2. Deploy to standby environment
  provisioning workspace use "prod-$active"
  provisioning infra apply --config "config/deployment-$new-version.ncl"

  # 3. Run health checks
  sleep 30sec  # Wait for services to stabilize
  let health = (provisioning test smoke-tests --environment $active)
  if $health != "passed" {
    error "Health checks failed on $active environment"
  }

  # 4. Switch traffic
  provisioning load-balancer update --primary $active

  # 5. Monitor
  sleep 60sec
  let error_rate = (provisioning metrics get "error_rate{environment=\"$active\"}")
  if $error_rate > 0.01 {  # 1% threshold
    provisioning load-balancer rollback
    error "Error rate too high, rolled back"
  }

  print "Deployment complete"
}
```

## Canary Deployment

Gradually roll out to detect issues early.

### Configuration

```nickel
{
  deployment = {
    strategy = "canary",
    stages = [
      {
        name = "stage-1-5-percent",
        traffic_percentage = 5,
        duration_minutes = 5,
        metrics_threshold = { error_rate = "< 0.5%" }
      },
      {
        name = "stage-2-25-percent",
        traffic_percentage = 25,
        duration_minutes = 10,
        metrics_threshold = { error_rate = "< 0.5%" }
      },
      {
        name = "stage-3-50-percent",
        traffic_percentage = 50,
        duration_minutes = 15,
        metrics_threshold = { error_rate = "< 0.5%" }
      },
      {
        name = "stage-4-100-percent",
        traffic_percentage = 100,
        duration_minutes = 30,
        metrics_threshold = { error_rate = "< 0.5%" }
      }
    ]
  }
}
```

### Monitoring

```bash
#!/usr/bin/env nu

def monitor-canary [] {
  let stages = [5, 25, 50, 100]

  for stage in $stages {
    print $"Monitoring stage: ($stage)%"

    # Collect metrics
    sleep 60sec
    let metrics = {
      error_rate = (provisioning metrics get "error_rate"),
      latency_p99 = (provisioning metrics get "latency_p99"),
      requests_per_sec = (provisioning metrics get "rps")
    }

    # Evaluate
    if $metrics.error_rate > 0.01 {
      print "✗ Error rate too high, rolling back"
      provisioning deployment rollback
      return false
    }

    print "✓ Stage ($stage)% healthy"
  }

  print "✓ Canary deployment successful"
  true
}
```

## Rolling Update

Update instances gradually to maintain availability.

### Configuration

```nickel
{
  deployment = {
    strategy = "rolling",
    max_surge = 1,              # Extra instance during update
    max_unavailable = 0,        # Must maintain availability
    update_batch_size = 1,      # Update one at a time
    min_ready_seconds = 30      # Wait before marking healthy
  }
}
```

## Recreate Deployment

Simple strategy for non-critical systems.

```nickel
{
  deployment = {
    strategy = "recreate",
    # Stop all instances, then start new ones
    # Simple but causes downtime
  }
}
```

## A/B Testing Deployment

Run two versions simultaneously for comparison.

```bash
#!/usr/bin/env nu

def ab-test-deploy [version-a version-b] {
  # Deploy both versions
  provisioning infra apply --config "v$version-a.ncl" --tags "version=a"
  provisioning infra apply --config "v$version-b.ncl" --tags "version=b"

  # Split traffic 50/50
  provisioning load-balancer set-weight version-a 50
  provisioning load-balancer set-weight version-b 50

  # Run test for duration
  print "Running A/B test for 1 hour..."
  sleep 3600sec

  # Analyze results
  let metrics-a = (provisioning metrics get-by-tag "version=a")
  let metrics-b = (provisioning metrics get-by-tag "version=b")

  print $"Version A: error_rate=($metrics-a.error_rate), latency=($metrics-a.latency)"
  print $"Version B: error_rate=($metrics-b.error_rate), latency=($metrics-b.latency)"

  # Choose winner
  if $metrics-b.error_rate < $metrics-a.error_rate {
    provisioning load-balancer set-weight version-b 100
    print "Version B chosen as winner"
  } else {
    provisioning load-balancer set-weight version-a 100
    print "Version A chosen as winner"
  }
}
```

## Database Migration Deployment

Safe database schema updates with rollback capability.

```bash
#!/usr/bin/env nu

def deploy-with-db-migration [migration-version] {
  # 1. Create backup before migration
  provisioning backup create --name "pre-migration-$migration-version"

  # 2. Run backward-compatible migration
  provisioning database migrate --version $migration-version --backward-compatible

  # 3. Verify data integrity
  let integrity_check = (provisioning database verify-integrity)
  if $integrity_check != "valid" {
    provisioning database restore --backup "pre-migration-$migration-version"
    error "Data integrity check failed"
  }

  # 4. Deploy application code
  provisioning infra apply --config "deployment-$migration-version.ncl"

  # 5. Monitor for issues
  sleep 120sec
  let error_rate = (provisioning metrics get "error_rate")
  if $error_rate > 0.01 {
    provisioning deployment rollback
    error "Rollback due to high error rate"
  }

  print "Deployment with database migration complete"
}
```

## Scheduled Maintenance Deployment

Deploy during planned maintenance windows.

```nickel
{
  deployment = {
    scheduled = {
      enabled = true,
      maintenance_window = {
        day_of_week = "sunday",
        start_hour = "02:00",
        end_hour = "04:00",
        timezone = "UTC"
      },
      blackout_periods = [
        {
          name = "holiday-season",
          start_date = "2025-12-15",
          end_date = "2026-01-05"
        }
      ]
    }
  }
}
```

## Deployment Rollback

Quick rollback procedures:

```bash
#!/usr/bin/env nu

def rollback [deployment-id] {
  print $"Rolling back deployment: ($deployment-id)"

  # Get previous version
  let previous = (provisioning deployment history $deployment-id | first)

  # Rollback infrastructure
  provisioning infra rollback --to-version $previous.version

  # Rollback database (if needed)
  if $previous.has_database_changes {
    provisioning database rollback --migration $previous.migration_version
  }

  # Verify rollback
  sleep 30sec
  provisioning test smoke-tests
  print "Rollback complete"
}
```

## Deployment Validation

Pre-deployment checklist:

```bash
#!/usr/bin/env nu

def pre-deployment-checks [] {
  let checks = {
    config_valid: (provisioning infra validate),
    no_errors_in_logs: (provisioning logs error | is-empty),
    health_checks_pass: (provisioning test health-checks),
    backup_exists: (provisioning backup list | length > 0),
    disk_space_available: (provisioning resource metrics disk-usage < 90)
  }

  print $checks

  # All must pass
  if ($checks | values | any { | | v $v == false }) {
    error "Pre-deployment checks failed"
    false
  } else {
    print "All pre-deployment checks passed"
    true
  }
}
```

## Related Documentation

- [Operations Overview](./README.md)
- [Upgrade Procedures](./upgrade.md)
- [Monitoring](./monitoring.md)
- [Disaster Recovery](../guides/disaster-recovery.md)
