6

Is it possible to use Helm to deploy Argo workflows? I get an error like below when I do a helm install

Error: UPGRADE FAILED: parse error at (workflows/templates/my_dag.yaml:47): function "workflow" not defined

The yaml itself has both Argo and Helm interpolations with {{..}}. I understand why it fails. Is there a way around this?

I've had a look at this but it does not look like something I want to do as it sort of changes the syntax.

crenshaw-dev
  • 7,504
  • 3
  • 45
  • 81
ss_everywhere
  • 439
  • 7
  • 19

3 Answers3

10

It is possible. I've been on a team that regularly deployed Helm-templated WorkflowTemplates.

There are two ways to work around the Helm/Argo template tag collision. (As you know, the issue is that Helm's Go templating language and Argo's templating language both use {{}} to denote templated areas.)

Option 1:

The first way is to carefully nest the tags. For example, if I want to use {{steps.hello-world.result}} as an Argo-template, I can write it as {{`{{steps.hello-world.result}}`}}. The outer {{ tells Helm to start interpreting templated code. The backtick tells Helm to interpret the backtick-delimited contents literally. And finally, the inner {{ is installed in the cluster as a plain-text part of the Workflow and eventually interpreted by Argo as a template.

Here's a modified version of the arguments-parameters example modified to be deployed with Helm.

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: arguments-parameters-
spec:
  entrypoint: whalesay
  arguments:
    parameters:
    - name: message
      value: hello world
  templates:
  - name: whalesay
    inputs:
      parameters:
      - name: message
    container:
      image: docker/whalesay:latest
      command: [cowsay]
      args: ["{{`{{inputs.parameters.message}}`}}"]

Option 2:

The second work-around is described in the blog post you linked. That approach does change the syntax. The first approach uses a funny-looking syntax, but it is still technically just Helm's and Argo's default syntax.

If the {{`{{yikes}}`}} work-around doesn't solve your error message, please post the whole workflow (or a redacted/simplified version), and I'd be happy to take a look.

Related:

The above is for Argo-in-Helm (Jinja2-in-Go) templating. If you need somethingelse-in-Argo (somethingelse-in-Jinja2) templating, where somethingelse also uses {{, check out this answer: How to escape "{{" and "}}" in argo workflow

crenshaw-dev
  • 7,504
  • 3
  • 45
  • 81
  • Do you have an example.? I escaped the {{ and shows as chart is installed, but I could see the workflow template or workflows when listed. – saranya elumalai Feb 08 '21 at 16:56
  • @saranyaelumalai added an example – crenshaw-dev Feb 08 '21 at 17:03
  • @saranyaelumalai sounds like that could be any number of issues... you should probably open a new question. I'll see it, I lurk on the `argo-workflow` tag. :-) – crenshaw-dev Feb 08 '21 at 17:07
  • @crenshaw-dev I've been working with this syntax for a while now and still didn't figure out how the correct syntax for an evaluation with a parameter in the string looks like, example: value:'{{`{{= inputs.parameters.repo == "devops" ? inputs.parameters.path : "kubernetes/{{inputs.parameters.repo}}" }}`}}' Can you help me here? – JDK92 May 20 '22 at 11:41
  • @JDK92 I don't really like nesting Argo Workflows interpolation tags. Technically I think it's supposed to work, but I don't trust it. I'd do something like this: `{{= inputs.parameters.repo == "devops" ? inputs.parameters.path : ("kubernetes/" + inputs.parameters.repo)}}`. Of course wrap that expression in the Helm string literal syntax. – crenshaw-dev May 20 '22 at 13:04
0

It Option1 fail an other workaround can be

{{ "{{inputs.parameters.message}}"|quote}}
Thomas
  • 1
  • 1
0

I've just had this issue and tried crenshaw-dev's solution, and it didn't work. Helm would throw the following message multiple times:

unable to parse YAML: error converting YAML to JSON: yaml: invalid map key: map[interface {}]interface {}{"tasks.data-formatting.outputs.parameters.employee-username-enc":interface {}(nil)}

The way I fixed it was by wrapping the escaped Argo statements with double quotes, like so:

# ...
arguments:
  parameters:
    - name: first-name
      value: "{{ `{{tasks.data-formatting.outputs.parameters.employee-username-enc}}` }}"

After

Hope it helps!