provisioning/docs/book/guides/from-scratch.html
2026-01-17 03:58:28 +00:00

989 lines
38 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE HTML>
<html lang="en" class="rust sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>From Scratch Guide - Provisioning Platform Documentation</title>
<!-- Custom HTML head -->
<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 = "../";
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;
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>
<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>
<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>
<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>
<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>
<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
# Linux
cargo install nu
# Verify installation
nu --version # Expected: 0.109.1+
</code></pre>
<h4 id="nickel-required"><a class="header" href="#nickel-required">Nickel (Required)</a></h4>
<pre><code class="language-bash"># macOS
brew install nickel
# Linux
cargo install nickel-lang-cli
# Verify installation
nickel --version # Expected: 1.15.1+
</code></pre>
<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)
# Age for encryption
brew install age # macOS
cargo install age # Linux
# K9s for Kubernetes management (optional)
brew install derailed/k9s/k9s
# Verify installations
sops --version # Expected: 3.10.2+
age --version # Expected: 1.2.1+
k9s version # Expected: 0.50.6+
</code></pre>
<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
# Follow prompts to configure installation directory and path
# Default: ~/.local/bin/provisioning
</code></pre>
<p>Installer performs:</p>
<ul>
<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>
</ul>
<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
# Build core CLI
cd provisioning/core
cargo build --release
# Install to local bin
cp target/release/provisioning ~/.local/bin/
# Add to PATH (add to ~/.bashrc or ~/.zshrc)
export PATH="$HOME/.local/bin:$PATH"
# Verify installation
provisioning version
</code></pre>
<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
# 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
# Test provider connectivity
provisioning providers
# 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/
│ ├── 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"]
}
}
EOF
</code></pre>
<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
# Validate against platform contracts
provisioning validate config --infra simple-server
# Preview deployment
provisioning server create --check --infra simple-server
</code></pre>
<p>Expected output:</p>
<pre><code class="language-text">Infrastructure Plan: simple-server
Provider: local
Environment: development
Servers to create:
- dev-web-01 (small, standalone)
Disk: 25 GB
Backup: disabled
Task services:
- containerd
Estimated resources:
CPU: 1 core
RAM: 1 GB
Disk: 25 GB
Validation: PASSED
</code></pre>
<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
# Monitor deployment
provisioning server status dev-web-01
</code></pre>
<p>Deployment progress:</p>
<pre><code class="language-text">Creating server: dev-web-01...
[████████████████████████] 100% - Container created
[████████████████████████] 100% - Network configured
[████████████████████████] 100% - SSH ready
Server dev-web-01 created successfully
IP Address: 172.17.0.2
Status: running
Provider: local (docker)
</code></pre>
<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
# Verify installation
provisioning taskserv status containerd
</code></pre>
<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
Containerd installed successfully
Version: 1.7.0
Runtime: runc
</code></pre>
<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
# Inside server - verify containerd
sudo systemctl status containerd
sudo ctr version
# Exit server
exit
# 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
</code></pre>
<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
# Validate configuration
provisioning validate config --infra k8s-cluster
# Preview deployment
provisioning cluster create --check --infra k8s-cluster
</code></pre>
<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
# Monitor cluster deployment
provisioning cluster status k8s-dev-cluster
</code></pre>
<p>Cluster deployment phases:</p>
<pre><code class="language-text">Phase 1: Creating servers...
[████████████████████████] 100% - 3/3 servers created
Phase 2: Installing containerd...
[████████████████████████] 100% - 3/3 nodes ready
Phase 3: Installing etcd...
[████████████████████████] 100% - Control plane ready
Phase 4: Installing Kubernetes...
[████████████████████████] 100% - API server available
[████████████████████████] 100% - Workers joined
Phase 5: Installing Cilium CNI...
[████████████████████████] 100% - Network ready
Kubernetes cluster deployed successfully
Cluster: k8s-dev-cluster
Control plane: k8s-control-01
Workers: k8s-worker-01, k8s-worker-02
</code></pre>
<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
# Set KUBECONFIG
export KUBECONFIG=~/.kube/config-dev
# Verify cluster
kubectl get nodes
# 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
</code></pre>
<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
# Monitor workflow progress
provisioning batch status
# View detailed operation status
provisioning batch operations
</code></pre>
<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
# View service status
provisioning service status orchestrator
provisioning service status control-center
# View logs
provisioning logs --service orchestrator --tail 100
</code></pre>
<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
# Show server details
provisioning server info k8s-control-01
# Check task service status
provisioning taskserv list
provisioning taskserv health containerd
</code></pre>
<h3 id="backup-configuration"><a class="header" href="#backup-configuration">Backup Configuration</a></h3>
<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
# Monitor workflow
provisioning workflow status deploy-application
# View workflow history
provisioning workflow history
</code></pre>
<h2 id="troubleshooting"><a class="header" href="#troubleshooting">Troubleshooting</a></h2>
<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
# Check provider connectivity
provisioning providers
# Validate credentials
provisioning validate config
</code></pre>
<h4 id="task-service-installation-fails"><a class="header" href="#task-service-installation-fails">Task Service Installation Fails</a></h4>
<pre><code class="language-bash"># Check server connectivity
provisioning server ssh dev-web-01
# Verify dependencies
provisioning taskserv check-deps containerd
# Retry installation
provisioning taskserv create containerd --force
</code></pre>
<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
# View cluster logs
provisioning cluster logs k8s-dev-cluster
# Reset and retry
provisioning cluster reset k8s-dev-cluster
provisioning cluster create --infra k8s-cluster
</code></pre>
<h2 id="next-steps"><a class="header" href="#next-steps">Next Steps</a></h2>
<h3 id="production-deployment"><a class="header" href="#production-deployment">Production Deployment</a></h3>
<ul>
<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>
<h2 id="summary"><a class="header" href="#summary">Summary</a></h2>
<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 -->
<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>
<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">
<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>
<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>
<!-- 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>
<script>
window.playground_line_numbers = true;
</script>
<script>
window.playground_copyable = true;
</script>
<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>