k8s.app.deploy ​
Deploy a containerised app: Namespace + ConfigMap + Secret + Deployment + Service, with optional PVC / HPA / PDB / Ingress
Deploy a single-container app to a Kubernetes cluster (BYO via CloudConnection).
Overview ​
| Property | Value |
|---|---|
| Workflow type | Dag |
| Library | App-kubernetes |
| Version | 1.0 |
Input Schema ​
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
connection_uuid | uuid | Yes | — | CloudConnection UUID for the target Kubernetes cluster, picked from the organization's kubernetes-type connections. |
namespace | string | Yes | — | Target namespace (created if missing) |
name | string | Yes | — | App name — used for Deployment / Service / ConfigMap / Secret |
image | string | Yes | — | Container image reference (registry/repo:tag) |
ports | json | Yes | — | List of {port, target_port?, protocol?} dicts |
replicas | integer | No | — | Replica count (default 1) |
env | json | No | — | NON-SECRET env vars set directly on the container. Rendered as plaintext env[].value — readable by anyone with get pod. Put credentials in secret_env, which references an existing cluster Secret instead of carrying the value. |
secret_env | json | No | — | Env vars sourced from EXISTING cluster Secrets: {ENV_NAME: {name: <secret>, key: <key>, optional?: bool}} or {ENV_NAME: '<secret>/<key>'}. Rendered as env[].valueFrom.secretKeyRef — the credential never enters the pod spec or workflow state. |
config_data | json | No | — | Key/value map mounted via envFrom.configMapRef on the deployment |
secret_data | json | No | — | Key/value map materialised into the {name}-secrets Secret and mounted via envFrom.secretRef. Vaulted by the engine, so this DAG's own row stores a [VAULT:...] reference — but the value still reaches the kubernetes.secret.ensure child in cleartext (that primitive's data is not sensitive) and the Kafka/scheduled-transition input_data. Prefer secret_env, which references an existing Secret and never carries the value at all — see CLAUDE.md 'Secret handling'. |
labels | json | No | — | Labels applied to Deployment / Service / pod template (default {app: name}) |
service_type | string | No | — | Service type (ClusterIP |
namespace_labels | json | No | — | Labels applied to the namespace on creation |
timeout_seconds | integer | No | — | Total wait budget for rollout to become Available (default 300, cap 1800) |
poll_interval | integer | No | — | Seconds between status reads while waiting (default 5, cap 60) |
resources | json | No | — | Container resources {requests?, limits?} (cpu/memory) |
probes | json | No | — | Container probes {liveness?, readiness?, startup?} as Kubernetes probe objects |
hpa | json | No | — | Attach an HPA named {name}: {min_replicas, max_replicas, metrics?, behavior?}. Cannot be combined with replicas — the HPA owns the replica count. |
pdb | json | No | — | Attach a PDB named {name}: exactly one of |
volume_claims | json | No | — | PVC list [{name, size, storage_class?, access_modes?}]. Creates {app}-{name}, max 8. |
volumes | json | No | — | Pod volumes [{name, mount_path, claim? |
ingress | json | No | — | Attach an Ingress named {name}: |
Output Schema ​
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
connection_uuid | uuid | No | — | CloudConnection UUID for the target cluster, echoed from input. |
namespace | string | No | — | — |
name | string | No | — | — |
image | string | No | — | — |
ports | json | No | — | — |
replicas | integer | No | — | — |
env | json | No | — | — |
secret_env | json | No | — | Secret references echoed from input — names/keys only, never values. |
config_data | json | No | — | — |
secret_data | json | No | — | Echoed from input. Vaulted — this row carries a [VAULT:...] reference, not the value. Prefer secret_env. |
labels | json | No | — | — |
service_type | string | No | — | — |
namespace_labels | json | No | — | — |
timeout_seconds | integer | No | — | — |
poll_interval | integer | No | — | — |
resources | json | No | — | Container resources {requests?, limits?} (cpu/memory) |
probes | json | No | — | Container probes {liveness?, readiness?, startup?} as Kubernetes probe objects |
hpa | json | No | — | Attach an HPA named {name}: {min_replicas, max_replicas, metrics?, behavior?}. Cannot be combined with replicas — the HPA owns the replica count. |
pdb | json | No | — | Attach a PDB named {name}: exactly one of |
volume_claims | json | No | — | PVC list [{name, size, storage_class?, access_modes?}]. Creates {app}-{name}, max 8. |
volumes | json | No | — | Pod volumes [{name, mount_path, claim? |
ingress | json | No | — | Attach an Ingress named {name}: |
workflow_run_uuid | string | No | — | Engine-stamped DAG run id written by action_start. |
ensure_namespace | json | No | — | — |
ensure_configmap | json | No | — | — |
ensure_secret | json | No | — | — |
ensure_pvc_0 | json | No | — | — |
ensure_pvc_1 | json | No | — | — |
ensure_pvc_2 | json | No | — | — |
ensure_pvc_3 | json | No | — | — |
ensure_pvc_4 | json | No | — | — |
ensure_pvc_5 | json | No | — | — |
ensure_pvc_6 | json | No | — | — |
ensure_pvc_7 | json | No | — | — |
wait_pvc_0 | json | No | — | — |
wait_pvc_1 | json | No | — | — |
wait_pvc_2 | json | No | — | — |
wait_pvc_3 | json | No | — | — |
wait_pvc_4 | json | No | — | — |
wait_pvc_5 | json | No | — | — |
wait_pvc_6 | json | No | — | — |
wait_pvc_7 | json | No | — | — |
ensure_deployment | json | No | — | — |
ensure_service | json | No | — | — |
ensure_hpa | json | No | — | — |
ensure_pdb | json | No | — | — |
ensure_ingress | json | No | — | — |
wait_for_rollout | json | No | — | — |
failure_reason | string | No | — | — |
failure_type | string | No | — | — |
failed_action | string | No | — | — |
failed_at_state | string | No | — | — |
failed_step | string | No | — | — |
failed_layer | string | No | — | — |
error | string | No | — | — |
error_type | string | No | — | — |
DAG Layers ​
| # | Layer | Steps | Compensation |
|---|---|---|---|
| 1 | namespace | kubernetes.namespace.ensure | — |
| 2 | config | kubernetes.configmap.ensure, kubernetes.secret.ensure, kubernetes.pvc.ensure, kubernetes.pvc.ensure, kubernetes.pvc.ensure, kubernetes.pvc.ensure, kubernetes.pvc.ensure, kubernetes.pvc.ensure, kubernetes.pvc.ensure, kubernetes.pvc.ensure | — |
| 3 | wait_storage | kubernetes.pvc.wait_for_bound, kubernetes.pvc.wait_for_bound, kubernetes.pvc.wait_for_bound, kubernetes.pvc.wait_for_bound, kubernetes.pvc.wait_for_bound, kubernetes.pvc.wait_for_bound, kubernetes.pvc.wait_for_bound, kubernetes.pvc.wait_for_bound | — |
| 4 | workload | kubernetes.deployment.ensure, kubernetes.service.ensure | — |
| 5 | policy | kubernetes.horizontalpodautoscaler.ensure, kubernetes.poddisruptionbudget.ensure, kubernetes.ingress.ensure | — |
| 6 | wait | kubernetes.deployment.wait_for_available | — |
Execution Flow ​
Sub-workflows ​
| Sub-workflow | Step name |
|---|---|
kubernetes.namespace.ensure | ensure_namespace |
kubernetes.configmap.ensure | ensure_configmap |
kubernetes.secret.ensure | ensure_secret |
kubernetes.pvc.ensure | ensure_pvc_0 |
kubernetes.pvc.wait_for_bound | wait_pvc_0 |
kubernetes.deployment.ensure | ensure_deployment |
kubernetes.service.ensure | ensure_service |
kubernetes.horizontalpodautoscaler.ensure | ensure_hpa |
kubernetes.poddisruptionbudget.ensure | ensure_pdb |
kubernetes.ingress.ensure | ensure_ingress |
kubernetes.deployment.wait_for_available | wait_for_rollout |
API Usage ​
bash
POST /api/workflows/start
Content-Type: application/json
{
"workflow_type": "k8s.app.deploy",
"initial_data": {
"connection_uuid": "value",
"namespace": "value",
"name": "value",
"image": "value"
}
}