2025-12-11 21:50:42 +00:00
<!DOCTYPE HTML>
2026-01-17 03:58:28 +00:00
< html lang = "en" class = "rust sidebar-visible" dir = "ltr" >
2025-12-11 21:50:42 +00:00
< head >
<!-- Book generated using mdBook -->
< meta charset = "UTF-8" >
2026-01-17 03:58:28 +00:00
< title > From Scratch Guide - Provisioning Platform Documentation< / title >
2025-12-11 21:50:42 +00:00
<!-- Custom HTML head -->
2026-01-17 03:58:28 +00:00
< meta name = "description" content = "Enterprise-grade Infrastructure as Code platform - Complete documentation" >
2025-12-11 21:50:42 +00:00
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< meta name = "theme-color" content = "#ffffff" >
< link rel = "icon" href = "../favicon.svg" >
< link rel = "shortcut icon" href = "../favicon.png" >
< link rel = "stylesheet" href = "../css/variables.css" >
< link rel = "stylesheet" href = "../css/general.css" >
< link rel = "stylesheet" href = "../css/chrome.css" >
< link rel = "stylesheet" href = "../css/print.css" media = "print" >
<!-- Fonts -->
< link rel = "stylesheet" href = "../FontAwesome/css/font-awesome.css" >
< link rel = "stylesheet" href = "../fonts/fonts.css" >
<!-- Highlight.js Stylesheets -->
< link rel = "stylesheet" id = "highlight-css" href = "../highlight.css" >
< link rel = "stylesheet" id = "tomorrow-night-css" href = "../tomorrow-night.css" >
< link rel = "stylesheet" id = "ayu-highlight-css" href = "../ayu-highlight.css" >
<!-- Custom theme stylesheets -->
<!-- Provide site root and default themes to javascript -->
< script >
const path_to_root = "../";
2026-01-17 03:58:28 +00:00
const default_light_theme = "rust";
2025-12-11 21:50:42 +00:00
const default_dark_theme = "navy";
< / script >
<!-- Start loading toc.js asap -->
< script src = "../toc.js" > < / script >
< / head >
< body >
< div id = "mdbook-help-container" >
< div id = "mdbook-help-popup" >
< h2 class = "mdbook-help-title" > Keyboard shortcuts< / h2 >
< div >
< p > Press < kbd > ←< / kbd > or < kbd > →< / kbd > to navigate between chapters< / p >
< p > Press < kbd > S< / kbd > or < kbd > /< / kbd > to search in the book< / p >
< p > Press < kbd > ?< / kbd > to show this help< / p >
< p > Press < kbd > Esc< / kbd > to hide this help< / p >
< / div >
< / div >
< / div >
< div id = "body-container" >
<!-- Work around some values being stored in localStorage wrapped in quotes -->
< script >
try {
let theme = localStorage.getItem('mdbook-theme');
let sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') & & theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') & & sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
< / script >
<!-- Set the theme before any content is loaded, prevents flash -->
< script >
const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? default_dark_theme : default_light_theme;
let theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
const html = document.documentElement;
2026-01-17 03:58:28 +00:00
html.classList.remove('rust')
2025-12-11 21:50:42 +00:00
html.classList.add(theme);
html.classList.add("js");
< / script >
< input type = "checkbox" id = "sidebar-toggle-anchor" class = "hidden" >
<!-- Hide / unhide sidebar before it is displayed -->
< script >
let sidebar = null;
const sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
< / script >
< nav id = "sidebar" class = "sidebar" aria-label = "Table of contents" >
<!-- populated by js -->
< mdbook-sidebar-scrollbox class = "sidebar-scrollbox" > < / mdbook-sidebar-scrollbox >
< noscript >
< iframe class = "sidebar-iframe-outer" src = "../toc.html" > < / iframe >
< / noscript >
< div id = "sidebar-resize-handle" class = "sidebar-resize-handle" >
< div class = "sidebar-resize-indicator" > < / div >
< / div >
< / nav >
< div id = "page-wrapper" class = "page-wrapper" >
< div class = "page" >
< div id = "menu-bar-hover-placeholder" > < / div >
< div id = "menu-bar" class = "menu-bar sticky" >
< div class = "left-buttons" >
< label id = "sidebar-toggle" class = "icon-button" for = "sidebar-toggle-anchor" title = "Toggle Table of Contents" aria-label = "Toggle Table of Contents" aria-controls = "sidebar" >
< i class = "fa fa-bars" > < / i >
< / label >
< button id = "theme-toggle" class = "icon-button" type = "button" title = "Change theme" aria-label = "Change theme" aria-haspopup = "true" aria-expanded = "false" aria-controls = "theme-list" >
< i class = "fa fa-paint-brush" > < / i >
< / button >
< ul id = "theme-list" class = "theme-popup" aria-label = "Themes" role = "menu" >
< li role = "none" > < button role = "menuitem" class = "theme" id = "default_theme" > Auto< / button > < / li >
< li role = "none" > < button role = "menuitem" class = "theme" id = "light" > Light< / button > < / li >
< li role = "none" > < button role = "menuitem" class = "theme" id = "rust" > Rust< / button > < / li >
< li role = "none" > < button role = "menuitem" class = "theme" id = "coal" > Coal< / button > < / li >
< li role = "none" > < button role = "menuitem" class = "theme" id = "navy" > Navy< / button > < / li >
< li role = "none" > < button role = "menuitem" class = "theme" id = "ayu" > Ayu< / button > < / li >
< / ul >
< button id = "search-toggle" class = "icon-button" type = "button" title = "Search (`/`)" aria-label = "Toggle Searchbar" aria-expanded = "false" aria-keyshortcuts = "/ s" aria-controls = "searchbar" >
< i class = "fa fa-search" > < / i >
< / button >
< / div >
< h1 class = "menu-title" > Provisioning Platform Documentation< / h1 >
< div class = "right-buttons" >
< a href = "../print.html" title = "Print this book" aria-label = "Print this book" >
< i id = "print-button" class = "fa fa-print" > < / i >
< / a >
2026-01-17 03:58:28 +00:00
< a href = "https://github.com/your-org/provisioning" title = "Git repository" aria-label = "Git repository" >
2025-12-11 21:50:42 +00:00
< i id = "git-repository-button" class = "fa fa-github" > < / i >
< / a >
2026-01-17 03:58:28 +00:00
< a href = "https://github.com/your-org/provisioning/edit/main/provisioning/docs/src/guides/from-scratch.md" title = "Suggest an edit" aria-label = "Suggest an edit" >
2025-12-11 21:50:42 +00:00
< i id = "git-edit-button" class = "fa fa-edit" > < / i >
< / a >
< / div >
< / div >
< div id = "search-wrapper" class = "hidden" >
< form id = "searchbar-outer" class = "searchbar-outer" >
< input type = "search" id = "searchbar" name = "searchbar" placeholder = "Search this book ..." aria-controls = "searchresults-outer" aria-describedby = "searchresults-header" >
< / form >
< div id = "searchresults-outer" class = "searchresults-outer hidden" >
< div id = "searchresults-header" class = "searchresults-header" > < / div >
< ul id = "searchresults" >
< / ul >
< / div >
< / div >
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
< script >
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
< / script >
< div id = "content" class = "content" >
< main >
2026-01-17 03:58:28 +00:00
< h1 id = "from-scratch-guide" > < a class = "header" href = "#from-scratch-guide" > From Scratch Guide< / a > < / h1 >
< p > Complete walkthrough from zero to production-ready infrastructure deployment using the Provisioning platform. This guide covers installation, configuration,
workspace setup, infrastructure definition, and deployment workflows.< / p >
< h2 id = "overview" > < a class = "header" href = "#overview" > Overview< / a > < / h2 >
< p > This guide walks you through:< / p >
2025-12-11 21:50:42 +00:00
< ul >
2026-01-17 03:58:28 +00:00
< li > Installing prerequisites and the Provisioning platform< / li >
< li > Configuring cloud provider credentials< / li >
< li > Creating your first workspace< / li >
< li > Defining infrastructure using Nickel< / li >
< li > Deploying servers and task services< / li >
< li > Setting up Kubernetes clusters< / li >
< li > Implementing security best practices< / li >
< li > Monitoring and maintaining infrastructure< / li >
2025-12-11 21:50:42 +00:00
< / ul >
2026-01-17 03:58:28 +00:00
< p > < strong > Time commitment< / strong > : 2-3 hours for complete setup
< strong > Prerequisites< / strong > : Linux or macOS, terminal access, cloud provider account (optional)< / p >
< h2 id = "phase-1-installation" > < a class = "header" href = "#phase-1-installation" > Phase 1: Installation< / a > < / h2 >
< h3 id = "system-prerequisites" > < a class = "header" href = "#system-prerequisites" > System Prerequisites< / a > < / h3 >
< p > Ensure your system meets minimum requirements:< / p >
< pre > < code class = "language-bash" > # Check OS (Linux or macOS)
uname -s
# Verify available disk space (minimum 10GB recommended)
df -h ~
# Check internet connectivity
ping -c 3 github.com
< / code > < / pre >
< h3 id = "install-required-tools" > < a class = "header" href = "#install-required-tools" > Install Required Tools< / a > < / h3 >
< h4 id = "nushell-required" > < a class = "header" href = "#nushell-required" > Nushell (Required)< / a > < / h4 >
< pre > < code class = "language-bash" > # macOS
2025-12-11 21:50:42 +00:00
brew install nushell
2026-01-17 03:58:28 +00:00
# Linux
cargo install nu
2025-12-11 21:50:42 +00:00
# Verify installation
2026-01-17 03:58:28 +00:00
nu --version # Expected: 0.109.1+
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< h4 id = "nickel-required" > < a class = "header" href = "#nickel-required" > Nickel (Required)< / a > < / h4 >
< pre > < code class = "language-bash" > # macOS
brew install nickel
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Linux
cargo install nickel-lang-cli
2025-12-11 21:50:42 +00:00
# Verify installation
2026-01-17 03:58:28 +00:00
nickel --version # Expected: 1.15.1+
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< h4 id = "additional-tools" > < a class = "header" href = "#additional-tools" > Additional Tools< / a > < / h4 >
< pre > < code class = "language-bash" > # SOPS for secrets management
brew install sops # macOS
# or download from [https://github.com/getsops/sops/releases](https://github.com/getsops/sops/releases)
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Age for encryption
brew install age # macOS
cargo install age # Linux
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# K9s for Kubernetes management (optional)
brew install derailed/k9s/k9s
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Verify installations
sops --version # Expected: 3.10.2+
age --version # Expected: 1.2.1+
k9s version # Expected: 0.50.6+
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< h3 id = "install-provisioning-platform" > < a class = "header" href = "#install-provisioning-platform" > Install Provisioning Platform< / a > < / h3 >
< h4 id = "option-1-using-installer-script-recommended" > < a class = "header" href = "#option-1-using-installer-script-recommended" > Option 1: Using Installer Script (Recommended)< / a > < / h4 >
< pre > < code class = "language-bash" > # Download and run installer
INSTALL_URL="https://raw.githubusercontent.com/yourusername/provisioning/main/install.sh"
curl -sSL "$INSTALL_URL" | bash
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Follow prompts to configure installation directory and path
# Default: ~/.local/bin/provisioning
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< p > Installer performs:< / p >
2026-01-12 04:42:18 +00:00
< ul >
2026-01-17 03:58:28 +00:00
< li > Downloads latest platform binaries< / li >
< li > Installs CLI to system PATH< / li >
< li > Creates default configuration structure< / li >
< li > Validates dependencies< / li >
< li > Runs health check< / li >
2026-01-12 04:42:18 +00:00
< / ul >
2026-01-17 03:58:28 +00:00
< h4 id = "option-2-build-from-source" > < a class = "header" href = "#option-2-build-from-source" > Option 2: Build from Source< / a > < / h4 >
< pre > < code class = "language-bash" > # Clone repository
git clone [https://github.com/yourusername/provisioning.git](https://github.com/yourusername/provisioning.git)
cd provisioning
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Build core CLI
cd provisioning/core
cargo build --release
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Install to local bin
cp target/release/provisioning ~/.local/bin/
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Add to PATH (add to ~/.bashrc or ~/.zshrc)
export PATH="$HOME/.local/bin:$PATH"
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Verify installation
provisioning version
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< h3 id = "platform-health-check" > < a class = "header" href = "#platform-health-check" > Platform Health Check< / a > < / h3 >
< pre > < code class = "language-bash" > # Verify installation
provisioning setup check
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Expected output:
# ✓ Nushell 0.109.1 installed
# ✓ Nickel 1.15.1 installed
# ✓ SOPS 3.10.2 installed
# ✓ Age 1.2.1 installed
# ✓ Provisioning CLI installed
# ✓ Configuration directory created
# Platform ready for use
< / code > < / pre >
< h2 id = "phase-2-initial-configuration" > < a class = "header" href = "#phase-2-initial-configuration" > Phase 2: Initial Configuration< / a > < / h2 >
< h3 id = "generate-user-configuration" > < a class = "header" href = "#generate-user-configuration" > Generate User Configuration< / a > < / h3 >
< pre > < code class = "language-bash" > # Create user configuration directory
mkdir -p ~/.config/provisioning
# Generate default user config
provisioning setup init-user-config
< / code > < / pre >
< p > Generated configuration structure:< / p >
< pre > < code class = "language-text" > ~/.config/provisioning/
├── user_config.yaml # User preferences and workspace registry
├── credentials/ # Provider credentials (encrypted)
├── age/ # Age encryption keys
└── cache/ # CLI cache
< / code > < / pre >
< h3 id = "configure-encryption" > < a class = "header" href = "#configure-encryption" > Configure Encryption< / a > < / h3 >
< pre > < code class = "language-bash" > # Generate Age key pair for secrets
age-keygen -o ~/.config/provisioning/age/provisioning.key
# Store public key
age-keygen -y ~/.config/provisioning/age/provisioning.key > ~/.config/provisioning/age/provisioning.pub
# Configure SOPS to use Age
cat > ~/.config/sops/config.yaml < < EOF
creation_rules:
- path_regex: \.secret\.(yam| l tom| l json)$
age: $(cat ~/.config/provisioning/age/provisioning.pub)
EOF
< / code > < / pre >
< h3 id = "provider-credentials" > < a class = "header" href = "#provider-credentials" > Provider Credentials< / a > < / h3 >
< p > Configure credentials for your chosen cloud provider.< / p >
< h4 id = "upcloud-configuration" > < a class = "header" href = "#upcloud-configuration" > UpCloud Configuration< / a > < / h4 >
< pre > < code class = "language-bash" > # Edit user config
nano ~/.config/provisioning/user_config.yaml
# Add provider credentials
cat > > ~/.config/provisioning/user_config.yaml < < EOF
providers:
upcloud:
username: "your-upcloud-username"
password_env: "UPCLOUD_PASSWORD" # Read from environment variable
default_zone: "de-fra1"
EOF
# Set environment variable (add to ~/.bashrc or ~/.zshrc)
export UPCLOUD_PASSWORD="your-upcloud-password"
< / code > < / pre >
< h4 id = "aws-configuration" > < a class = "header" href = "#aws-configuration" > AWS Configuration< / a > < / h4 >
< pre > < code class = "language-bash" > # Add AWS credentials to user config
cat > > ~/.config/provisioning/user_config.yaml < < EOF
providers:
aws:
access_key_id_env: "AWS_ACCESS_KEY_ID"
secret_access_key_env: "AWS_SECRET_ACCESS_KEY"
default_region: "eu-west-1"
EOF
# Set environment variables
export AWS_ACCESS_KEY_ID="your-access-key-id"
export AWS_SECRET_ACCESS_KEY="your-secret-access-key"
< / code > < / pre >
< h4 id = "local-provider-development" > < a class = "header" href = "#local-provider-development" > Local Provider (Development)< / a > < / h4 >
< pre > < code class = "language-bash" > # Configure local provider for testing
cat > > ~/.config/provisioning/user_config.yaml < < EOF
providers:
local:
backend: "docker" # or "podman", "libvirt"
storage_path: "$HOME/.local/share/provisioning/local"
EOF
# Ensure Docker is running
docker info
< / code > < / pre >
< h3 id = "validate-configuration" > < a class = "header" href = "#validate-configuration" > Validate Configuration< / a > < / h3 >
< pre > < code class = "language-bash" > # Validate user configuration
provisioning validate config
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Test provider connectivity
provisioning providers
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Expected output:
# PROVIDER STATUS REGION/ZONE
# upcloud connected de-fra1
# local ready localhost
< / code > < / pre >
< h2 id = "phase-3-create-first-workspace" > < a class = "header" href = "#phase-3-create-first-workspace" > Phase 3: Create First Workspace< / a > < / h2 >
< h3 id = "initialize-workspace" > < a class = "header" href = "#initialize-workspace" > Initialize Workspace< / a > < / h3 >
< pre > < code class = "language-bash" > # Create workspace for first project
provisioning workspace init my-first-project
# Navigate to workspace
cd workspace_my_first_project
# Verify structure
ls -la
< / code > < / pre >
< p > Workspace structure created:< / p >
< pre > < code class = "language-text" > workspace_my_first_project/
├── infra/ # Infrastructure definitions (Nickel)
├── config/ # Workspace configuration
│ ├── provisioning.yaml # Workspace metadata
│ ├── dev-defaults.toml # Development defaults
│ ├── test-defaults.toml # Testing defaults
│ └── prod-defaults.toml # Production defaults
├── extensions/ # Workspace-specific extensions
2026-01-08 09:55:37 +00:00
│ ├── providers/
2026-01-17 03:58:28 +00:00
│ ├── taskservs/
│ └── workflows/
└── runtime/ # State and logs (gitignored)
├── state/
├── checkpoints/
└── logs/
< / code > < / pre >
< h3 id = "configure-workspace" > < a class = "header" href = "#configure-workspace" > Configure Workspace< / a > < / h3 >
< pre > < code class = "language-bash" > # Edit workspace metadata
nano config/provisioning.yaml
< / code > < / pre >
< p > Example workspace configuration:< / p >
< pre > < code class = "language-yaml" > workspace:
name: my-first-project
description: Learning Provisioning platform
environment: development
created: 2026-01-16T10:00:00Z
defaults:
provider: local
region: localhost
confirmation_required: false
versioning:
nushell: "0.109.1"
nickel: "1.15.1"
kubernetes: "1.29.0"
< / code > < / pre >
< h2 id = "phase-4-define-infrastructure" > < a class = "header" href = "#phase-4-define-infrastructure" > Phase 4: Define Infrastructure< / a > < / h2 >
< h3 id = "simple-server-configuration" > < a class = "header" href = "#simple-server-configuration" > Simple Server Configuration< / a > < / h3 >
< p > Create your first infrastructure definition using Nickel:< / p >
< pre > < code class = "language-bash" > # Create server definition
cat > infra/simple-server.ncl < < 'EOF'
{
metadata = {
name = "simple-server"
provider = "local"
environment = 'development
}
infrastructure = {
servers = [
{
name = "dev-web-01"
plan = "small"
zone = "localhost"
disk_size_gb = 25
backup_enabled = false
role = 'standalone
}
]
}
services = {
taskservs = ["containerd"]
}
2026-01-08 09:55:37 +00:00
}
2026-01-17 03:58:28 +00:00
EOF
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< h3 id = "validate-infrastructure-schema" > < a class = "header" href = "#validate-infrastructure-schema" > Validate Infrastructure Schema< / a > < / h3 >
< pre > < code class = "language-bash" > # Type-check Nickel schema
nickel typecheck infra/simple-server.ncl
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Validate against platform contracts
provisioning validate config --infra simple-server
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Preview deployment
provisioning server create --check --infra simple-server
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< p > Expected output:< / p >
< pre > < code class = "language-text" > Infrastructure Plan: simple-server
Provider: local
Environment: development
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
Servers to create:
- dev-web-01 (small, standalone)
Disk: 25 GB
Backup: disabled
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
Task services:
- containerd
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
Estimated resources:
CPU: 1 core
RAM: 1 GB
Disk: 25 GB
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
Validation: PASSED
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< h3 id = "deploy-infrastructure" > < a class = "header" href = "#deploy-infrastructure" > Deploy Infrastructure< / a > < / h3 >
< pre > < code class = "language-bash" > # Create server
provisioning server create --infra simple-server --yes
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Monitor deployment
provisioning server status dev-web-01
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< p > Deployment progress:< / p >
< pre > < code class = "language-text" > Creating server: dev-web-01...
[████████████████████████] 100% - Container created
[████████████████████████] 100% - Network configured
[████████████████████████] 100% - SSH ready
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
Server dev-web-01 created successfully
IP Address: 172.17.0.2
Status: running
Provider: local (docker)
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< h3 id = "install-task-service" > < a class = "header" href = "#install-task-service" > Install Task Service< / a > < / h3 >
< pre > < code class = "language-bash" > # Install containerd
provisioning taskserv create containerd --infra simple-server
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Verify installation
provisioning taskserv status containerd
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< p > Installation output:< / p >
< pre > < code class = "language-text" > Installing containerd on dev-web-01...
[████████████████████████] 100% - Dependencies resolved
[████████████████████████] 100% - Containerd installed
[████████████████████████] 100% - Service started
[████████████████████████] 100% - Health check passed
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
Containerd installed successfully
Version: 1.7.0
Runtime: runc
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< h3 id = "verify-deployment" > < a class = "header" href = "#verify-deployment" > Verify Deployment< / a > < / h3 >
< pre > < code class = "language-bash" > # SSH into server
provisioning server ssh dev-web-01
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Inside server - verify containerd
sudo systemctl status containerd
sudo ctr version
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Exit server
exit
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# List all resources
provisioning server list
provisioning taskserv list
< / code > < / pre >
< h2 id = "phase-5-kubernetes-cluster-deployment" > < a class = "header" href = "#phase-5-kubernetes-cluster-deployment" > Phase 5: Kubernetes Cluster Deployment< / a > < / h2 >
< h3 id = "define-kubernetes-infrastructure" > < a class = "header" href = "#define-kubernetes-infrastructure" > Define Kubernetes Infrastructure< / a > < / h3 >
< pre > < code class = "language-bash" > # Create Kubernetes cluster definition
cat > infra/k8s-cluster.ncl < < 'EOF'
{
metadata = {
name = "k8s-dev-cluster"
provider = "local"
environment = 'development
}
infrastructure = {
servers = [
{
name = "k8s-control-01"
plan = "medium"
role = 'control
zone = "localhost"
disk_size_gb = 50
}
{
name = "k8s-worker-01"
plan = "medium"
role = 'worker
zone = "localhost"
disk_size_gb = 50
}
{
name = "k8s-worker-02"
plan = "medium"
role = 'worker
zone = "localhost"
disk_size_gb = 50
}
]
}
services = {
taskservs = ["containerd", "etcd", "kubernetes", "cilium"]
}
kubernetes = {
version = "1.29.0"
pod_cidr = "10.244.0.0/16"
service_cidr = "10.96.0.0/12"
container_runtime = "containerd"
cri_socket = "/run/containerd/containerd.sock"
}
}
EOF
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< h3 id = "validate-kubernetes-configuration" > < a class = "header" href = "#validate-kubernetes-configuration" > Validate Kubernetes Configuration< / a > < / h3 >
< pre > < code class = "language-bash" > # Type-check schema
nickel typecheck infra/k8s-cluster.ncl
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Validate configuration
provisioning validate config --infra k8s-cluster
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Preview deployment
provisioning cluster create --check --infra k8s-cluster
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< h3 id = "deploy-kubernetes-cluster" > < a class = "header" href = "#deploy-kubernetes-cluster" > Deploy Kubernetes Cluster< / a > < / h3 >
< pre > < code class = "language-bash" > # Create cluster infrastructure
provisioning cluster create --infra k8s-cluster --yes
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Monitor cluster deployment
provisioning cluster status k8s-dev-cluster
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< p > Cluster deployment phases:< / p >
< pre > < code class = "language-text" > Phase 1: Creating servers...
[████████████████████████] 100% - 3/3 servers created
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
Phase 2: Installing containerd...
[████████████████████████] 100% - 3/3 nodes ready
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
Phase 3: Installing etcd...
[████████████████████████] 100% - Control plane ready
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
Phase 4: Installing Kubernetes...
[████████████████████████] 100% - API server available
[████████████████████████] 100% - Workers joined
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
Phase 5: Installing Cilium CNI...
[████████████████████████] 100% - Network ready
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
Kubernetes cluster deployed successfully
Cluster: k8s-dev-cluster
Control plane: k8s-control-01
Workers: k8s-worker-01, k8s-worker-02
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< h3 id = "access-kubernetes-cluster" > < a class = "header" href = "#access-kubernetes-cluster" > Access Kubernetes Cluster< / a > < / h3 >
< pre > < code class = "language-bash" > # Get kubeconfig
provisioning cluster kubeconfig k8s-dev-cluster > ~/.kube/config-dev
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Set KUBECONFIG
export KUBECONFIG=~/.kube/config-dev
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Verify cluster
2025-12-11 21:50:42 +00:00
kubectl get nodes
2026-01-17 03:58:28 +00:00
# Expected output:
# NAME STATUS ROLES AGE VERSION
# k8s-control-01 Ready control-plane 5m v1.29.0
# k8s-worker-01 Ready < none> 4m v1.29.0
# k8s-worker-02 Ready < none> 4m v1.29.0
# Use K9s for interactive management
k9s
< / code > < / pre >
< h2 id = "phase-6-security-configuration" > < a class = "header" href = "#phase-6-security-configuration" > Phase 6: Security Configuration< / a > < / h2 >
< h3 id = "enable-audit-logging" > < a class = "header" href = "#enable-audit-logging" > Enable Audit Logging< / a > < / h3 >
< pre > < code class = "language-bash" > # Configure audit logging
cat > config/audit-config.toml < < EOF
[audit]
enabled = true
log_path = "runtime/logs/audit"
retention_days = 90
level = "info"
[audit.filters]
include_commands = ["server create", "server delete", "cluster deploy"]
exclude_users = []
EOF
< / code > < / pre >
< h3 id = "configure-sops-for-secrets" > < a class = "header" href = "#configure-sops-for-secrets" > Configure SOPS for Secrets< / a > < / h3 >
< pre > < code class = "language-bash" > # Create secrets file
cat > config/secrets.secret.yaml < < EOF
database:
password: "changeme-db-password"
admin_user: "admin"
kubernetes:
service_account_key: "changeme-sa-key"
EOF
# Encrypt secrets with SOPS
sops -e -i config/secrets.secret.yaml
# Verify encryption
cat config/secrets.secret.yaml # Should show encrypted content
# Decrypt when needed
sops -d config/secrets.secret.yaml
< / code > < / pre >
< h3 id = "enable-mfa-optional" > < a class = "header" href = "#enable-mfa-optional" > Enable MFA (Optional)< / a > < / h3 >
< pre > < code class = "language-bash" > # Enable multi-factor authentication
provisioning security mfa enable
# Scan QR code with authenticator app
# Enter verification code
< / code > < / pre >
< h3 id = "configure-rbac" > < a class = "header" href = "#configure-rbac" > Configure RBAC< / a > < / h3 >
< pre > < code class = "language-bash" > # Create role definition
cat > config/rbac-roles.yaml < < EOF
roles:
- name: developer
permissions:
- server:read
- server:create
- taskserv:read
- taskserv:install
deny:
- cluster:delete
- config:modify
- name: operator
permissions:
- "*:read"
- server:*
- taskserv:*
- cluster:read
- cluster:deploy
- name: admin
permissions:
- "*:*"
EOF
< / code > < / pre >
< h2 id = "phase-7-multi-cloud-deployment" > < a class = "header" href = "#phase-7-multi-cloud-deployment" > Phase 7: Multi-Cloud Deployment< / a > < / h2 >
< h3 id = "define-multi-cloud-infrastructure" > < a class = "header" href = "#define-multi-cloud-infrastructure" > Define Multi-Cloud Infrastructure< / a > < / h3 >
< pre > < code class = "language-bash" > # Create multi-cloud definition
cat > infra/multi-cloud.ncl < < 'EOF'
{
batch_workflow = {
operations = [
{
id = "upcloud-frontend"
provider = "upcloud"
region = "de-fra1"
servers = [
{name = "upcloud-web-01", plan = "medium", role = 'web}
]
taskservs = ["containerd", "nginx"]
}
{
id = "aws-backend"
provider = "aws"
region = "eu-west-1"
servers = [
{name = "aws-api-01", plan = "t3.medium", role = 'api}
]
taskservs = ["containerd", "docker"]
dependencies = ["upcloud-frontend"]
}
{
id = "local-database"
provider = "local"
region = "localhost"
servers = [
{name = "local-db-01", plan = "large", role = 'database}
]
taskservs = ["postgresql"]
}
]
parallel_limit = 2
}
}
EOF
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< h3 id = "deploy-multi-cloud-infrastructure" > < a class = "header" href = "#deploy-multi-cloud-infrastructure" > Deploy Multi-Cloud Infrastructure< / a > < / h3 >
< pre > < code class = "language-bash" > # Submit batch workflow
provisioning batch submit infra/multi-cloud.ncl
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Monitor workflow progress
provisioning batch status
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# View detailed operation status
provisioning batch operations
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< h2 id = "phase-8-monitoring-and-maintenance" > < a class = "header" href = "#phase-8-monitoring-and-maintenance" > Phase 8: Monitoring and Maintenance< / a > < / h2 >
< h3 id = "platform-health-monitoring" > < a class = "header" href = "#platform-health-monitoring" > Platform Health Monitoring< / a > < / h3 >
< pre > < code class = "language-bash" > # Check platform health
provisioning health
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# View service status
provisioning service status orchestrator
provisioning service status control-center
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# View logs
provisioning logs --service orchestrator --tail 100
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< h3 id = "infrastructure-monitoring" > < a class = "header" href = "#infrastructure-monitoring" > Infrastructure Monitoring< / a > < / h3 >
< pre > < code class = "language-bash" > # List all servers
provisioning server list --all-workspaces
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Show server details
provisioning server info k8s-control-01
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Check task service status
provisioning taskserv list
provisioning taskserv health containerd
2026-01-12 04:42:18 +00:00
< / code > < / pre >
< h3 id = "backup-configuration" > < a class = "header" href = "#backup-configuration" > Backup Configuration< / a > < / h3 >
2026-01-17 03:58:28 +00:00
< pre > < code class = "language-bash" > # Create backup
provisioning backup create --type full --output ~/backups/provisioning-$(date +%Y%m%d).tar.gz
# Schedule automatic backups
provisioning backup schedule daily --time "02:00" --retention 7
< / code > < / pre >
< h2 id = "phase-9-advanced-workflows" > < a class = "header" href = "#phase-9-advanced-workflows" > Phase 9: Advanced Workflows< / a > < / h2 >
< h3 id = "custom-workflow-creation" > < a class = "header" href = "#custom-workflow-creation" > Custom Workflow Creation< / a > < / h3 >
< pre > < code class = "language-bash" > # Create custom workflow
cat > extensions/workflows/deploy-app.ncl < < 'EOF'
{
workflow = {
name = "deploy-application"
description = "Deploy application to Kubernetes"
steps = [
{
name = "build-image"
action = "docker-build"
params = {dockerfile = "Dockerfile", tag = "myapp:latest"}
}
{
name = "push-image"
action = "docker-push"
params = {image = "myapp:latest", registry = "registry.example.com"}
depends_on = ["build-image"]
}
{
name = "deploy-k8s"
action = "kubectl-apply"
params = {manifest = "k8s/deployment.yaml"}
depends_on = ["push-image"]
}
{
name = "verify-deployment"
action = "kubectl-rollout-status"
params = {deployment = "myapp"}
depends_on = ["deploy-k8s"]
}
]
}
}
EOF
< / code > < / pre >
< h3 id = "execute-custom-workflow" > < a class = "header" href = "#execute-custom-workflow" > Execute Custom Workflow< / a > < / h3 >
< pre > < code class = "language-bash" > # Run workflow
provisioning workflow run deploy-application
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Monitor workflow
provisioning workflow status deploy-application
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# View workflow history
provisioning workflow history
2026-01-12 04:42:18 +00:00
< / code > < / pre >
< h2 id = "troubleshooting" > < a class = "header" href = "#troubleshooting" > Troubleshooting< / a > < / h2 >
2026-01-17 03:58:28 +00:00
< h3 id = "common-issues" > < a class = "header" href = "#common-issues" > Common Issues< / a > < / h3 >
< h4 id = "server-creation-fails" > < a class = "header" href = "#server-creation-fails" > Server Creation Fails< / a > < / h4 >
< pre > < code class = "language-bash" > # Enable debug logging
provisioning --debug server create --infra simple-server
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Check provider connectivity
provisioning providers
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Validate credentials
provisioning validate config
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< h4 id = "task-service-installation-fails" > < a class = "header" href = "#task-service-installation-fails" > Task Service Installation Fails< / a > < / h4 >
2026-01-12 04:42:18 +00:00
< pre > < code class = "language-bash" > # Check server connectivity
2026-01-17 03:58:28 +00:00
provisioning server ssh dev-web-01
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Verify dependencies
provisioning taskserv check-deps containerd
2025-12-11 21:50:42 +00:00
# Retry installation
2026-01-17 03:58:28 +00:00
provisioning taskserv create containerd --force
2026-01-12 04:42:18 +00:00
< / code > < / pre >
2026-01-17 03:58:28 +00:00
< h4 id = "cluster-deployment-fails" > < a class = "header" href = "#cluster-deployment-fails" > Cluster Deployment Fails< / a > < / h4 >
< pre > < code class = "language-bash" > # Check cluster status
provisioning cluster status k8s-dev-cluster
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# View cluster logs
provisioning cluster logs k8s-dev-cluster
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
# Reset and retry
provisioning cluster reset k8s-dev-cluster
provisioning cluster create --infra k8s-cluster
2026-01-12 04:42:18 +00:00
< / code > < / pre >
< h2 id = "next-steps" > < a class = "header" href = "#next-steps" > Next Steps< / a > < / h2 >
2026-01-17 03:58:28 +00:00
< h3 id = "production-deployment" > < a class = "header" href = "#production-deployment" > Production Deployment< / a > < / h3 >
2025-12-11 21:50:42 +00:00
< ul >
2026-01-17 03:58:28 +00:00
< li > Review < a href = "../security/README.html" > Security Best Practices< / a > < / li >
< li > Configure < a href = "../operations/backup-recovery.html" > Backup & Recovery< / a > < / li >
< li > Set up < a href = "../operations/monitoring.html" > Monitoring< / a > < / li >
< li > Implement < a href = "disaster-recovery.html" > Disaster Recovery< / a > < / li >
< / ul >
< h3 id = "advanced-features" > < a class = "header" href = "#advanced-features" > Advanced Features< / a > < / h3 >
< ul >
< li > Explore < a href = "../infrastructure/batch-workflows.html" > Batch Workflows< / a > < / li >
< li > Configure < a href = "../features/orchestrator.html" > Orchestrator< / a > < / li >
< li > Use < a href = "../features/interactive-guides.html" > Interactive Guides< / a > < / li >
< li > Develop < a href = "custom-extensions.html" > Custom Extensions< / a > < / li >
< / ul >
< h3 id = "learning-resources" > < a class = "header" href = "#learning-resources" > Learning Resources< / a > < / h3 >
< ul >
< li > < a href = "../infrastructure/nickel-guide.html" > Nickel Guide< / a > - Infrastructure as code< / li >
< li > < a href = "workspace-management.html" > Workspace Management< / a > - Advanced workspace usage< / li >
< li > < a href = "multi-cloud-deployment.html" > Multi-Cloud Deployment< / a > - Multi-cloud strategies< / li >
< li > < a href = "../api-reference/README.html" > API Reference< / a > - Complete API documentation< / li >
2025-12-11 21:50:42 +00:00
< / ul >
2026-01-12 04:42:18 +00:00
< h2 id = "summary" > < a class = "header" href = "#summary" > Summary< / a > < / h2 >
2026-01-17 03:58:28 +00:00
< p > You’ ve completed the from-scratch guide and learned:< / p >
< ul >
< li > Platform installation and configuration< / li >
< li > Provider credential setup< / li >
< li > Workspace creation and management< / li >
< li > Infrastructure definition with Nickel< / li >
< li > Server and task service deployment< / li >
< li > Kubernetes cluster deployment< / li >
< li > Security configuration< / li >
< li > Multi-cloud deployment< / li >
< li > Monitoring and maintenance< / li >
< li > Custom workflow creation< / li >
< / ul >
< p > Your Provisioning platform is now ready for production use.< / p >
2025-12-11 21:50:42 +00:00
< / main >
< nav class = "nav-wrapper" aria-label = "Page navigation" >
<!-- Mobile navigation buttons -->
2026-01-17 03:58:28 +00:00
< a rel = "prev" href = "../guides/index.html" class = "mobile-nav-chapters previous" title = "Previous chapter" aria-label = "Previous chapter" aria-keyshortcuts = "Left" >
2025-12-11 21:50:42 +00:00
< i class = "fa fa-angle-left" > < / i >
< / a >
2026-01-17 03:58:28 +00:00
< a rel = "next prefetch" href = "../guides/workspace-management.html" class = "mobile-nav-chapters next" title = "Next chapter" aria-label = "Next chapter" aria-keyshortcuts = "Right" >
2025-12-11 21:50:42 +00:00
< i class = "fa fa-angle-right" > < / i >
< / a >
< div style = "clear: both" > < / div >
< / nav >
< / div >
< / div >
< nav class = "nav-wide-wrapper" aria-label = "Page navigation" >
2026-01-17 03:58:28 +00:00
< a rel = "prev" href = "../guides/index.html" class = "nav-chapters previous" title = "Previous chapter" aria-label = "Previous chapter" aria-keyshortcuts = "Left" >
2025-12-11 21:50:42 +00:00
< i class = "fa fa-angle-left" > < / i >
< / a >
2026-01-17 03:58:28 +00:00
< a rel = "next prefetch" href = "../guides/workspace-management.html" class = "nav-chapters next" title = "Next chapter" aria-label = "Next chapter" aria-keyshortcuts = "Right" >
2025-12-11 21:50:42 +00:00
< i class = "fa fa-angle-right" > < / i >
< / a >
< / nav >
< / div >
2026-01-17 03:58:28 +00:00
<!-- Livereload script (if served using the cli tool) -->
< script >
const wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
const wsAddress = wsProtocol + "//" + location.host + "/" + "__livereload";
const socket = new WebSocket(wsAddress);
socket.onmessage = function (event) {
if (event.data === "reload") {
socket.close();
location.reload();
}
};
window.onbeforeunload = function() {
socket.close();
}
< / script >
2025-12-11 21:50:42 +00:00
2026-01-17 03:58:28 +00:00
< script >
window.playground_line_numbers = true;
< / script >
2025-12-11 21:50:42 +00:00
< script >
window.playground_copyable = true;
< / script >
2026-01-17 03:58:28 +00:00
< script src = "../ace.js" > < / script >
< script src = "../mode-rust.js" > < / script >
< script src = "../editor.js" > < / script >
< script src = "../theme-dawn.js" > < / script >
< script src = "../theme-tomorrow_night.js" > < / script >
2025-12-11 21:50:42 +00:00
< script src = "../elasticlunr.min.js" > < / script >
< script src = "../mark.min.js" > < / script >
< script src = "../searcher.js" > < / script >
< script src = "../clipboard.min.js" > < / script >
< script src = "../highlight.js" > < / script >
< script src = "../book.js" > < / script >
<!-- Custom JS scripts -->
< / div >
< / body >
< / html >