wanderland-k8s-pack ships the deploy-slot boundaries for a site whose target is a Kubernetes cluster. It fills the deploy slot of the containerized_deployment archetype — the same slot cfn_provisioner fills for an ECS/CloudFormation target — with the kustomize/kubectl path: pin an overlay to the freshly-built image, apply it, and roll the deployment. The boundaries follow the iscanGuide deploy step by step (kustomize edit set image → kubectl apply → rollout restart → rollout status), reframed as wanderland boundaries that run through the :kubectl shell adapter.
The pack ships no archetype of its own. A Kubernetes deployment names containerized_deployment like any other, builds its image in the image stage, and names k8s_provisioner for the deploy component. The image the deploy pins comes from the build slot's output, threaded in with !Context.
Add the gem; the entry file requires wanderland-core and globs the three boundaries, which self-register on load. There is no AWS dependency.
# Gemfile
gem "wanderland-k8s-pack", path: "../wanderland-k8s-pack"
| Boundary | Role | What it does |
|---|---|---|
k8s_provisioner |
deploy slot wrapper |
Pin the overlay image, then apply + rollout, as one group. The kubectl analogue of cfn_provisioner. |
kustomize_set_image |
sub-step (pure transform) | Write the images: entry in an overlay's kustomization.yaml so it points at a specific image ref. No binary, no adapter. |
kubectl_apply |
sub-step (shells out) | Render + apply the overlay, then rollout restart a deployment and wait for rollout status. |
The pack needs one adapter: a :kubectl shell mount.
adapters:
kubectl:
kind: shell
command: kubectl
kind: shell wraps one fixed binary behind .run(*args, cwd:, env:), returning {exit_code:, stdout:, stderr:, duration_s:}. The same live / replay / mock discipline as every other adapter applies: a scenario records the kubectl calls to cassettes once, then replays them.
k8s_provisioner is the deploy-slot wrapper. It dispatches kustomize_set_image to pin the overlay, then kubectl_apply to apply and roll out, exposing both sub-boundaries' args through the parent. A containerized_deployment component names it like this:
pipeline:
stages:
deploy:
type: component
args:
output_root: /tmp/iscanguide-deploy
components:
sc-website:
type: k8s_provisioner
args:
kustomize_dir: k8s/overlays/prod
name: 789905347053.dkr.ecr.us-west-2.amazonaws.com/iscanguide/sc-website
image: !Context for_boundary.sc-website.image_ref
namespace: iscanguide
deployment: deploy/sc-website
wait_timeout_s: 180
load_restrictor: LoadRestrictionsNone
Anatomy:
name is the image name the manifests reference — the image: in the Deployment, without a tag. It identifies which images: entry kustomize rewrites.image is the full ref to pin to. It reads !Context for_boundary.<image>.image_ref — the value the image stage's docker_build produced earlier this run — so the overlay deploys exactly what was built.kustomize_dir is the overlay directory, passed to both sub-boundaries.namespace, deployment, wait_timeout_s, load_restrictor thread straight through to kubectl_apply.k8s_provisioner dispatches its sub-boundaries through input.dispatch, so their results roll up under its crossing and a sub-boundary's halt propagates as the wrapper's halt. The route sees one signed crossing for the deploy; the set-image and apply steps are its internals.
kustomize_set_image writes the images: block in the overlay's kustomization.yaml. It is a pure YAML transform — no kustomize binary, no adapter — so it is deterministic and unit-testable. A kustomize overlay's images: block looks like this before a deploy:
# k8s/overlays/prod/kustomization.yaml
images:
- name: 789905347053.dkr.ecr.us-west-2.amazonaws.com/iscanguide/sc-website
newTag: latest
- name: 789905347053.dkr.ecr.us-west-2.amazonaws.com/iscanguide/sc-worker
newTag: latest
Given name and a full image ref, the boundary finds (or appends) the matching entry and writes newName + newTag. It splits the ref on its final : into name and tag, treating the colon as a tag separator only when the suffix has no / — so a registry port like host:5001/repo keeps its colon and a missing tag clears newTag rather than writing a bogus one. It returns kustomization_path, name, new_name, new_tag, and image. A kustomization.yaml (or .yml) missing under kustomize_dir halts with a 404 naming the directory.
kubectl_apply shells through :kubectl to apply the overlay and, when a deployment: is named, restart it and wait for the rollout to stabilize. It accumulates duration_s across every shell call.
load_restrictor, it runs kubectl apply -k <kustomize_dir>. When an overlay references files outside its own directory (a ../../base/... resource), kustomize's default LoadRestrictionsRootOnly policy refuses them; setting load_restrictor: LoadRestrictionsNone makes the boundary render with kubectl kustomize --load-restrictor=LoadRestrictionsNone to a temp file, then kubectl apply -f that file. Two shell calls, one boundary, no external script.deployment: is set, it runs kubectl rollout restart <deployment> (with -n <namespace> when given), then kubectl rollout status <deployment> --timeout=<wait_timeout_s>s. Omit deployment: to apply without rolling — the boundary returns rolled: false.kubectl's stderr, so the operator sees why without re-running.It returns applied, kustomize_dir, rolled, rollout_status, and duration_s. k8s_provisioner folds these into its own OK payload alongside the pinned image.
A site whose target is Kubernetes can name containerized_deployment, build its image in the image stage, and name k8s_provisioner for each deploy component. The provisioner pins each overlay to the image the build just produced, applies it (honoring cross-directory overlays), rolls the deployment, and waits for it to stabilize — all through the :kubectl shell adapter, recordable and replayable like every other adapter. Swapping an ECS target for a Kubernetes one is a change of which boundary fills the deploy slot; the rest of the chain — start_run, collect, load_metadata, image — is unchanged.
containerized_deployment archetype and the slots the deploy component plugs into.cfn_provisioner fills the same deploy slot for an ECS/CloudFormation target.!Context for_boundary.<image>.image_ref, the resolver that threads the built image into the deploy.kind: shell adapter.