Files
sencho/docs/tutorials/set-up-fleet-federation.mdx
T
Anso de7ecee497 docs: tutorials batch 1 (#1656)
* docs: scaffold Tutorials tab and write enroll-a-remote-node

Adds the Tutorials tab to docs.json with 15 stub pages across three
groups (Fleet & nodes, Deploy & automate, Secure & integrate), and
writes the first full tutorial: enrolling a remote node via Pilot
Agent mode, verified end to end against a live control instance and
a second host running an existing Jellyfin Compose stack.

* docs: write Schedule an Operation tutorial

* docs: fix MDX parse error in Schedule an Operation tutorial

* docs: write Set Up SSO with Custom OIDC tutorial

Registers an OAuth client in a self-hosted identity provider (Keycloak
worked example), configures Sencho's Custom OIDC settings, tests the
connection, and verifies a real end-to-end login with auto-provisioning
from two independent surfaces.

* docs: drop unused SSO tutorial screenshot

sso-settings-empty.png isn't referenced by the tutorial content.

* docs: write Set Up Fleet Federation tutorial

Migrates a Blueprint-managed workload from one node to another using
pin and cordon, with the confirm-before-mutate rollout in between.
Corrects the published feature page's claim that pin requires the
global admin role; the code gates cordon and pin identically, scoped
to the target node.

* docs: write Create and Approve a Blueprint tutorial

Covers labeling a target node, authoring a stateless Blueprint,
walking through the create-then-approve rollout flow, verifying
from the Deployments tab and the audit log, and recovering from a
port-conflict deploy failure. Cross-links with Move a Blueprint
Deployment to a New Node in both directions.

* docs: write Automatically Patch a Stack With an Auto-Update Label tutorial

* docs: write Configure Auto-Heal Policies tutorial

Adds the full step-by-step content for the Configure Auto-Heal Policies
stub: an nginx+redis scenario stack, adding a service-scoped policy,
and a live verification that breaks a container's healthcheck,
confirms the policy restarts it, and recovers it.

* docs: write Set Up Deploy Enforcement tutorial

Covers configuring a block-on-deploy scan policy against a stack running
a deliberately outdated nginx image, reading the block dialog, and
overriding it as an admin with the bypass confirmed in the audit log.
Includes a stack-pattern mismatch as the most likely first-time failure.

* docs: write Configure Environment Guardrails tutorial

Covers the Block deploy on missing required env vars guardrail end to
end: deploy a Postgres stack with a required password, enable the
guardrail, watch a real update get refused with a named-variable
message, fix it, and verify from the Activity and Environment tabs.

* docs: write Deploy a Stack Automatically From Your CI Pipeline tutorial

* docs: write Catch and Fix a Container That's Drifted From Its Compose File tutorial

Covers reading a real Drift finding after an out-of-band container
change and resolving it by redeploying through Sencho.

* docs: write Connect a Git Source tutorial

* docs: write Push a Shared Environment File to Every Node tutorial

Writes the Fleet Secrets tutorial: create a bundle, target nodes by
label, read the push preview/results, verify via the audit log, and
recover from a stack-name typo. Removes the three unwritten
placeholder stubs (RBAC, Sencho Mesh, private registries) that had no
scheduled content.
2026-08-08 01:49:21 -04:00

120 lines
11 KiB
Plaintext

---
title: Move a Blueprint Deployment to a New Node
sidebarTitle: Move a blueprint to a new node
description: Relocate a Blueprint-managed stack from a node you're retiring to another node in the fleet, without letting the reconciler undo the move partway through.
---
Say a small stateless service, a status page, a metrics exporter, an internal API, runs as a [Blueprint](/features/blueprint-model)-managed deployment on one node in your fleet. That node is going away, for maintenance, decommissioning, or a hardware swap, and you need the workload running on a different node before you take the old one offline. This walks through doing that with **Federation**'s pin and cordon controls: pin the blueprint to the destination so the reconciler stops trusting its normal selector, cordon the source so it stops picking up anything new, then confirm the rollout that actually moves the workload.
<Note>
Despite the name, Federation doesn't connect separate Sencho instances or fleets together, that's a different concept Sencho doesn't do at all. Federation is a tab inside a single fleet's **Fleet** view. It steers *where* that one fleet's Blueprint-managed deployments land; it has no notion of "other fleets."
</Note>
By the end, the workload runs only on the new node, the old node is marked unschedulable, and you can confirm both from more than one place in the UI.
Both controls follow the same rule, and it's the part most likely to trip up a first-time user: **pinning and cordoning only declare intent.** Neither one deploys or withdraws a single container by itself. The reconciler stages what it *wants* to do next; you still open the blueprint and click **Confirm Apply** before anything on the fleet actually changes. That extra step is what makes this walkthrough three actions long instead of one.
This tutorial does not cover creating a Blueprint from scratch (see [Create and Approve a Blueprint](/tutorials/create-and-approve-a-blueprint)), draining a node of everything it runs, or evicting a stateful deployment. See the [Blueprints](/features/blueprint-model) and [Fleet Federation](/features/fleet-federation) feature pages for those last two.
## Prerequisites
- **An admin account.** Cordoning a node and pinning a blueprint both check the same permission, scoped to the node you're acting on; clearing a pin checks that same permission without a node scope. Delegating that permission to a non-admin role for one specific node is an Admiral-tier capability, so on Community you complete every step here as the instance's admin.
- **An existing Blueprint already deployed on at least one node.** Federation steers placement for Blueprints that exist; it does not create them. If you don't have one yet, walk through [Create and Approve a Blueprint](/tutorials/create-and-approve-a-blueprint) first.
- **At least two nodes in the fleet**, both online. Pinning only matters when there's somewhere else to pin to. Multi-node fleets and Federation are both Community-tier, no paid plan required.
<Frame caption="Federation before any changes: no nodes cordoned, one blueprint listed, unpinned.">
<img src="/images/tutorials/set-up-fleet-federation/federation-tab-before-pin.png" alt="Fleet Federation tab showing Cordoned nodes 0 of 4 and a Pin policy table with one row for the edge-status blueprint, selector any=[dev], Pinned to (unpinned), Effective any=[dev]." />
</Frame>
<Steps>
<Step title="Pin the blueprint to the destination node">
Open **Fleet → Federation** and find your blueprint's row in the **Pin policy** table. Open the **Pinned to** dropdown and select the node you're moving the workload to. A cordoned node would show inline as `<name> · cordoned` here, so you can see at a glance if you're about to pin onto something already out of rotation.
<Frame caption="The Pinned to dropdown, before selecting a destination.">
<img src="/images/tutorials/set-up-fleet-federation/pin-dropdown-open.png" alt="Pinned to dropdown open for the edge-status blueprint, listing (unpinned) with a checkmark, Local, Pitt-Moba, SLX-Mars, and SLX-Orion." />
</Frame>
The selection saves immediately and a toast confirms it. The **Effective** column updates to `pin: <destination>`, overriding whatever the selector would otherwise resolve to. Nothing has deployed yet, this only changes what the reconciler wants to do next.
<Frame caption="Pin saved. The Effective column now reads the pinned node.">
<img src="/images/tutorials/set-up-fleet-federation/pin-applied-effective.png" alt="Pin policy table with the edge-status row now showing Pinned to SLX-Mars and Effective pin: SLX-Mars." />
</Frame>
</Step>
<Step title="Cordon the node you're retiring">
Go to **Fleet → Overview**. On the source node's card, click the kebab menu (`⋯`) and choose **Cordon node**.
<Frame caption="The node card's kebab menu, with Cordon node as the only Federation action available on an uncordoned node.">
<img src="/images/tutorials/set-up-fleet-federation/node-actions-cordon-menu.png" alt="Node actions menu open on the Pitt-Moba card, listing Node details, Edit node, Delete node, Cordon node, and Mute." />
</Frame>
A confirmation dialog opens with an optional reason field, up to 256 characters. Fill in something that will make sense to whoever looks at this node in a week.
<Frame caption="Cordon confirmation dialog with a reason filled in.">
<img src="/images/tutorials/set-up-fleet-federation/cordon-confirm-dialog.png" alt="Cordon Pitt-Moba confirmation dialog. Description reads 'Mark this node as unschedulable. New blueprint deployments will skip it. Existing deployments remain in place.' Reason field filled with 'Retiring host, migrating workloads to SLX-Mars'." />
</Frame>
Click **Cordon node**. The card gains a `Cordoned` pill immediately; this alone does not touch anything already running on the node, including the blueprint you're about to move off it.
<Frame caption="Node card carrying the Cordoned pill after confirming.">
<img src="/images/tutorials/set-up-fleet-federation/node-card-cordoned.png" alt="Fleet Overview grid with the Pitt-Moba node card showing the amber Cordoned pill alongside its Online and remote badges. Local, SLX-Mars, and SLX-Orion have no cordon indicator." />
</Frame>
<Note>
Cordon only ever removes a node from consideration for *new* placements; it never touches what's already running, and it never overrides an explicit pin. If you pinned a blueprint to a node that happens to be cordoned, the pin still wins, the blueprint deploys there anyway once its rollout is confirmed. Cordon and pin answer different questions ("should this node pick up new work automatically" versus "where must this specific blueprint run"), and when they disagree, the explicit answer (pin) beats the general one (cordon).
</Note>
</Step>
<Step title="Confirm the rollout that actually moves it">
Pinning and cordoning only declared intent, neither one deployed or withdrew anything by itself. Open **Fleet → Deployments**, select your blueprint, and click **Apply now**. Sencho opens a rollout preview.
<Frame caption="Rollout preview for the migration: a safe create on the destination, a safe remove on the source.">
<img src="/images/tutorials/set-up-fleet-federation/rollout-preview-migration.png" alt="Confirm rollout dialog for the edge-status blueprint reading Safe 2, Warnings 1, Blockers 0. Changes list: SLX-Mars (remote/online) create safe New placement, and Pitt-Moba (remote/online) remove safe Withdraw from selector." />
</Frame>
You should see one **create** on the destination node and one **remove** on the source, both marked safe. If the destination were unreachable, that create would show as a blocker instead and **Confirm Apply** would stay disabled, see [If something goes wrong](#if-something-goes-wrong). Click **Confirm Apply**.
<Frame caption="After confirming: the deployment table now lists only the destination node, marked Pinned.">
<img src="/images/tutorials/set-up-fleet-federation/blueprint-migrated-pinned-badge.png" alt="Blueprint detail sheet for edge-status showing a Pinned to SLX-Mars banner and a Deployments table with a single row: SLX-Mars, marked Pinned, status Active, last activity just now." />
</Frame>
</Step>
</Steps>
## Verify it worked
Check from more than one surface, since a single stale UI element could tell you the wrong thing.
**The Federation tab.** The Pin policy row's **Effective** column reads the pinned node, and the Cordoned nodes card lists the source node with its reason and a timestamp.
<Frame caption="Federation tab after the migration: source node cordoned, blueprint pinned to the destination.">
<img src="/images/tutorials/set-up-fleet-federation/federation-tab-after-migration.png" alt="Fleet Federation tab showing Cordoned nodes 1 of 4 with Pitt-Moba listed and the reason 'Retiring host, migrating workloads to SLX-Mars', and a Pin policy row for edge-status with Pinned to SLX-Mars and Effective pin: SLX-Mars." />
</Frame>
**The audit log.** Open **Audit** and search or scan for the actions you just took. Each mutating request gets its own row: the pin write, the cordon, and the apply.
<Frame caption="Audit log entries for the pin, cordon, and apply actions, in reverse chronological order.">
<img src="/images/tutorials/set-up-fleet-federation/audit-log-federation-entries.png" alt="Audit log rows: admin post /api/blueprints/15/apply at 15:43:04, admin cordoned node: 7 at 15:40:48, and admin updated blueprint pin: 15 at 15:38:44." />
</Frame>
## If something goes wrong
The most common first-time confusion is pinning or cordoning and then expecting the workload to move on its own. It won't. Both actions only change what the reconciler *wants*; the blueprint's catalog tile and detail sheet footer show **pending** or **reapproval required** until you open the blueprint and confirm a rollout.
<Frame caption="A pinned blueprint sitting in pending state before the rollout is confirmed.">
<img src="/images/tutorials/set-up-fleet-federation/blueprint-pinned-banner-pending.png" alt="Blueprint detail sheet showing a Pinned to SLX-Mars banner while the Deployments table still lists the original node, Pitt-Moba, as Active, and the sheet footer reads pending." />
</Frame>
If **Confirm Apply** is greyed out instead, a blocker is present, most often an offline or unreachable destination node. Check the destination's status in **Fleet → Overview** before retrying, or change the pin to a node that's actually reachable.
## Related
<CardGroup cols={2}>
<Card title="Fleet Federation" icon="diagram-project" href="/features/fleet-federation">
Cordon and pin mechanics, the confirm-before-mutate model, and full troubleshooting.
</Card>
<Card title="Blueprints" icon="sitemap" href="/features/blueprint-model">
The declarative deployment model Federation steers, including selectors, drift policy, and the rollout-preview mechanic.
</Card>
<Card title="Create and Approve a Blueprint" icon="drafting-compass" href="/tutorials/create-and-approve-a-blueprint">
Author and deploy a Blueprint from scratch, the prerequisite this tutorial assumes.
</Card>
</CardGroup>