AgentStack
SKILL unreviewed MIT Self-run

Argo To Zenml Migration

skill-zenml-io-skills-argo-migration · by zenml-io

>-

No reviews yet
0 installs
14 views
0.0% view→install

Install

$ agentstack add skill-zenml-io-skills-argo-migration

Open-source listing — not yet scanned by AgentStack. Follow the source repository for install instructions.

Security review

⚠ Flagged

1 finding(s); flagged for manual review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures
  • high Dangerous shell/eval execution.

What it can access

  • Network access No
  • Filesystem access Used
  • Shell / process execution Used
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Argo To Zenml Migration? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Migrate Argo Workflows to ZenML

This skill translates Argo Workflows into idiomatic ZenML pipelines. It handles the full migration workflow: analyzing Argo YAML and referenced scripts, classifying each pattern, translating what maps cleanly, flagging what needs redesign, and producing a working ZenML project.

How migration works at a high level

Argo and ZenML can both express DAG-shaped workflows, but they speak different native languages.

  • Argo is a Kubernetes-native workflow engine driven by YAML CRDs, template references, variable substitution, pod topology, and controller policies.
  • ZenML is a Python-first pipeline framework driven by @step, @pipeline, typed artifacts, stack components, and orchestrator-managed execution.

That means this migration is not a simple rename operation. Some Argo features map well, some only preserve intent, and some depend so heavily on controller or pod semantics that they must be redesigned explicitly.

The three mapping types

Every Argo concept falls into one of these categories:

| Type | Meaning | Action | |------|---------|--------| | Direct | Clean 1:1 or near-1:1 mapping exists | Translate automatically | | Approximate | Conceptual equivalent exists but semantics differ | Translate with caveats noted in the migration report | | Absent | No ZenML equivalent exists | Flag for human review with redesign suggestions |

See [references/concept-map.md](references/concept-map.md) for the full mapping tables.

The Migration Workflow

Phase 1: Receive and Analyze the Argo Workflow

Ask the user for all relevant migration inputs. At minimum, request:

  • the Argo YAML manifests (Workflow, WorkflowTemplate, ClusterWorkflowTemplate, CronWorkflow)
  • any referenced scripts, Python modules, container commands, or shell scripts
  • any EventSource / Sensor / trigger definitions if Argo Events is involved
  • any Kubernetes resources the workflow depends on (PVCs, service accounts, secrets, ConfigMaps, pod-spec patches)
  • any assumptions about cluster-local files, mounted volumes, or helper containers

Read everything thoroughly before doing anything else. For each workflow, identify:

  1. Object kinds -- Workflow, WorkflowTemplate, ClusterWorkflowTemplate, CronWorkflow, EventSource, Sensor
  2. Template types -- container, script, dag, steps, resource, http, suspend, plugin, data, containerSet
  3. Dependencies -- dependencies, enhanced depends, templateRef, workflowTemplateRef, workflow-of-workflows patterns
  4. Data flow -- workflow parameters, input parameters, output parameters from files, outputs.result, artifacts, globalName
  5. Control flow -- when, withItems, withParam, withSequence, continueOn, onExit, lifecycle hooks
  6. Execution policies -- retries, backoff, deadlines, memoization, synchronization, fail-fast settings
  7. Kubernetes coupling -- shared volumes, PVC templates, emptyDir, sidecars, init containers, node selectors, affinity, tolerations, service accounts
  8. Scheduling and triggers -- CronWorkflow schedules, concurrency policy, timezone, Argo Events integration
  9. Runtime contract -- whether a template is really value-based, path-based, or same-pod / same-filesystem coupled

Phase 2: Classify and Plan

For each component identified in Phase 1, classify it using the mapping type (direct / approximate / absent). Use the decision logic below and the full tables in [references/concept-map.md](references/concept-map.md).

Quick classification guide

Direct or near-direct translations (translate automatically):

  • workflow parameters -> pipeline parameters
  • template input parameters -> step function arguments
  • simple dag success-path dependencies -> pipeline step wiring
  • withSequence -> Python range(...) in a dynamic pipeline
  • retry count/delay -> StepRetryConfig(...)
  • memoization intent -> ZenML caching

Approximate translations (translate with caveats):

  • Workflow / WorkflowTemplate -> @pipeline plus a pipeline run or reusable Python module
  • CronWorkflow -> OSS/orchestrator-backed Schedule(...) on a supported orchestrator, with zenml pipeline schedule ... for supported lifecycle operations; ZenML Pro schedule triggers are separate snapshot trigger objects
  • container / script template -> @step with Python logic, DockerSettings, or subprocess.run(...)
  • output parameter via file or outputs.result -> explicit step return value
  • artifact passing -> ZenML artifacts and materializers
  • when on values -> dynamic pipeline branching or explicit soft-conditional logic
  • withItems / withParam -> dynamic fanout using real list artifacts and .map(); for dynamic pipelines, default to STOP_ON_FAILURE, use FAIL_FAST only with caveats, and do not recommend CONTINUE_ON_FAILURE
  • onExit -> redesign using hooks, idempotent cleanup, execution modes, or external cleanup control
  • resource / http templates -> explicit SDK or API calls inside steps
  • Kubernetes resources / placement settings -> orchestrator-specific settings documented as portability loss

Absent / redesign-first patterns (flag for human review):

  • enhanced depends expressions based on task status (A.Failed, B.Errored, etc.)
  • containerSet
  • suspend templates unless the target project is on a recent 0.94.x release with zenml.wait(...) support (preferably >=0.94.1), and even then only as an explicit redesign
  • shared PVC / emptyDir filesystem contracts across steps
  • sidecars, daemon containers, and same-pod helper services
  • synchronization mutexes / semaphores
  • Argo Events graphs (EventSource + Sensor + dependency logic); ZenML Pro platform-event triggers may cover supported ZenML platform lifecycle events, but they are not Argo Events graph parity
  • non-Python arbitrary images that cannot be sensibly wrapped in a Python-capable ZenML step environment
Present the migration plan

Before writing any code, present a summary to the user:

> "Here's what I found in your Argo workflow: > - Direct translations (will migrate cleanly): [list] > - Approximate translations (will work but with noted caveats): [list] > - Needs redesign (cannot auto-migrate): [list with brief explanation] > > Shall I proceed with the migration?"

If there are HIGH-severity flags, explain each one concretely: what the Argo workflow does, why ZenML cannot reproduce it directly, and what the redesign options look like.

Phase 3: Generate ZenML Code

Translate the Argo workflow into a ZenML project. Follow these conventions strictly.

Project structure

Every migrated project MUST use this layout:

migrated_pipeline/
├── steps/                    # One file per step
│   ├── extract.py
│   ├── transform.py
│   └── load.py
├── pipelines/
│   └── my_pipeline.py        # Pipeline definition
├── materializers/            # Custom materializers (if needed)
├── configs/
│   ├── dev.yaml
│   └── prod.yaml
├── run.py                    # CLI entry point (argparse, not click)
├── README.md
└── pyproject.toml

This matches the zenml-pipeline-authoring skill's conventions. Key rules:

  • one step per file in steps/
  • separate pipeline definition from execution
  • run.py uses argparse (click conflicts with ZenML)
  • pyproject.toml uses requires-python = ">=3.12" and zenml>=0.94.1 as the dependency floor
  • always generate configs/dev.yaml and configs/prod.yaml
  • always generate a README.md explaining what was migrated and what still needs manual attention
  • include concise migration comments in code, not essay-length explanations
  • run zenml init at the project root
Translation patterns

See [references/code-patterns.md](references/code-patterns.md) for side-by-side examples covering DAGs, steps templates, loops, conditionals, artifacts, CronWorkflows, exit handlers, shared-volume redesigns, and Argo Events integration patterns.

The core translation rule: move business logic out of YAML templates and into typed Python functions. Treat the YAML graph as a description of orchestration, then rebuild that orchestration in Python using step calls and artifact wiring.

# Argo mental model
# template "extract" writes a value to a file or stdout

# ZenML translation
@step
def extract() -> list[int]:
    return [1, 2, 3]

Parameters -> function arguments:

@pipeline
def training_pipeline(dataset: str, learning_rate: float = 0.1) -> None:
    prepared = prepare_data(dataset=dataset)
    train_model(data=prepared, learning_rate=learning_rate)

Output files / outputs.result -> step returns:

@step
def read_threshold() -> float:
    # Migration note: Argo previously read this from `valueFrom.path`.
    # ZenML treats the extracted value as a normal typed return.
    return 0.8

File artifacts -> typed artifacts or explicit Path contracts:

from pathlib import Path

@step
def produce_manifest() -> Path:
    output = Path("/tmp/manifest.json")
    output.write_text("{\"ok\": true}")
    return output

Use a file- or path-based contract only when the original workflow genuinely depends on file identity or layout. Otherwise prefer typed domain objects.

CronWorkflow -> Schedule:

from zenml.config.schedule import Schedule

schedule = Schedule(cron_expression="0 2 * * *")
my_pipeline.with_options(schedule=schedule)()

Always note that scheduling is orchestrator-dependent. In OSS, this is a Schedule(...) on a pipeline run, managed with singular zenml pipeline schedule ... commands where the orchestrator supports lifecycle operations. In ZenML Pro, schedule triggers are separate server-side trigger objects attached to snapshots (zenml trigger schedule create, attach, list, delete). CronWorkflow-specific behavior like timezone and concurrency policy may need extra handling.

Argo Events -> trigger redesign: Do not claim Argo Events parity. ZenML Pro platform-event triggers attach supported ZenML platform events to snapshots, but Argo EventSource/Sensor dependency graphs usually need external eventing plus a ZenML snapshot/API/deployment trigger design.

Suspend / pause-resume note:

If the source workflow uses suspend, do not present ZenML wait/resume as a generic drop-in replacement. Treat it as a redesign option that requires a recent 0.94.x release -- preferably zenml>=0.94.1, where zenml.wait(...) and pipeline run resume are documented in the official changelog.

Code comment style

Keep migration-related comments short and actionable:

  • use # Migration note: for brief inline caveats
  • use # TODO(migration): for unsupported patterns or manual follow-up
  • keep long explanations in the migration report, not in code
Handling approximate translations

When translating approximate patterns, add a brief note explaining the semantic shift:

@step
def run_cli(command: list[str]) -> str:
    # Migration note: Argo container templates can run any image + command.
    # This ZenML step runs in a Python-capable environment and wraps the CLI
    # with subprocess. Verify tooling is present in the step image.
    import subprocess

    completed = subprocess.run(command, check=True, text=True, capture_output=True)
    return completed.stdout
Handling absent patterns

For patterns that have no ZenML equivalent, do NOT silently approximate them. Instead:

  1. add a clearly marked # TODO(migration) comment in the generated code
  2. include the pattern in the migration report
  3. suggest a redesign approach
# TODO(migration): UNSUPPORTED -- Argo enhanced depends expression
# `cleanup` previously ran when `train.Failed || validate.Errored`.
# ZenML cannot branch on upstream failure states this way. Redesign with
# explicit status artifacts, hooks, or separate alerting/cleanup flows.
@step
def cleanup_after_failure(status: dict[str, bool]) -> None:
    ...

Phase 4: Produce the Migration Report

After generating the ZenML project, produce a MIGRATION_REPORT.md in the project root.

# Migration Report: [Argo Workflow] -> [ZenML Pipeline]

## Summary
- **Source**: Argo `[kind]` `[name]`
- **Target**: ZenML pipeline `[pipeline_name]`
- **Templates migrated**: X direct, Y approximate, Z flagged

## Direct Translations
| Argo Template / Concept | ZenML Equivalent | Notes |
|---|---|---|
| parameters | pipeline args | Clean translation |

## Approximate Translations
| Argo Template / Concept | ZenML Equivalent | What Changed |
|---|---|---|
| CronWorkflow | `Schedule(...)` or ZenML Pro schedule trigger | OSS schedule support depends on orchestrator and uses `zenml pipeline schedule ...`; Pro schedule triggers attach to snapshots; concurrency/timezone policy may need extra handling |

## Flagged for Review
| Argo Pattern | Severity | Issue | Suggested Redesign |
|---|---|---|---|
| containerSet | HIGH | No multi-container same-pod primitive in ZenML | Collapse into one step or externalize to Kubernetes-native service |

## Scheduling
- **Original**: CronWorkflow `0 2 * * *`, timezone `UTC`
- **Migrated OSS path**: `Schedule(cron_expression="0 2 * * *")`, managed with `zenml pipeline schedule ...` where supported
- **ZenML Pro option**: a schedule trigger attached to the target snapshot (`zenml trigger schedule create` + `zenml trigger schedule attach`)
- **Note**: Verify orchestrator scheduling support and any concurrency / timezone semantics

## Kubernetes-Native / Infrastructure Assumptions
| Original Argo Assumption | Migration Status | Notes |
|---|---|---|
| Shared PVC | Flagged | Redesign around artifacts or explicit external storage |

## Limitations and Key Differences
[Summarize the most important semantic shifts before listing benefits.]

## What's NOT Migrated
[List Argo features outside the portable ZenML scope: Sensors, EventSources, cluster policy, sidecars, etc.]

## What You Get for Free After Migration
- typed artifacts and artifact lineage
- step caching
- stack abstraction
- service connectors and secrets management
- Model Control Plane for ML workflows

## Recommended Next Steps
1. Run the `zenml-quick-wins` skill
2. Install the ZenML docs MCP server
3. Review every HIGH-severity redesign item
4. Use the `zenml-pipeline-authoring` skill for Docker settings, custom materializers, deployment, or deeper configuration

Phase 5: Suggest Next Steps

After migration is complete, always include a "Recommended Next Steps" section in the migration report AND communicate it to the user.

1. Run the zenml-quick-wins skill

Always suggest this as the immediate next step:

> "Now that the migration is done, I'd recommend running the zenml-quick-wins skill to add metadata logging, experiment tracking, alerters, and other production-readiness features."

2. Documentation links for flagged patterns

For every flagged pattern, include a link to the relevant ZenML documentation:

  • Scheduling: https://docs.zenml.io/how-to/steps-pipelines/scheduling
  • Dynamic pipelines: https://docs.zenml.io/how-to/steps-pipelines/dynamic-pipelines
  • ZenML Pro triggers: https://docs.zenml.io/getting-started/zenml-pro/triggers
  • Orchestrators: https://docs.zenml.io/stacks/stack-components/orchestrators
  • Containerization: https://docs.zenml.io/how-to/containerization/containerization
  • Secrets management: https://docs.zenml.io/how-to/secrets/secrets
  • Service connectors / auth: https://docs.zenml.io/how-to/infrastructure-deployment/auth-management
3. Suggest installing the ZenML docs MCP server

> "For easier access to ZenML documentation while you work, you can install the ZenML docs MCP server: claude mcp add zenmldocs --transport http https://docs.zenml.io/~gitbook/mcp"

4. Community support for unsupported patterns

When the migration has HIGH-severity flags, offer to help t

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.