# First Deployment

Comprehensive walkthrough deploying production-ready infrastructure with the Provisioning platform.

## Overview

This guide walks through deploying a complete Kubernetes cluster with storage and networking
on a cloud provider. You'll learn workspace management, Nickel schema structure, provider
configuration, dependency resolution, and validation workflows.

## Deployment Architecture

What we'll build:

- 3-node Kubernetes cluster (1 control plane, 2 workers)
- Cilium CNI for networking
- Rook-Ceph for persistent storage
- Container runtime (containerd)
- Automated dependency resolution
- Health monitoring

## Prerequisites

- Platform [installed](installation.md)
- Cloud provider credentials configured (UpCloud or AWS recommended)
- 30-60 minutes for complete deployment

## Part 1: Workspace Setup

### Create Workspace

```bash
# Initialize production workspace
provisioning workspace init production-k8s
cd production-k8s

# Verify structure
ls -la
```

Workspace contains:

```text
production-k8s/
├── infra/       # Infrastructure Nickel schemas
├── config/      # Workspace configuration
├── extensions/  # Custom providers/taskservs
└── runtime/     # State and logs
```

### Configure Workspace

```bash
# Edit workspace configuration
cat > config/provisioning-config.yaml <<'EOF'
workspace:
  name: production-k8s
  environment: production

defaults:
  provider: upcloud  # or aws
  region: de-fra1    # UpCloud Frankfurt
  ssh_key_path: ~/.ssh/provisioning_production

servers:
  default_plan: medium
  auto_backup: true

logging:
  level: info
  format: text
EOF
```

## Part 2: Infrastructure Definition

### Define Nickel Schema

Create infrastructure definition with type-safe Nickel:

```bash
# Create Kubernetes cluster schema
cat > infra/k8s-cluster.ncl <<'EOF'
{
  metadata = {
    name = "k8s-prod"
    provider = "upcloud"
    environment = "production"
    version = "1.0.0"
  }

  infrastructure = {
    servers = [
      {
        name = "k8s-control-01"
        plan = "medium"      # 4 CPU, 8 GB RAM
        role = "control"
        zone = "de-fra1"
        disk_size_gb = 50
        backup_enabled = true
      }
      {
        name = "k8s-worker-01"
        plan = "large"       # 8 CPU, 16 GB RAM
        role = "worker"
        zone = "de-fra1"
        disk_size_gb = 100
        backup_enabled = true
      }
      {
        name = "k8s-worker-02"
        plan = "large"
        role = "worker"
        zone = "de-fra1"
        disk_size_gb = 100
        backup_enabled = true
      }
    ]
  }

  services = {
    taskservs = [
      "containerd"     # Container runtime (dependency)
      "etcd"           # Key-value store (dependency)
      "kubernetes"     # Core orchestration
      "cilium"         # CNI networking
      "rook-ceph"      # Persistent storage
    ]
  }

  kubernetes = {
    version = "1.28.0"
    pod_cidr = "10.244.0.0/16"
    service_cidr = "10.96.0.0/12"
    container_runtime = "containerd"
    cri_socket = "/run/containerd/containerd.sock"
  }

  networking = {
    cni = "cilium"
    enable_network_policy = true
    enable_encryption = true
  }

  storage = {
    provider = "rook-ceph"
    replicas = 3
    storage_class = "ceph-rbd"
  }
}
EOF
```

### Validate Schema

```bash
# Type-check Nickel schema
nickel typecheck infra/k8s-cluster.ncl

# Validate against provisioning contracts
provisioning validate config --infra k8s-cluster
```

Expected output:

```text
Schema validation: PASSED
  - Syntax: Valid Nickel
  - Type safety: All contracts satisfied
  - Dependencies: Resolved (5 taskservs)
  - Provider: upcloud (credentials found)
```

## Part 3: Preview and Validation

### Preview Infrastructure

```bash
# Dry-run to see what will be created
provisioning server create --check --infra k8s-cluster
```

Output shows:

```text
Infrastructure Plan: k8s-prod
Provider: upcloud
Region: de-fra1

Servers to create: 3
  - k8s-control-01 (medium, 4 CPU, 8 GB RAM, 50 GB disk)
  - k8s-worker-01 (large, 8 CPU, 16 GB RAM, 100 GB disk)
  - k8s-worker-02 (large, 8 CPU, 16 GB RAM, 100 GB disk)

Task services: 5 (with dependencies resolved)
  1. containerd (dependency for kubernetes)
  2. etcd (dependency for kubernetes)
  3. kubernetes
  4. cilium (requires kubernetes)
  5. rook-ceph (requires kubernetes)

Estimated monthly cost: $xxx.xx
Estimated deployment time: 15-20 minutes

WARNING: Production deployment - ensure backup enabled
```

### Dependency Graph

```bash
# Visualize dependency resolution
provisioning taskserv dependencies kubernetes --graph
```

Shows:

```text
kubernetes
├── containerd (required)
├── etcd (required)
└── cni (cilium) (soft dependency)

cilium
└── kubernetes (required)

rook-ceph
└── kubernetes (required)
```

## Part 4: Server Provisioning

### Create Servers

```bash
# Create all servers in parallel
provisioning server create --infra k8s-cluster --yes
```

Progress tracking:

```text
Creating 3 servers...
  k8s-control-01: [████████████████████████] 100%
  k8s-worker-01:  [████████████████████████] 100%
  k8s-worker-02:  [████████████████████████] 100%

Servers created: 3/3
SSH configured: 3/3
Network ready: 3/3

Servers available:
  k8s-control-01: 94.237.x.x (running)
  k8s-worker-01:  94.237.x.x (running)
  k8s-worker-02:  94.237.x.x (running)
```

### Verify Server Access

```bash
# Test SSH connectivity
provisioning server ssh k8s-control-01 -- uname -a

# Check all servers
provisioning server list
```

## Part 5: Service Installation

### Install Task Services

```bash
# Install all task services (automatic dependency resolution)
provisioning taskserv create kubernetes --infra k8s-cluster
```

Installation flow (automatic):

```text
Resolving dependencies...
  containerd → etcd → kubernetes → cilium, rook-ceph

Installing task services: 5

[1/5] Installing containerd...
  k8s-control-01: [████████████████████████] 100%
  k8s-worker-01:  [████████████████████████] 100%
  k8s-worker-02:  [████████████████████████] 100%

[2/5] Installing etcd...
  k8s-control-01: [████████████████████████] 100%

[3/5] Installing kubernetes...
  Control plane init: [████████████████████████] 100%
  Worker join: [████████████████████████] 100%
  Cluster ready: [████████████████████████] 100%

[4/5] Installing cilium...
  CNI deployment: [████████████████████████] 100%
  Network policies: [████████████████████████] 100%

[5/5] Installing rook-ceph...
  Operator: [████████████████████████] 100%
  Cluster: [████████████████████████] 100%
  Storage class: [████████████████████████] 100%

All task services installed successfully
```

### Verify Kubernetes Cluster

```bash
# SSH to control plane
provisioning server ssh k8s-control-01

# Check cluster status
kubectl get nodes
kubectl get pods --all-namespaces
kubectl get storageclass
```

Expected output:

```text
NAME              STATUS   ROLES    AGE   VERSION
k8s-control-01    Ready    control-plane  5m   v1.28.0
k8s-worker-01     Ready    <none>   4m   v1.28.0
k8s-worker-02     Ready    <none>   4m   v1.28.0

NAMESPACE     NAME                                READY   STATUS
kube-system   cilium-xxxxx                        1/1     Running
kube-system   cilium-operator-xxxxx               1/1     Running
kube-system   etcd-k8s-control-01                 1/1     Running
rook-ceph     rook-ceph-operator-xxxxx            1/1     Running

NAME              PROVISIONER
ceph-rbd          rook-ceph.rbd.csi.ceph.com
```

## Part 6: Deployment Verification

### Health Checks

```bash
# Platform-level health check
provisioning cluster status k8s-cluster

# Individual service health
provisioning taskserv status kubernetes
provisioning taskserv status cilium
provisioning taskserv status rook-ceph
```

### Test Application Deployment

```bash
# Deploy test application on K8s cluster
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-pvc
spec:
  storageClassName: ceph-rbd
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        volumeMounts:
        - name: storage
          mountPath: /usr/share/nginx/html
      volumes:
      - name: storage
        persistentVolumeClaim:
          claimName: test-pvc
EOF

# Verify deployment
kubectl get deployment test-nginx
kubectl get pods -l app=nginx
kubectl get pvc test-pvc
```

### Network Policy Test

```bash
# Verify Cilium network policies work
kubectl exec -it <pod-name> -- curl  [http://test-nginx](http://test-nginx)
```

## Part 7: State Management

### View State

```bash
# Show current workspace state
provisioning workspace info

# List all resources
provisioning server list
provisioning taskserv list

# Export state for backup
provisioning workspace export > k8s-cluster-state.json
```

### Configuration Backup

```bash
# Backup workspace configuration
tar -czf k8s-cluster-backup.tar.gz infra/ config/ runtime/

# Store securely (encrypted)
sops -e k8s-cluster-backup.tar.gz > k8s-cluster-backup.tar.gz.enc
```

## What You've Learned

This deployment demonstrated:

- Workspace creation and configuration
- Nickel schema structure for infrastructure-as-code
- Type-safe configuration validation
- Automatic dependency resolution
- Multi-server provisioning
- Task service installation with health checks
- Kubernetes cluster deployment
- Storage and networking configuration
- Verification and testing workflows
- State management and backup

## Next Steps

- [Verification](verification.md) - Comprehensive platform health checks
- [Workspace Management](../guides/workspace-management.md) - Advanced workspace patterns
- [Batch Workflows](../infrastructure/batch-workflows.md) - Multi-cloud orchestration
- [Security System](../security/README.md) - Secure your infrastructure
