Home > Software engineering >  Unable to pass output parameters from one workflowTemplate to a workflow via another workflowTemplat
Unable to pass output parameters from one workflowTemplate to a workflow via another workflowTemplat

Time:01-30

I've Two workflowTemplates generate-output, lib-read-outputs and One workflow output-paramter as follows

  1. generate-output.yaml
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
  name: generate-output
spec:
  entrypoint: main
  templates:
    - name: main
      dag:
        tasks:

          # Generate Json for Outputs
          - name: read-outputs
            arguments:
              parameters:
                - name: outdata
                  value: |
                    {
                      "version": 4,
                      "terraform_version": "0.14.11",
                      "serial": 0,
                      "lineage": "732322df-5bd43-6e92-8f46-56c0dddwe83cb4",
                      "outputs": {
                        "key_alias_arn": {
                          "value": "arn:aws:kms:us-west-2:123456789:alias/tetsing-key",
                          "type": "string",
                          "sensitive": true
                        },
                        "key_arn": {
                          "value": "arn:aws:kms:us-west-2:123456789:alias/tetsing-key",
                          "type": "string",
                          "sensitive": true
                        }
                      }
                    }
            template: retrieve-outputs

    # Create Json
    - name: retrieve-outputs
      inputs:
        parameters:
          - name: outdata
      script:
        image: 145565074481.dkr.ecr.us-west-2.amazonaws.com/infssdev-or-infpl-python:v3
        command: [python]
        env:
          - name: OUTDATA
            value: "{{inputs.parameters.outdata}}"
        source: |
          import json
          import os
          OUTDATA = json.loads(os.environ["OUTDATA"])
          with open('/tmp/templates_lst.json', 'w') as outfile:
            outfile.write(str(json.dumps(OUTDATA['outputs'])))
        volumeMounts:
          - name: out
            mountPath: /tmp
      volumes:
        - name: out
          emptyDir: { }
      outputs:
        parameters:
          - name: message
            valueFrom:
              path: /tmp/templates_lst.json

  1. lib-read-outputs.yaml
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
  name: lib-read-outputs
spec:
  entrypoint: main
  templates:
    - name: main
      dag:
        tasks:
          # Read Outputs
          - name: lib-wft
            templateRef:
              name: generate-output
              template: main
  1. output-paramter.yaml
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: output-paramter-
spec:
  entrypoint: main
  templates:
    - name: main
      dag:
        tasks:
          # Json Output data task1
          - name: wf
            templateRef:
              name: lib-read-outputs
              template: main

          - name: lib-wf2
            dependencies: [wf]
            arguments:
              parameters:
                - name: outputResult
                  value: "{{tasks.wf.outputs.parameters.message}}"
            template: whalesay

    - name: whalesay
      inputs:
        parameters:
          - name: outputResult
      container:
        image: docker/whalesay:latest
        command: [cowsay]
        args: ["{{inputs.parameters.outputResult}}"]

I am trying to pass the output parameters generated in workflowTemplate generate-output to workflow output-paramter via lib-read-outputs

When I execute them, it's giving the following error - Failed: invalid spec: templates.main.tasks.lib-wf2 failed to resolve {{tasks.wf.outputs.parameters.message}}

CodePudding user response:

DAG and steps templates don't produce outputs by default

DAG and steps templates do not automatically produce their child templates' outputs, even if there is only one child template.

For example, the no-outputs template here does not produce an output, even though it invokes a template which does have an output.

apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
spec:
  templates:
  - name: no-outputs
    dag:
      tasks:
      - name: get-an-artifact
        template: get-an-artifact

This lack of outputs makes sense if you consider a DAG template with multiple tasks:

apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
spec:
  templates:
  - name: no-outputs
    dag:
      tasks:
      - name: get-an-artifact
        template: get-an-artifact
      - name: get-another-artifact
        depends: get-an-artifact
        template: get-another-artifact

Which task's outputs should no-outputs produce? Since it's unclear, DAG and steps templates simply do not produce outputs by default.

You can think of templates as being like functions. You wouldn't expect a function to implicitly return the output of a function it calls.

def get_a_string():
    return "Hello, world!"

def call_get_a_string():
    get_a_string()

print(call_get_a_string())  # This prints nothing.

But a DAG or steps template can forward outputs

You can make a DAG or a steps template forward an output by setting its outputs field.

apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
  name: get-artifacts-wftmpl
spec:
  templates:
  - name: get-artifacts
    dag:
      tasks:
      - name: get-an-artifact
        template: get-an-artifact
      - name: get-another-artifact
        depends: get-an-artifact
        template: get-another-artifact
    # This is the critical part!
    outputs:
      artifacts:
      - name: artifact-1
        from: "{{tasks.get-an-artifact.outputs.artifacts.artifact-name}}"
      - name: artifact-2
        from: "{{tasks.get-another-artifact.outputs.artifacts.artifact-name}}"
---
apiVersion: argoproj.io/v1alpha1
kind: Workflow
spec:
  templates:
  - name: print-artifact
    dag:
      tasks:
      - name: get-artifacts
        templateRef:
          name: get-artifacts-wftmpl
          template: get-artifacts 
      - name: print-artifact
        template: print-artifact
        arguments:
          outputs:
          - name: artifact
            from: "{{tasks.get-artifacts.outputs.artifacts.artifact-1}}"

To continue the Python analogy:

def get_a_string():
    return "Hello, world!"

def call_get_a_string():
    return get_a_string()  # Add 'return'.

print(call_get_a_string())  # This prints "Hello, world!".

So, in your specific case...

  1. Add an outputs section to the main template in the generate-output WorkflowTemplate to forward the output artifact from the retrieve-outputs template.

    apiVersion: argoproj.io/v1alpha1
    kind: WorkflowTemplate
    metadata:
      name: generate-output
    spec:
      entrypoint: main
      templates:
        - name: main
          outputs:
            artifacts:
              - name: message
                from: "{{tasks.read-outputs.outputs.artifacts.message}}"
          dag:
            tasks:
              # ... the rest of the file ...
    
    
  2. Add an outputs section to the main template in the lib-read-outputs WorkflowTemplate to forward generate-output's artifact.

    apiVersion: argoproj.io/v1alpha1
    kind: WorkflowTemplate
    metadata:
      name: lib-read-outputs
    spec:
      entrypoint: main
      templates:
        - name: main
          outputs:
            artifacts:
              - name: message
                from: "{{tasks.lib-wft.outputs.artifacts.message}}"
          dag:
            tasks:
              # ... the rest of the file ...
    
  •  Tags:  
  • Related