provisioning/docs/book/guides/update-infrastructure.html

1063 lines
29 KiB
HTML
Raw Normal View History

<!DOCTYPE HTML>
<html lang="en" class="ayu sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Update Infrastructure - Provisioning Platform Documentation</title>
<!-- Custom HTML head -->
<meta name="description" content="Complete documentation for the Provisioning Platform - Infrastructure automation with Nushell, KCL, and Rust">
<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 = "ayu";
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('ayu')
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/provisioning/provisioning-platform" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://github.com/provisioning/provisioning-platform/edit/main/provisioning/docs/src/guides/update-infrastructure.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="update-existing-infrastructure"><a class="header" href="#update-existing-infrastructure">Update Existing Infrastructure</a></h1>
<p><strong>Goal</strong>: Safely update running infrastructure with minimal downtime
<strong>Time</strong>: 15-30 minutes
<strong>Difficulty</strong>: Intermediate</p>
<h2 id="overview"><a class="header" href="#overview">Overview</a></h2>
<p>This guide covers:</p>
<ol>
<li>Checking for updates</li>
<li>Planning update strategies</li>
<li>Updating task services</li>
<li>Rolling updates</li>
<li>Rollback procedures</li>
<li>Verification</li>
</ol>
<h2 id="update-strategies"><a class="header" href="#update-strategies">Update Strategies</a></h2>
<h3 id="strategy-1-in-place-updates-fastest"><a class="header" href="#strategy-1-in-place-updates-fastest">Strategy 1: In-Place Updates (Fastest)</a></h3>
<p><strong>Best for</strong>: Non-critical environments, development, staging</p>
<pre><code class="language-bash"># Direct update without downtime consideration
provisioning t create &lt;taskserv&gt; --infra &lt;project&gt;
```plaintext
### Strategy 2: Rolling Updates (Recommended)
**Best for**: Production environments, high availability
```bash
# Update servers one by one
provisioning s update --infra &lt;project&gt; --rolling
```plaintext
### Strategy 3: Blue-Green Deployment (Safest)
**Best for**: Critical production, zero-downtime requirements
```bash
# Create new infrastructure, switch traffic, remove old
provisioning ws init &lt;project&gt;-green
# ... configure and deploy
# ... switch traffic
provisioning ws delete &lt;project&gt;-blue
```plaintext
## Step 1: Check for Updates
### 1.1 Check All Task Services
```bash
# Check all taskservs for updates
provisioning t check-updates
```plaintext
**Expected Output:**
```plaintext
📦 Task Service Update Check:
NAME CURRENT LATEST STATUS
kubernetes 1.29.0 1.30.0 ⬆️ update available
containerd 1.7.13 1.7.13 ✅ up-to-date
cilium 1.14.5 1.15.0 ⬆️ update available
postgres 15.5 16.1 ⬆️ update available
redis 7.2.3 7.2.3 ✅ up-to-date
Updates available: 3
```plaintext
### 1.2 Check Specific Task Service
```bash
# Check specific taskserv
provisioning t check-updates kubernetes
```plaintext
**Expected Output:**
```plaintext
📦 Kubernetes Update Check:
Current: 1.29.0
Latest: 1.30.0
Status: ⬆️ Update available
Changelog:
• Enhanced security features
• Performance improvements
• Bug fixes in kube-apiserver
• New workload resource types
Breaking Changes:
• None
Recommended: ✅ Safe to update
```plaintext
### 1.3 Check Version Status
```bash
# Show detailed version information
provisioning version show
```plaintext
**Expected Output:**
```plaintext
📋 Component Versions:
COMPONENT CURRENT LATEST DAYS OLD STATUS
kubernetes 1.29.0 1.30.0 45 ⬆️ update
containerd 1.7.13 1.7.13 0 ✅ current
cilium 1.14.5 1.15.0 30 ⬆️ update
postgres 15.5 16.1 60 ⬆️ update (major)
redis 7.2.3 7.2.3 0 ✅ current
```plaintext
### 1.4 Check for Security Updates
```bash
# Check for security-related updates
provisioning version updates --security-only
```plaintext
## Step 2: Plan Your Update
### 2.1 Review Current Configuration
```bash
# Show current infrastructure
provisioning show settings --infra my-production
```plaintext
### 2.2 Backup Configuration
```bash
# Create configuration backup
cp -r workspace/infra/my-production workspace/infra/my-production.backup-$(date +%Y%m%d)
# Or use built-in backup
provisioning ws backup my-production
```plaintext
**Expected Output:**
```plaintext
✅ Backup created: workspace/backups/my-production-20250930.tar.gz
```plaintext
### 2.3 Create Update Plan
```bash
# Generate update plan
provisioning plan update --infra my-production
```plaintext
**Expected Output:**
```plaintext
📝 Update Plan for my-production:
Phase 1: Minor Updates (Low Risk)
• containerd: No update needed
• redis: No update needed
Phase 2: Patch Updates (Medium Risk)
• cilium: 1.14.5 → 1.15.0 (estimated 5 minutes)
Phase 3: Major Updates (High Risk - Requires Testing)
• kubernetes: 1.29.0 → 1.30.0 (estimated 15 minutes)
• postgres: 15.5 → 16.1 (estimated 10 minutes, may require data migration)
Recommended Order:
1. Update cilium (low risk)
2. Update kubernetes (test in staging first)
3. Update postgres (requires maintenance window)
Total Estimated Time: 30 minutes
Recommended: Test in staging environment first
```plaintext
## Step 3: Update Task Services
### 3.1 Update Non-Critical Service (Cilium Example)
#### Dry-Run Update
```bash
# Test update without applying
provisioning t create cilium --infra my-production --check
```plaintext
**Expected Output:**
```plaintext
🔍 CHECK MODE: Simulating Cilium update
Current: 1.14.5
Target: 1.15.0
Would perform:
1. Download Cilium 1.15.0
2. Update configuration
3. Rolling restart of Cilium pods
4. Verify connectivity
Estimated downtime: &lt;1 minute per node
No errors detected. Ready to update.
```plaintext
#### Generate Updated Configuration
```bash
# Generate new configuration
provisioning t generate cilium --infra my-production
```plaintext
**Expected Output:**
```plaintext
✅ Generated Cilium configuration (version 1.15.0)
Saved to: workspace/infra/my-production/taskservs/cilium.k
```plaintext
#### Apply Update
```bash
# Apply update
provisioning t create cilium --infra my-production
```plaintext
**Expected Output:**
```plaintext
🚀 Updating Cilium on my-production...
Downloading Cilium 1.15.0... ⏳
✅ Downloaded
Updating configuration... ⏳
✅ Configuration updated
Rolling restart: web-01... ⏳
✅ web-01 updated (Cilium 1.15.0)
Rolling restart: web-02... ⏳
✅ web-02 updated (Cilium 1.15.0)
Verifying connectivity... ⏳
✅ All nodes connected
🎉 Cilium update complete!
Version: 1.14.5 → 1.15.0
Downtime: 0 minutes
```plaintext
#### Verify Update
```bash
# Verify updated version
provisioning version taskserv cilium
```plaintext
**Expected Output:**
```plaintext
📦 Cilium Version Info:
Installed: 1.15.0
Latest: 1.15.0
Status: ✅ Up-to-date
Nodes:
✅ web-01: 1.15.0 (running)
✅ web-02: 1.15.0 (running)
```plaintext
### 3.2 Update Critical Service (Kubernetes Example)
#### Test in Staging First
```bash
# If you have staging environment
provisioning t create kubernetes --infra my-staging --check
provisioning t create kubernetes --infra my-staging
# Run integration tests
provisioning test kubernetes --infra my-staging
```plaintext
#### Backup Current State
```bash
# Backup Kubernetes state
kubectl get all -A -o yaml &gt; k8s-backup-$(date +%Y%m%d).yaml
# Backup etcd (if using external etcd)
provisioning t backup kubernetes --infra my-production
```plaintext
#### Schedule Maintenance Window
```bash
# Set maintenance mode (optional, if supported)
provisioning maintenance enable --infra my-production --duration 30m
```plaintext
#### Update Kubernetes
```bash
# Update control plane first
provisioning t create kubernetes --infra my-production --control-plane-only
```plaintext
**Expected Output:**
```plaintext
🚀 Updating Kubernetes control plane on my-production...
Draining control plane: web-01... ⏳
✅ web-01 drained
Updating control plane: web-01... ⏳
✅ web-01 updated (Kubernetes 1.30.0)
Uncordoning: web-01... ⏳
✅ web-01 ready
Verifying control plane... ⏳
✅ Control plane healthy
🎉 Control plane update complete!
```plaintext
```bash
# Update worker nodes one by one
provisioning t create kubernetes --infra my-production --workers-only --rolling
```plaintext
**Expected Output:**
```plaintext
🚀 Updating Kubernetes workers on my-production...
Rolling update: web-02...
Draining... ⏳
✅ Drained (pods rescheduled)
Updating... ⏳
✅ Updated (Kubernetes 1.30.0)
Uncordoning... ⏳
✅ Ready
Waiting for pods to stabilize... ⏳
✅ All pods running
🎉 Worker update complete!
Updated: web-02
Version: 1.30.0
```plaintext
#### Verify Update
```bash
# Verify Kubernetes cluster
kubectl get nodes
provisioning version taskserv kubernetes
```plaintext
**Expected Output:**
```plaintext
NAME STATUS ROLES AGE VERSION
web-01 Ready control-plane 30d v1.30.0
web-02 Ready &lt;none&gt; 30d v1.30.0
```plaintext
```bash
# Run smoke tests
provisioning test kubernetes --infra my-production
```plaintext
### 3.3 Update Database (PostgreSQL Example)
⚠️ **WARNING**: Database updates may require data migration. Always backup first!
#### Backup Database
```bash
# Backup PostgreSQL database
provisioning t backup postgres --infra my-production
```plaintext
**Expected Output:**
```plaintext
🗄️ Backing up PostgreSQL...
Creating dump: my-production-postgres-20250930.sql... ⏳
✅ Dump created (2.3 GB)
Compressing... ⏳
✅ Compressed (450 MB)
Saved to: workspace/backups/postgres/my-production-20250930.sql.gz
```plaintext
#### Check Compatibility
```bash
# Check if data migration is needed
provisioning t check-migration postgres --from 15.5 --to 16.1
```plaintext
**Expected Output:**
```plaintext
🔍 PostgreSQL Migration Check:
From: 15.5
To: 16.1
Migration Required: ✅ Yes (major version change)
Steps Required:
1. Dump database with pg_dump
2. Stop PostgreSQL 15.5
3. Install PostgreSQL 16.1
4. Initialize new data directory
5. Restore from dump
Estimated Time: 15-30 minutes (depending on data size)
Estimated Downtime: 15-30 minutes
Recommended: Use streaming replication for zero-downtime upgrade
```plaintext
#### Perform Update
```bash
# Update PostgreSQL (with automatic migration)
provisioning t create postgres --infra my-production --migrate
```plaintext
**Expected Output:**
```plaintext
🚀 Updating PostgreSQL on my-production...
⚠️ Major version upgrade detected (15.5 → 16.1)
Automatic migration will be performed
Dumping database... ⏳
✅ Database dumped (2.3 GB)
Stopping PostgreSQL 15.5... ⏳
✅ Stopped
Installing PostgreSQL 16.1... ⏳
✅ Installed
Initializing new data directory... ⏳
✅ Initialized
Restoring database... ⏳
✅ Restored (2.3 GB)
Starting PostgreSQL 16.1... ⏳
✅ Started
Verifying data integrity... ⏳
✅ All tables verified
🎉 PostgreSQL update complete!
Version: 15.5 → 16.1
Downtime: 18 minutes
```plaintext
#### Verify Update
```bash
# Verify PostgreSQL
provisioning version taskserv postgres
ssh db-01 "psql --version"
```plaintext
## Step 4: Update Multiple Services
### 4.1 Batch Update (Sequentially)
```bash
# Update multiple taskservs one by one
provisioning t update --infra my-production --taskservs cilium,containerd,redis
```plaintext
**Expected Output:**
```plaintext
🚀 Updating 3 taskservs on my-production...
[1/3] Updating cilium... ⏳
✅ cilium updated (1.15.0)
[2/3] Updating containerd... ⏳
✅ containerd updated (1.7.14)
[3/3] Updating redis... ⏳
✅ redis updated (7.2.4)
🎉 All updates complete!
Updated: 3 taskservs
Total time: 8 minutes
```plaintext
### 4.2 Parallel Update (Non-Dependent Services)
```bash
# Update taskservs in parallel (if they don't depend on each other)
provisioning t update --infra my-production --taskservs redis,postgres --parallel
```plaintext
**Expected Output:**
```plaintext
🚀 Updating 2 taskservs in parallel on my-production...
redis: Updating... ⏳
postgres: Updating... ⏳
redis: ✅ Updated (7.2.4)
postgres: ✅ Updated (16.1)
🎉 All updates complete!
Updated: 2 taskservs
Total time: 3 minutes (parallel)
```plaintext
## Step 5: Update Server Configuration
### 5.1 Update Server Resources
```bash
# Edit server configuration
provisioning sops workspace/infra/my-production/servers.k
```plaintext
**Example: Upgrade server plan**
```kcl
# Before
{
name = "web-01"
plan = "1xCPU-2GB" # Old plan
}
# After
{
name = "web-01"
plan = "2xCPU-4GB" # New plan
}
```plaintext
```bash
# Apply server update
provisioning s update --infra my-production --check
provisioning s update --infra my-production
```plaintext
### 5.2 Update Server OS
```bash
# Update operating system packages
provisioning s update --infra my-production --os-update
```plaintext
**Expected Output:**
```plaintext
🚀 Updating OS packages on my-production servers...
web-01: Updating packages... ⏳
✅ web-01: 24 packages updated
web-02: Updating packages... ⏳
✅ web-02: 24 packages updated
db-01: Updating packages... ⏳
✅ db-01: 24 packages updated
🎉 OS updates complete!
```plaintext
## Step 6: Rollback Procedures
### 6.1 Rollback Task Service
If update fails or causes issues:
```bash
# Rollback to previous version
provisioning t rollback cilium --infra my-production
```plaintext
**Expected Output:**
```plaintext
🔄 Rolling back Cilium on my-production...
Current: 1.15.0
Target: 1.14.5 (previous version)
Rolling back: web-01... ⏳
✅ web-01 rolled back
Rolling back: web-02... ⏳
✅ web-02 rolled back
Verifying connectivity... ⏳
✅ All nodes connected
🎉 Rollback complete!
Version: 1.15.0 → 1.14.5
```plaintext
### 6.2 Rollback from Backup
```bash
# Restore configuration from backup
provisioning ws restore my-production --from workspace/backups/my-production-20250930.tar.gz
```plaintext
### 6.3 Emergency Rollback
```bash
# Complete infrastructure rollback
provisioning rollback --infra my-production --to-snapshot &lt;snapshot-id&gt;
```plaintext
## Step 7: Post-Update Verification
### 7.1 Verify All Components
```bash
# Check overall health
provisioning health --infra my-production
```plaintext
**Expected Output:**
```plaintext
🏥 Health Check: my-production
Servers:
✅ web-01: Healthy
✅ web-02: Healthy
✅ db-01: Healthy
Task Services:
✅ kubernetes: 1.30.0 (healthy)
✅ containerd: 1.7.13 (healthy)
✅ cilium: 1.15.0 (healthy)
✅ postgres: 16.1 (healthy)
Clusters:
✅ buildkit: 2/2 replicas (healthy)
Overall Status: ✅ All systems healthy
```plaintext
### 7.2 Verify Version Updates
```bash
# Verify all versions are updated
provisioning version show
```plaintext
### 7.3 Run Integration Tests
```bash
# Run comprehensive tests
provisioning test all --infra my-production
```plaintext
**Expected Output:**
```plaintext
🧪 Running Integration Tests...
[1/5] Server connectivity... ⏳
✅ All servers reachable
[2/5] Kubernetes health... ⏳
✅ All nodes ready, all pods running
[3/5] Network connectivity... ⏳
✅ All services reachable
[4/5] Database connectivity... ⏳
✅ PostgreSQL responsive
[5/5] Application health... ⏳
✅ All applications healthy
🎉 All tests passed!
```plaintext
### 7.4 Monitor for Issues
```bash
# Monitor logs for errors
provisioning logs --infra my-production --follow --level error
```plaintext
## Update Checklist
Use this checklist for production updates:
- [ ] Check for available updates
- [ ] Review changelog and breaking changes
- [ ] Create configuration backup
- [ ] Test update in staging environment
- [ ] Schedule maintenance window
- [ ] Notify team/users of maintenance
- [ ] Update non-critical services first
- [ ] Verify each update before proceeding
- [ ] Update critical services with rolling updates
- [ ] Backup database before major updates
- [ ] Verify all components after update
- [ ] Run integration tests
- [ ] Monitor for issues (30 minutes minimum)
- [ ] Document any issues encountered
- [ ] Close maintenance window
## Common Update Scenarios
### Scenario 1: Minor Security Patch
```bash
# Quick security update
provisioning t check-updates --security-only
provisioning t update --infra my-production --security-patches --yes
```plaintext
### Scenario 2: Major Version Upgrade
```bash
# Careful major version update
provisioning ws backup my-production
provisioning t check-migration &lt;service&gt; --from X.Y --to X+1.Y
provisioning t create &lt;service&gt; --infra my-production --migrate
provisioning test all --infra my-production
```plaintext
### Scenario 3: Emergency Hotfix
```bash
# Apply critical hotfix immediately
provisioning t create &lt;service&gt; --infra my-production --hotfix --yes
```plaintext
## Troubleshooting Updates
### Issue: Update fails mid-process
**Solution:**
```bash
# Check update status
provisioning t status &lt;taskserv&gt; --infra my-production
# Resume failed update
provisioning t update &lt;taskserv&gt; --infra my-production --resume
# Or rollback
provisioning t rollback &lt;taskserv&gt; --infra my-production
```plaintext
### Issue: Service not starting after update
**Solution:**
```bash
# Check logs
provisioning logs &lt;taskserv&gt; --infra my-production
# Verify configuration
provisioning t validate &lt;taskserv&gt; --infra my-production
# Rollback if necessary
provisioning t rollback &lt;taskserv&gt; --infra my-production
```plaintext
### Issue: Data migration fails
**Solution:**
```bash
# Check migration logs
provisioning t migration-logs &lt;taskserv&gt; --infra my-production
# Restore from backup
provisioning t restore &lt;taskserv&gt; --infra my-production --from &lt;backup-file&gt;
```plaintext
## Best Practices
1. **Always Test First**: Test updates in staging before production
2. **Backup Everything**: Create backups before any update
3. **Update Gradually**: Update one service at a time
4. **Monitor Closely**: Watch for errors after each update
5. **Have Rollback Plan**: Always have a rollback strategy
6. **Document Changes**: Keep update logs for reference
7. **Schedule Wisely**: Update during low-traffic periods
8. **Verify Thoroughly**: Run tests after each update
## Next Steps
- **[Customize Guide](customize-infrastructure.md)** - Customize your infrastructure
- **[From Scratch Guide](from-scratch.md)** - Deploy new infrastructure
- **[Workflow Guide](../development/workflow.md)** - Automate with workflows
## Quick Reference
```bash
# Update workflow
provisioning t check-updates
provisioning ws backup my-production
provisioning t create &lt;taskserv&gt; --infra my-production --check
provisioning t create &lt;taskserv&gt; --infra my-production
provisioning version taskserv &lt;taskserv&gt;
provisioning health --infra my-production
provisioning test all --infra my-production
```plaintext
---
*This guide is part of the provisioning project documentation. Last updated: 2025-09-30*
</code></pre>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../guides/from-scratch.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/customize-infrastructure.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/from-scratch.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/customize-infrastructure.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>
<script>
window.playground_copyable = true;
</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>