At Red Hat Tech Day Netherlands 2026 (Bunnik, 3 June 2026), Fred van Zwieten and Ismail Dhaoui demoed the new Automation Portal in Ansible Automation Platform 2.7 — a self-service template gallery where operators hit "Start" without knowing where a playbook lives or how it's configured. One catalog entry, Network - Firewall Rule Request, submits a firewall rule change for an approval workflow instead of applying it directly. Here's a runnable playbook that mirrors that pattern.

Example playbook

---
- name: "Network - Firewall Rule Request"
  hosts: localhost
  gather_facts: false
  vars:
    requester: "jdoe"
    ticket_id: "CHG0012345"
    firewall_rule:
      name: "allow-app-to-db"
      source: "10.10.20.0/24"
      destination: "10.10.30.15/32"
      port: 5432
      protocol: "tcp"
      action: "permit"
    approval_workflow_id: "fw-change-approval"

  tasks:
    - name: Validate required rule fields are present
      ansible.builtin.assert:
        that:
          - firewall_rule.name is defined
          - firewall_rule.source is defined
          - firewall_rule.destination is defined
          - firewall_rule.port is defined
        fail_msg: "Firewall rule request is missing required fields"

    - name: Build the change request payload
      ansible.builtin.set_fact:
        change_request:
          requested_by: "{{ requester }}"
          ticket: "{{ ticket_id }}"
          rule: "{{ firewall_rule }}"
          status: "pending_approval"

    - name: Submit rule request to approval workflow
      ansible.builtin.uri:
        url: "https://itsm.example.com/api/v1/workflows/{{ approval_workflow_id }}/requests"
        method: POST
        body_format: json
        body: "{{ change_request }}"
        status_code: 201
      register: submission
      delegate_to: localhost

    - name: Wait for approval decision
      ansible.builtin.uri:
        url: "https://itsm.example.com/api/v1/requests/{{ submission.json.id }}"
        method: GET
      register: decision
      until: decision.json.status in ['approved', 'rejected']
      retries: 60
      delay: 30
      delegate_to: localhost

    - name: Apply approved rule to firewall
      when: decision.json.status == 'approved'
      cisco.asa.asa_config:
        lines:
          - "access-list OUTSIDE_IN extended {{ firewall_rule.action }} {{ firewall_rule.protocol }} {{ firewall_rule.source }} {{ firewall_rule.destination }} eq {{ firewall_rule.port }}"
        save_when: modified

    - name: Report rejected request
      when: decision.json.status == 'rejected'
      ansible.builtin.debug:
        msg: "Firewall rule request {{ ticket_id }} was rejected. No change applied."

What it does and why

The play never touches the firewall until a human (or an automated approval gate) signs off. It builds a structured change request from the requested rule, POSTs it to an approval workflow endpoint, then polls the request status with until/retries rather than blocking indefinitely. Only when decision.json.status == 'approved' does the play push the rule to the device with cisco.asa.asa_config; a rejected request just gets logged, so nothing is silently discarded.

This is exactly the separation the Automation Portal template relies on: the operator clicks "Start", the job template handles submission and polling, and the actual privileged configuration task is gated behind approval — you don't need job template survey knowledge or credential details to request a change, only permission to run the template.

Notes / Gotchas

  • Swap the uri calls for real integrations. The example uses a generic REST endpoint; in production this is typically ServiceNow, Jira Service Management, or an AAP workflow job template with an approval node instead of a bare API call.
  • retries/delay bound the wait, they don't guarantee an answer. Sixty retries at 30 seconds is 30 minutes — tune to your SLA, and handle the "still pending" case explicitly rather than letting the play just fail on timeout.
  • cisco.asa.asa_config is one example. Swap in the collection matching your vendor (cisco.ios, arista.eos, fortinet.fortios, etc.) — the approval gate pattern is vendor-agnostic, only the final apply task changes.
  • Idempotency still matters. Once approved, the apply task should be safe to re-run; most network config modules already check current state before pushing lines.

Gate the risky task, not the whole playbook: submit, wait, then apply — that's the whole shape of a safe firewall change workflow.

References