Alexander Reshytko
Alexander Reshytko

Reputation: 2246

Dynamically provide an image name for the container template

Is there a way to provide an image name for the container template dynamically based on its input parameters?

We have more than 30 different tasks each with its own image and that should be invoked identically in a workflow. The number may vary each run depending on the output of a previous task. So we don't want to or even can't just hardcode them inside workflow YAML.

An easy solution would be to provide the image field for the container depending on the input parameter and have the same template for each of these tasks. But looks like it's impossible. This workflow doesn't work:

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: hello-world-
spec:
  entrypoint: whalesay

  templates:
  - name: whalesay
    inputs:
      parameters:
        - name: image
          default: whalesay:latest
    container:
      image: "docker/{{image}}"
      command: [cowsay]
      args: ["hello world"]

Is there some workaround for this particular case?

Also is there a document somewhere describing in which fields one can use workflow variables? Documentation page says only:

Some fields in a workflow specification allow for variable references which are automatically substituted by Argo.

Upvotes: 3

Views: 2727

Answers (2)

crenshaw-dev
crenshaw-dev

Reputation: 8392

What you’re trying to do is definitely supported. Just change {{image}} to the fully qualified variable name {{inputs.parameters.image}}.

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

There is currently no documentation listing template-able fields. But there is an open issue for adding that documentation.

Upvotes: 5

Alexander Reshytko
Alexander Reshytko

Reputation: 2246

This is a possible workaround: to use when and conditional run of a task. We need to list of all possible tasks with their container images though:

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: test-dynamic-image-
spec:
  entrypoint: main

  templates:
  - name: main
    steps:
    - - name: fanout-step
        template: fanout
    - - name: loop-step
        template: options
        arguments:
          parameters:
          - name: code
            value: "{{item}}"
        withParam: "{{steps.code-step.outputs.parameters.codes}}"

  - name: fanout
    script:
      image: python:alpine3.6
      command: [python]
      source: |
        import json
        with open("/tmp/codes.json", 'w') as wf:
          json.dump(["foo", "bar", "buz"], wf)
    outputs:
      parameters:
        - name: codes
          valueFrom:
            path: /tmp/codes.json

  - name: foo-code
    script:
      image: python:alpine3.6
      command: [ python ]
      source: |
        print("foo-code")

  - name: bar-code
    script:
      image: python:alpine3.6
      command: [ python ]
      source: |
        print("bar-code")

  - name: buz-code
    script:
      image: python:alpine3.6
      command: [ python ]
      source: |
        print("buz-code")

  - name: missed-code
    script:
      image: python:alpine3.6
      command: [ python ]
      source: |
        print("THIS SHOULD NOT BE PRINTED")

  - name: options
    inputs:
      parameters:
        - name: code
    steps:
    - - name: foo-code-option
        template: foo-code
        when: "{{inputs.parameters.code}} == foo"
      - name: bar-code-option
        template: bar-code
        when: "{{inputs.parameters.code}} == bar"
      - name: buz-code-option
        template: buz-code
        when: "{{inputs.parameters.code}} == buz"
      - name: missed-code-option
        template: missed-code
        when: "{{inputs.parameters.code}} == missed"

Upvotes: 0

Related Questions