shdctl workflows
Run shdctl in your CI pipeline with ArgoCD, or use it for generate-only, air-gapped, or direct Helm deployments
읽는 시간 7분최근 업데이트: 19시간 전
Recommended workflow: CI + ArgoCD
This is the recommended way to run shdctl: in a CI job, with ArgoCD reconciling the rendered charts from a Git repo. It is Mode A of the architecture.
One-time setup
-
Create the deployment namespace (). Nothing in the release creates it, and every step below that touches the cluster needs it.
configuration.kubernetes.namespace -
Install ArgoCD so that it reconciles Applications in that namespace. Every application lands there, in ArgoCD'sproject — shdctl applies the top-level one and ArgoCD creates the rest from Git. Install ArgoCD into the deployment namespace, or configure it to watch that namespace (ArgoCD's "Applications in any namespace", which needs the namespace in both its
defaultsetting and theapplication.namespacesproject'sdefault). Give it read access to the Git repo the pipeline commits the rendered charts to.sourceNamespaces -
Pointin your manifest at that repo (the manifest reference).
deployment.argocdandrepoURLare required;destinationServeris the branch the pipeline pushes to;targetRevisionis the directory, relative to the repository root, the charts are committed under. The pipeline below runs at the root of your repository checkout and renders intopathPrefix, so setgenerated-charts/— or change both together.pathPrefix: generated-charts -
Buildonce, with
secrets.import.yaml, so that it carries every value shdctl generates as well as the ones you supply.--persistreads the release's secrets schema, so pull the release first:secret generateshdctl release pull --clean-outputshdctl secret generate --import my-values.yaml --use-defaults --persist secrets.import.yamlCheck it forbefore you store it — a required value missing fromTBDis saved as that placeholder, and later runs reuse it without warning again. Store that file in your CI secret store, base64-encoded. A value it does not carry is generated afresh on every pipeline run, and deploying a regenerated password over the one a running service holds breaks that service. When an upgrade adds a secret, runmy-values.yamlagainst the new release — it reads the file back and generates only the new values — and store the result.shdctl secret generate --use-defaults --persist secrets.import.yaml -
Provision a kubeconfig for the CI runner with namespace-scoped RBAC:,
getandcreateonpatchand onSecretin the deployment namespace.argoproj.io/Applicationreads each object before creating or patching it, which is whykubectl applyis needed.get -
Step 0 of the pipeline reads cluster-scoped objects that role cannot. Either grant the CI identity these read-only rules through a ClusterRole, or runyourself before the first deploy and leave it out of the pipeline:
shdctl cluster checkrules: - apiGroups: [""] resources: ["nodes"] verbs: ["list"] - apiGroups: [""] resources: ["namespaces"] verbs: ["get"] - apiGroups: ["storage.k8s.io"] resources: ["storageclasses"] verbs: ["list"] - apiGroups: ["apiregistration.k8s.io"] resources: ["apiservices"] verbs: ["get"] - apiGroups: ["apiextensions.k8s.io"] resources: ["customresourcedefinitions"] verbs: ["get"]Addonlistfor the ArgoCD controller check, which is skipped without it, andpodsonlistinnodepoolsif Karpenter provides your transformation nodes on demand.karpenter.sh -
Registry credentials for the runner: a Unity registry account forand, air-gapped, the source side of
release pull; push access to your own registry for its target side.artifact sync
Pipeline steps
# 0. Validate the manifest, then that the cluster meets the prerequisites (read-only)shdctl manifest validateshdctl cluster check# 1. Pull the release from Unity's registry (read-only)echo "$UNITY_REGISTRY_PASSWORD" | shdctl configure set --username "$UNITY_REGISTRY_USERNAME" --password-stdinshdctl release pull --clean-output# 2. (Air-gapped only) Mirror artifacts to your registry, then confirm the result.# Run `docker login` for Unity's registry and yours first.shdctl artifact sync preflightshdctl artifact sync images --skip-existing --cleanupshdctl artifact sync orasshdctl artifact sync verify# 3. Render ArgoCD app-of-apps charts into generated-charts/, the directory pathPrefix namesshdctl release generate --format argocd --clean-output# 4. Render Kubernetes Secret manifests (secrets.import.yaml decoded from your CI secret store)shdctl secret generate --import secrets.import.yaml --use-defaults --output secrets.yaml# 5. Commit charts to your Git repogit add generated-charts/git commit -m "Deploy release ${RELEASE_VERSION}"git push# 6. Apply Secrets to the cluster (namespace-scoped kubeconfig; every Secret already names its namespace)shdctl secret deploy --file secrets.yaml# 7. Apply the bootstrap Application (namespace-scoped kubeconfig)shdctl release deploy --format argocd# ArgoCD picks up the changes from Git from here on.
For the credentials shdctl reads and the verbs it calls in your cluster, refer to What shdctl touches.
Helm alternative
If you don't run ArgoCD, you can use in the same CI pipeline. Replace steps 3, 5, and 7 with and ; skip the and the ArgoCD items of the one-time setup. The CI runner then needs a cluster-wide kubeconfig (it runs directly), which is a weaker trust boundary than the ArgoCD path. ArgoCD is recommended for that reason.
--format helmshdctl release generate --clean-outputshdctl release deploy --format helmgit pushhelm upgrade --installRun as its own step before the real deploy: it prints every chart's command, wave by wave, which is the record to read when a deploy stops partway. With above 1 (or ), it prints the sequential plan, which leaves out the dependency steps a parallel deploy runs. on the real deploy rides out the first-install race where a chart's CRDs are not yet visible to the next chart.
shdctl release deploy --format helm --dry-runhelm--concurrencydeployment.helm.concurrency--retries 1Other ways to use shdctl
The recommended workflow above (Mode A) is one of several. The required step is always (and usually alongside it); choose what you do with the output.
shdctl release generateshdctl secret generateGenerate-only — bring your own CD (Mode C)
The minimum viable use of shdctl. shdctl renders charts and secrets from your manifest and the extracted release package; your existing CD tooling — , , Flux, a custom pipeline — handles everything downstream. shdctl never holds a kubeconfig and never touches your cluster.
helmkubectlshdctl release pull --clean-outputshdctl release generate --clean-outputshdctl secret generate --import secrets.import.yaml --use-defaults --output secrets.yaml# Hand off generated-charts/ and secrets.yaml to your existing pipeline.
Refer to the Mode C diagram for the trust boundary.
Air-gapped (Mode B)
Mirror Unity's release artifacts into your registry once from a bastion, then run any of the modes above with no internet access at deploy time — for a Helm deploy, from a host with no Helm chart repository registered (What shdctl touches).
# On the bastion (one-time per release):shdctl release pull --clean-outputshdctl artifact sync preflight # proves the credentialsshdctl artifact sync images --skip-existing --cleanup # only what your features requireshdctl artifact sync orasshdctl artifact sync verify # reports anything still missing# Then continue with generate / deploy from inside your network.
The mirror covers what your manifest's enabled features require, so re-run after changing a feature toggle, or mirror the full set with . compares a registry against a manifest and exits non-zero when a required image is absent; run it before every deploy from a mirrored registry. Note the order: proves your credentials and reports content, and a run against a registry you cannot authenticate to reports everything as missing. Verify the target registry explains how to read a report.
shdctl artifact sync images--allshdctl artifact sync verifypreflightverifyverifyRefer to the Mode B diagram.
Direct Helm deploy
shdctl runs directly. Suited to operators who already manage Helm releases by hand and have a kubeconfig with cluster-wide deploy rights. No separate architecture diagram — this is a thin wrapper around ; review the Helm flags in Generate and deploy charts.
helm upgrade --installhelm upgrade --installshdctl release pull --clean-outputshdctl release generate --clean-outputshdctl release deploy --format helm
Pass first to print every command, wave by wave, without contacting the cluster. The deploy does not create the namespace: it has to exist first.
--dry-runhelmFor faster deployments, set on (or in your manifest). Charts within the same wave deploy in parallel, largest first; waves themselves remain sequential. Per-chart helm output is buffered and printed when each chart finishes (), so line ordering will not match sequential mode. A summary line at the end of every wave and at the end of deploy reports total / succeeded / failed counts and elapsed time. Helm format only. Generate and deploy charts lists every flag.
--concurrency Nshdctl release deploydeployment.helm.concurrency: N==> [chart-name] done in 12.3sMinimum requirement
Whichever mode you pick, is the one command that must run. It is what turns your into Helm chart values for the rest of the pipeline.
shdctl release generatemanifest.yaml