Skip to content

[RFE] Enhanced Workflow Artifacts: GUI Visibility, Secret Masking, and Artifact-Conditional Connectors #505

Description

@fernandorocagonzalez

Please confirm the following

  • I have checked the current issues for duplicates.
  • I understand that Ascender is open source software provided for free and that I might not receive a timely response.

Feature type

New Feature

Feature Summary

Summary

Workflow connectors in Ascender only support three types: on success, on failure, and always. There is no way to route workflow execution based on what actually happened inside a job beyond pass/fail.

This feature request proposes a fourth connector type that evaluates a condition against the parent node's artifacts (set_stats data) to decide whether to activate the downstream node.

Problem

Artifacts produced via ansible.builtin.set_stats are already persisted in the database and passed downstream as extra_vars. The data is there, but the workflow engine ignores it when deciding which nodes to activate next.

This forces users into workarounds like:

  • A "router" job template that deliberately fails based on a condition, just to abuse the failure path toward the desired next node
  • Cramming all branching logic inside a single monolithic playbook instead of using the workflow engine, because the workflow can't express "run node B only if artifact X equals Y"
  • Wrapping the real logic in a workflow that calls sub-workflows, adding unnecessary complexity

These workarounds are brittle, hard to maintain, and defeat the purpose of having a visual workflow orchestrator.

Proposal

Introduce a fourth connector type, something like on condition, where you define an expression that gets evaluated against the parent node's artifacts after the job completes.

How it would work

A condition on an edge would have three fields:

  • artifact_key: the artifact key to evaluate (e.g. environment)
  • operator: comparison operator (==, !=, in, etc.)
  • expected_value: the value to compare against (e.g. production)

A node connected via a conditional edge would only activate if the parent job completed successfully AND the condition evaluates to true. A failed job should not trigger condition paths (same as on success in that regard).

Example

[Check Environment]
    |-- on_condition (environment == "production")  --> [Deploy to Prod]
    |-- on_condition (environment == "staging")     --> [Deploy to Staging]
    '-- on_failure                                  --> [Notify Failure]

The playbook in "Check Environment" would simply do:

- name: Set deployment target
  ansible.builtin.set_stats:
    data:
      environment: "{{ target_env }}"

Phased approach

Phase 1 (MVP): Simple key-value equality only (artifact_key == expected_value). This covers the majority of real use cases and keeps the scope manageable.

Phase 2: Extended operators (!=, in, >=, etc.), multiple conditions per edge with AND/OR logic, and potentially Jinja2 expression evaluation for more complex scenarios.

Areas of the codebase affected (preliminary)

  • Models: new fields on the workflow node edge relationship, or a new model for conditional edges
  • Workflow engine (task manager): evaluation logic when determining which downstream nodes to activate after a job completes
  • API: serializers and viewsets for CRUD on condition configuration
  • UI: workflow visualizer updates with a new connector style and a configuration modal for setting the condition
  • Migrations: backward-compatible schema migration, existing workflows would not be affected

Prior art

This specific feature has never been formally requested in upstream AWX. The upstream project treats artifacts purely as a data-passing mechanism and has never explored using them for routing decisions. This would be a differentiating capability for Ascender.

Some related upstream issues that show broader community interest in improving the artifact system:

Willingness to contribute

I am happy to develop this and submit a PR. I would prefer to get feedback on the design before investing time in code. Specifically:

  1. Is this something that fits with Ascender's roadmap?
  2. Are there ongoing refactors or architectural constraints I should know about?
  3. Any preferences on how to structure the PR?

I have previous contribution experience with the Ascender codebase (merged PR fixing UnifiedJob.save() / finished timestamp handling).

Open to discussing the design further.

Select the relevant components

  • UI
  • API
  • Docs
  • Collection
  • CLI
  • Other

Steps to reproduce

Just create any workflow

Current results

No direct capacity to orchestrate connectors between jt

Sugested feature result

Introduce a fourth connector type, something like on condition, where you define an expression that gets evaluated against the parent node's artifacts after the job completes.

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions