Skip to content

Support passing parameters (vars:) to runbooks called from the needs: section #1492

Description

@k2tzumi

Summary

I'd like to propose allowing parameters (e.g. vars:) to be passed to runbooks invoked from the needs: section, so that a single "fixture / provisioning" runbook can be reused across many scenarios with different inputs.

Currently needs: only accepts a key-to-path mapping:

needs:
  prebook: path/to/prebook.yml
  prebook2: path/to/prebook2.yml

There is no way to parameterize the called runbook, so variations of the same fixture have to be created as separate runbook files.

Motivation / Use case

I want to use needs: runbooks as common fixture / provisioning templates to minimize the amount of dependent data each scenario has to own. This is primarily for regression testing, where I don't want to keep increasing the number of test accounts.

Concretely, my goals are:

  • Reduce total test execution time. Shared, expensive setup should run only once.
  • Make dependencies easy to manage. The dependent data effectively becomes the identifier of the needs:, which is easier to reason about than duplicating similar data everywhere.
  • Register SaaS provisioning data. Many features need to be verified; the scenarios themselves have few dependencies, but provisioning data is always required and is expensive to create (authentication & authorization data must be set up).
  • Avoid mass-producing near-identical data/runbooks.

Why the existing options don't fully cover this

needs:

needs: already deduplicates the same runbook across scenarios (via lo.Uniq in sortWithNeeds), so "run the shared setup only once" is effectively achieved and I don't have to write any "already executed?" guard in my scenarios. This is exactly why needs: is attractive for shared/expensive provisioning.

However, because needs: takes only map[string]string (key → path), I cannot pass vars:. When I need data variations, I'm forced to duplicate the runbook, which leads to a lot of near-identical runbooks.

include:

include: does support vars:, but it runs every time and is not deduplicated. To reuse a shared fixture with include:, I'd have to implement an "is it already executed?" check inside my scenarios myself, which is exactly the boilerplate I want to avoid.

So there is a gap between the two mechanisms:

Need needs: include:
Run shared setup only once (dedup) ✅ automatic ❌ must guard manually
Pass parameters (vars:) ❌ not supported ✅ supported

The goal of this request is to close that gap: keep the "run once / declarative dependency" behavior of needs:, while allowing parameterization like include:.

Proposed idea

Allow a vars:-like input for needs: entries, e.g. (syntax is just for illustration):

needs:
  admin_account:
    path: path/to/provision_account.yml
    vars:
      role: admin
  member_account:
    path: path/to/provision_account.yml
    vars:
      role: member

Bound values would still be referenced via needs.<key>.* as today.

Points to discuss

I understand needs: and runbook-to-runbook interaction is a sensitive area (the Include + needs: combination in #1002 was reverted once and reworked in #1006, and #1017 addressed result overwriting), so I'd like to raise the following design points:

  • Dedup key design: should two needs: entries that point to the same path but have different vars: be treated as distinct executions? (i.e. how should lo.Uniq in sortWithNeeds account for vars:?)
  • Result structure: impact on needs.<key> results when the same path is run multiple times with different parameters.
  • Backward compatibility: the existing needs: { key: path } shorthand should keep working unchanged.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions