AAP 2.6 Workflow Templates: Advanced Multi-Step Automation Guide
By Luca Berton · Published 2024-01-01 · Category: troubleshooting
Master AAP 2.6 Workflow Templates for multi-step automation pipelines. Build complex workflows with approval nodes, convergence, inventory overrides, and error.
What Are Workflow Templates in AAP 2.6?
Workflow Templates in Ansible Automation Platform 2.6 let you chain multiple job templates, project syncs, inventory updates, and approval gates into a single automated pipeline. Unlike running individual job templates, workflows provide branching logic, error handling, convergence points, and variable passing between steps.
Workflows are essential for enterprise automation patterns like multi-tier application deployments, change management processes, and disaster recovery procedures.
See also: AAP 2.6 Job Templates and Inventories: Complete Configuration Guide
Creating a Basic Workflow
Via the Platform Gateway UI
Navigate to Automation Controller → Templates → Add → Add workflow template Configure the workflow template settings: • Name: Descriptive name for the workflow • Organization: The owning organization • Inventory: Default inventory (can be overridden per node) • Labels: Optional tags for filtering Open the Workflow Visualizer to add nodes and connectionsVia the ansible.platform Collection
- name: Create a deployment workflow
ansible.platform.workflow_job_template:
controller_host: "{{ gateway_url }}"
controller_username: "{{ controller_user }}"
controller_password: "{{ controller_pass }}"
name: "Application Deployment Pipeline"
organization: "Operations"
inventory: "Production Servers"
ask_variables_on_launch: true
survey_enabled: true
state: present
Workflow Node Types
AAP 2.6 supports five types of workflow nodes:
| Node Type | Purpose | Use Case | |-----------|---------|----------| | Job Template | Run a playbook | Deploy, configure, test | | Workflow Job Template | Nest another workflow | Reusable sub-workflows | | Project Sync | Update project from SCM | Ensure latest code before deploy | | Inventory Source Sync | Refresh dynamic inventory | Get current cloud hosts | | Approval | Pause for human approval | Change management gates |
Approval Nodes
Approval nodes pause workflow execution until an authorized user approves or denies:
- name: Add approval node to workflow
ansible.platform.workflow_job_template_node:
controller_host: "{{ gateway_url }}"
controller_username: "{{ controller_user }}"
controller_password: "{{ controller_pass }}"
workflow_job_template: "Application Deployment Pipeline"
identifier: "production-approval"
approval_node:
name: "Approve Production Deploy"
description: "Review staging results before production deployment"
timeout: 3600 # 1 hour timeout
state: present
See also: Ansible Automation Platform 2.6 Architecture and Components: Complete Guide
Branching Logic: Success, Failure, Always
Each workflow node connection has a condition: • On Success (green): Next node runs only if the previous succeeded • On Failure (red): Next node runs only if the previous failed • On Always (blue): Next node runs regardless of previous result
Example: Deploy with Rollback
[Project Sync] → success → [Deploy to Staging]
↓ success ↓ failure
[Run Integration Tests] [Notify: Deploy Failed]
↓ success ↓ failure
[Approval Gate] [Rollback Staging]
↓ success ↓ always
[Deploy to Prod] [Notify: Rollback Done]
↓ failure
[Rollback Production]
# Define workflow nodes with branching
- name: Add project sync node
ansible.platform.workflow_job_template_node:
workflow_job_template: "Application Deployment Pipeline"
identifier: "project-sync"
unified_job_template: "Sync App Repository"
state: present
- name: Add staging deploy node (on sync success)
ansible.platform.workflow_job_template_node:
workflow_job_template: "Application Deployment Pipeline"
identifier: "deploy-staging"
unified_job_template: "Deploy Application"
extra_data:
target_env: staging
success_nodes:
- "project-sync"
state: present
- name: Add rollback node (on staging failure)
ansible.platform.workflow_job_template_node:
workflow_job_template: "Application Deployment Pipeline"
identifier: "rollback-staging"
unified_job_template: "Rollback Application"
extra_data:
target_env: staging
failure_nodes:
- "deploy-staging"
state: present
Convergence
Convergence lets a node wait for multiple parent nodes to complete before executing. This is useful when parallel tasks must all finish before proceeding:
[Update Load Balancers] → success →
[Update DNS Records] → success → [Verify Connectivity] → [Notify Complete]
[Update Firewall Rules] → success →
The Verify Connectivity node has convergence: all — it waits for all three parent nodes to succeed before running.
Set convergence in the UI via the node settings, or via API:
- name: Add convergence node
ansible.platform.workflow_job_template_node:
workflow_job_template: "Network Update Pipeline"
identifier: "verify-connectivity"
unified_job_template: "Verify Network Connectivity"
success_nodes:
- "update-lb"
- "update-dns"
- "update-fw"
all_parents_must_converge: true
state: present
See also: AAP 2.6 Backup, Restore, and Disaster Recovery Guide
Passing Variables Between Nodes
Workflow nodes can pass data using set_stats in playbooks:
# In the first job template's playbook
- name: Get deployment version
ansible.builtin.set_fact:
deployed_version: "2.4.1"
- name: Pass version to workflow
ansible.builtin.set_stats:
data:
app_version: "{{ deployed_version }}"
deploy_timestamp: "{{ ansible_date_time.iso8601 }}"
Subsequent nodes in the workflow can access app_version and deploy_timestamp as extra variables.
Artifact Passing Example
# Node 1: Gather server info
- name: Collect server facts
ansible.builtin.setup:
gather_subset: [hardware, network]
- name: Export to workflow
ansible.builtin.set_stats:
data:
total_memory_mb: "{{ ansible_memtotal_mb }}"
primary_ip: "{{ ansible_default_ipv4.address }}"
# Node 2: Use gathered info
- name: Configure monitoring
ansible.builtin.template:
src: monitoring.conf.j2
dest: /etc/monitoring/agent.conf
vars:
server_memory: "{{ total_memory_mb }}"
server_ip: "{{ primary_ip }}"
Inventory and Credential Overrides
Override the default inventory or credentials per workflow node:
- name: Deploy to staging (different inventory)
ansible.platform.workflow_job_template_node:
workflow_job_template: "Multi-Environment Deploy"
identifier: "staging-deploy"
unified_job_template: "Deploy Application"
inventory: "Staging Servers"
credentials:
- "SSH Key - Staging"
- "Vault - Staging Secrets"
state: present
- name: Deploy to production (different inventory)
ansible.platform.workflow_job_template_node:
workflow_job_template: "Multi-Environment Deploy"
identifier: "production-deploy"
unified_job_template: "Deploy Application"
inventory: "Production Servers"
credentials:
- "SSH Key - Production"
- "Vault - Production Secrets"
success_nodes:
- "staging-deploy"
state: present
Surveys for Runtime Input
Add surveys to collect input at launch time:
- name: Configure workflow survey
ansible.platform.workflow_job_template:
name: "Application Deployment Pipeline"
survey_enabled: true
survey_spec:
name: "Deployment Parameters"
description: "Provide deployment details"
spec:
- question_name: "Application Version"
variable: "app_version"
type: "text"
required: true
default: "latest"
- question_name: "Target Environment"
variable: "target_env"
type: "multiplechoice"
choices: ["staging", "production"]
required: true
- question_name: "Skip Tests"
variable: "skip_tests"
type: "multiplechoice"
choices: ["yes", "no"]
default: "no"
Scheduling Workflows
Schedule workflows to run on a recurring basis:
- name: Schedule nightly deployment
ansible.platform.schedule:
controller_host: "{{ gateway_url }}"
controller_username: "{{ controller_user }}"
controller_password: "{{ controller_pass }}"
name: "Nightly Staging Deploy"
unified_job_template: "Application Deployment Pipeline"
rrule: "DTSTART:20260101T020000Z RRULE:FREQ=DAILY;INTERVAL=1"
extra_data:
target_env: staging
app_version: latest
state: present
Enterprise Workflow Patterns
Pattern 1: Rolling Application Update
[Disable Monitoring] → [Remove from LB Pool]
↓ success
[Stop Application]
↓ success
[Deploy New Version]
↓ success
[Run Health Check]
↓ success ↓ failure
[Add to LB Pool] [Rollback Version]
↓ success ↓ always
[Enable Monitoring] [Alert Operations]
Pattern 2: Multi-Cloud Provisioning
[Provision AWS VMs] → success →
[Provision Azure VMs] → success → [Configure All Hosts] → [Deploy App]
[Provision GCP VMs] → success →
Pattern 3: Compliance Audit and Remediation
[Scan for Compliance] → success → [Generate Report]
↓ failure
[Auto-Remediate]
↓ success
[Re-Scan Compliance]
↓ success ↓ failure
[Close Ticket] [Escalate to Team]
Monitoring Workflow Execution
Track workflow status via API:
# Get workflow job status
curl -s -k -H "Authorization: Bearer $TOKEN" \
"https://gateway.example.org/api/controller/v2/workflow_jobs/42/" | \
jq '{id: .id, name: .name, status: .status, started: .started, finished: .finished}'
# List workflow job nodes with results
curl -s -k -H "Authorization: Bearer $TOKEN" \
"https://gateway.example.org/api/controller/v2/workflow_jobs/42/workflow_nodes/" | \
jq '.results[] | {identifier: .identifier, status: .summary_fields.job.status}'
Best Practices
• Keep workflows modular — use nested workflows for reusable sub-processes • Set timeouts on approval nodes — prevent workflows from hanging indefinitely • Useset_stats sparingly — only pass essential data between nodes
• Always include failure paths — rollback and notification nodes for every critical step
• Name nodes descriptively — use identifiers that explain the step's purpose
• Test in staging first — use inventory overrides to run the same workflow in staging before production
• Version control workflows — export workflow definitions as YAML and store in Git
FAQ
Can workflows call other workflows?
Yes. You can add a Workflow Job Template node inside another workflow. This lets you create reusable sub-workflows — for example, a "Deploy Application" workflow nested inside both a "Full Release" and "Hotfix" workflow.
What happens if an approval node times out?
If the configured timeout expires without approval or denial, the approval node is marked as timed out (failed). Any nodes connected via the failure path will execute.
Can I retry a failed workflow from the point of failure?
Not directly from the UI. You can relaunch the entire workflow, but it re-runs from the beginning. Design workflows with idempotent steps so re-running is safe. Use set_stats to track progress if needed.
How many nodes can a workflow have?
There is no hard-coded limit on workflow nodes, but very large workflows (100+ nodes) can impact visualization performance and become difficult to maintain. Break large workflows into nested sub-workflows.
Can different nodes use different credentials?
Yes. Each workflow node can override the workflow's default credentials with node-specific credentials. This is essential for multi-environment deployments where staging and production use different SSH keys or vault passwords.
Conclusion
Workflow Templates transform AAP from a job runner into a full automation orchestration platform. By combining branching logic, convergence, approval gates, and variable passing, you can model complex enterprise processes as repeatable, auditable automation pipelines.
Related Articles
• AAP 2.6 Architecture and Components: Complete Guide • AAP 2.6 RBAC and Gateway API • AAP 2.6 Event-Driven Ansible Enhancements • AAP 2.6 Configuration as Code with ansible.platform • AAP 2.6 Security Best PracticesCategory: troubleshooting