Skip to content

tasks outputs that enrich context of dependent downstream tasks  #2385

@osher

Description

@osher

Description

Usecase

Consider a setup where many tasks needs same credentials for different operations.

Therefore, the logical thing is to have a task that reads creds that MUST NOT be persisted on disk from some secret manager, and passes them in-memory to all its dependents.

Current state

The only way I could find how to do it now - is have the "reader" task print something that the downstream stasks have to pass to eval - e.g. a step like - eval $(task creds).

version: '3'

tasks:
  creds:
    cmds:
    - echo "export USR=me; export PWD=top-secret!!;"
   
  operation1:
    cmds:
    - >
       eval $(task creds);
       some-cli-tool -u $USR -p $PWD some operation1

  operation2:
    deps: [creds]
    cmds:
    - >
       eval $(task creds);
       some-cli-tool -u $USR -p $PWD some operation2

That is less than ideal.
Firstly because it is platform-dependent and shell dependent.
Second - if I want to debug something - I should print it to >&2 - and that's also a shell specific thing.
Third - the eval must happen on every command - it is not persisted even on the task level... If I want to pass it to env - it gets very clunky:

tasks:
  creds:
    cmds:
    - vault read ...
   
  operation1:
    vars:
       USR:  { sh: task creds | jq.USR }
       PWD:  { sh: task creds | jq.PWD}
    cmds:
    - some-cli-tool-expects-ENV-vars operation3

this negates all the reuse beause the operation<#>.vars is coppied between all the operations that depend on creds :(

Proposal

I would propose tasks to have "outputs", similar to how outputs work in GitHub actions, just less cumbersome...

e.g:

version: '3'

tasks:
  creds:
    vars:
      JSON:
        sh: aws sts get-parameter .... | jq -r .Parameter.Value
      USR: 
        sh: echo {{.JSON}} | jq .USR
        output: true  # makes $USR available on context of dependent tasks
      PWD: 
        sh: echo {{.JSON}} | jq .PWD
        output: { as: SVC_API_KEY } # makes it available on context of dependent tasks as `SVC_API_KEY`

  operation1:
    deps: [creds]
    cmds:
    - some-cli-tool -u $USR some operation1 # assumes SVC_API_KEY

Mind that on operation1 - it explicitly uses $USR and not {{.USR}} so that the value is not spat to screen.

It would be nice to support secret mode if the scope allows it:

  creds:
    vars:
      JSON:
        sh: aws sts get-parameter .... | jq -r .Parameter.Value
      USR: 
        sh: echo {{.JSON}} | jq .USR
        output: true  # make it available on contexts of dependent tasks
      PWD:
         sh: echo {{.JSON}} | jq .PWD
         output: true
         secret: true  # truncates the secret from being print, replacing it with `<secret>`

         # more suggested forms that worth considering to be supported:
         # (but if it makes the scope too big - it can be dealt in a separate feature PR)

         # secret: { replace: '..shh!!' }  - when print to logs - replaces each secret with `...shh!!` (you control the string)
         # secret: { mask: '*' }  - replaces every character with a `*`, so the length of the secret is visible
         # secret: { peek: 4, replace: true }  - keeps the first `peek` character visible 
         #         and replaces all the rest with `replace` so the output confirms you got the right secret, 
         #         but it is never spat raw.
         # secret: { peek: 4, replace: '<truncated>' }  - same like previous, but you control the replacement string
         # secret: { peek: 4, mask: '*' } - keeps the first `peek` character visible and replaces the rest of characters with `mask`
         #         so the secret can be identified also by the length as an additional confirmation
         #         but it is never spat raw.

Metadata

Metadata

Assignees

No one assigned

    Labels

    state: needs triageWaiting to be triaged by a maintainer.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions