provisioning/docs/book/guides/from-scratch.html

989 lines
38 KiB
HTML
Raw Permalink Normal View History

<!DOCTYPE HTML>
2026-01-17 03:58:28 +00:00
<html lang="en" class="rust sidebar-visible" dir="ltr">
<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>
<!-- Custom HTML head -->
2026-01-17 03:58:28 +00:00
<meta name="description" content="Enterprise-grade Infrastructure as Code platform - Complete documentation">
<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";
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')
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">
<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">
<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>
<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>
</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
brew install nushell
2026-01-17 03:58:28 +00:00
# Linux
cargo install nu
# 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
2026-01-17 03:58:28 +00:00
# Linux
cargo install nickel-lang-cli
# 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)
2026-01-17 03:58:28 +00:00
# Age for encryption
brew install age # macOS
cargo install age # Linux
2026-01-17 03:58:28 +00:00
# K9s for Kubernetes management (optional)
brew install derailed/k9s/k9s
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
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
2026-01-17 03:58:28 +00:00
# Build core CLI
cd provisioning/core
cargo build --release
2026-01-17 03:58:28 +00:00
# Install to local bin
cp target/release/provisioning ~/.local/bin/
2026-01-17 03:58:28 +00:00
# Add to PATH (add to ~/.bashrc or ~/.zshrc)
export PATH="$HOME/.local/bin:$PATH"
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
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 &gt; ~/.config/provisioning/age/provisioning.pub
# Configure SOPS to use Age
cat &gt; ~/.config/sops/config.yaml &lt;&lt;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 &gt;&gt; ~/.config/provisioning/user_config.yaml &lt;&lt;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 &gt;&gt; ~/.config/provisioning/user_config.yaml &lt;&lt;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 &gt;&gt; ~/.config/provisioning/user_config.yaml &lt;&lt;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
2026-01-17 03:58:28 +00:00
# Test provider connectivity
provisioning providers
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
│ ├── 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 &gt; infra/simple-server.ncl &lt;&lt;'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-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
2026-01-17 03:58:28 +00:00
# Validate against platform contracts
provisioning validate config --infra simple-server
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
2026-01-17 03:58:28 +00:00
Servers to create:
- dev-web-01 (small, standalone)
Disk: 25 GB
Backup: disabled
2026-01-17 03:58:28 +00:00
Task services:
- containerd
2026-01-17 03:58:28 +00:00
Estimated resources:
CPU: 1 core
RAM: 1 GB
Disk: 25 GB
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
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
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
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
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
2026-01-17 03:58:28 +00:00
# Inside server - verify containerd
sudo systemctl status containerd
sudo ctr version
2026-01-17 03:58:28 +00:00
# Exit server
exit
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 &gt; infra/k8s-cluster.ncl &lt;&lt;'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
2026-01-17 03:58:28 +00:00
# Validate configuration
provisioning validate config --infra k8s-cluster
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
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
2026-01-17 03:58:28 +00:00
Phase 2: Installing containerd...
[████████████████████████] 100% - 3/3 nodes ready
2026-01-17 03:58:28 +00:00
Phase 3: Installing etcd...
[████████████████████████] 100% - Control plane ready
2026-01-17 03:58:28 +00:00
Phase 4: Installing Kubernetes...
[████████████████████████] 100% - API server available
[████████████████████████] 100% - Workers joined
2026-01-17 03:58:28 +00:00
Phase 5: Installing Cilium CNI...
[████████████████████████] 100% - Network ready
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 &gt; ~/.kube/config-dev
2026-01-17 03:58:28 +00:00
# Set KUBECONFIG
export KUBECONFIG=~/.kube/config-dev
2026-01-17 03:58:28 +00:00
# Verify cluster
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 &lt;none&gt; 4m v1.29.0
# k8s-worker-02 Ready &lt;none&gt; 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 &gt; config/audit-config.toml &lt;&lt;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 &gt; config/secrets.secret.yaml &lt;&lt;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 &gt; config/rbac-roles.yaml &lt;&lt;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 &gt; infra/multi-cloud.ncl &lt;&lt;'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
2026-01-17 03:58:28 +00:00
# Monitor workflow progress
provisioning batch status
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
2026-01-17 03:58:28 +00:00
# View service status
provisioning service status orchestrator
provisioning service status control-center
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
2026-01-17 03:58:28 +00:00
# Show server details
provisioning server info k8s-control-01
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 &gt; extensions/workflows/deploy-app.ncl &lt;&lt;'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
2026-01-17 03:58:28 +00:00
# Monitor workflow
provisioning workflow status deploy-application
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
2026-01-17 03:58:28 +00:00
# Check provider connectivity
provisioning providers
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
2026-01-17 03:58:28 +00:00
# Verify dependencies
provisioning taskserv check-deps containerd
# 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
2026-01-17 03:58:28 +00:00
# View cluster logs
provisioning cluster logs k8s-dev-cluster
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>
<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 &amp; 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>
</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>Youve 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>
</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">
<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">
<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">
<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">
<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>
2026-01-17 03:58:28 +00:00
<script>
window.playground_line_numbers = true;
</script>
<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>
<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>