At Red Hat Tech Day Netherlands 2026 (3 June 2026, Bunnik), the Ansible team announced 12 new content collections for AAP 2.7, one of which is ansible.platform — built for configuration-as-code, RBAC/settings refactoring, and performance improvements on the platform itself. Instead of clicking through the AAP UI to create orgs, teams, and permissions, you define them declaratively and let a playbook reconcile the state.

Example playbook

---
- name: Reconcile AAP organizations, teams, and RBAC as code
  hosts: localhost
  gather_facts: false
  collections:
    - ansible.platform

  vars:
    aap_controller_host: "https://aap.example.internal"
    aap_validate_certs: true
    platform_org: "Platform Engineering"
    platform_teams:
      - name: "network-automation"
        users: ["a.jansen", "s.devries"]
      - name: "security-compliance"
        users: ["m.bakker"]

  tasks:
    - name: Ensure the Platform Engineering organization exists
      ansible.platform.organization:
        name: "{{ platform_org }}"
        description: "Owns shared automation content and execution environments"
        state: present

    - name: Create teams under the organization
      ansible.platform.team:
        name: "{{ item.name }}"
        organization: "{{ platform_org }}"
        state: present
      loop: "{{ platform_teams }}"

    - name: Assign RBAC roles to each team on the organization
      ansible.platform.role_user_assignment:
        team: "{{ item.name }}"
        role_definition: "Organization Member"
        object_id: "{{ platform_org }}"
        object_type: "organization"
      loop: "{{ platform_teams }}"

    - name: Grant execute-only role to network-automation team on a job template
      ansible.platform.role_team_assignment:
        team: "network-automation"
        role_definition: "Job Template Execute"
        object_id: "Router Compliance Check"
        object_type: "job_template"
        state: present

    - name: Add users to their team
      ansible.platform.team_user:
        team: "{{ item.0.name }}"
        user: "{{ item.1 }}"
        state: present
      loop: "{{ platform_teams | subelements('users') }}"

What it does and why

The playbook targets localhost because ansible.platform modules talk to the AAP controller API directly rather than to managed nodes — connection details (aap_controller_host, tokens, certs) are typically supplied via environment variables or an ansible.cfg/collection-level config rather than inline. Each task is idempotent: running the playbook repeatedly converges AAP toward the declared state instead of duplicating orgs, teams, or role assignments.

The RBAC-specific tasks are the point of the exercise. Rather than an admin manually granting "who can run what" in the UI, role_user_assignment and role_team_assignment express permissions as versioned, reviewable YAML. That's the "RBAC as code" pattern Red Hat highlighted for AAP 2.7: your access model lives in Git, goes through pull-request review, and can be diffed and audited like any other change.

Notes / Gotchas

  • Authentication: don't hardcode tokens in the playbook. Use ANSIBLE_PLATFORM_URL, ANSIBLE_PLATFORM_TOKEN, or a collection-level config file, and keep secrets out of version control (a Vault-backed lookup pairs well here).
  • Module names are illustrative: ansible.platform was announced at Red Hat Tech Day Netherlands 2026 alongside 11 other new AAP 2.7 collections, but full module reference documentation wasn't published at announcement time. Confirm exact module and parameter names against the shipped collection docs before running this in production.
  • Ordering matters: teams must exist before you assign roles to them, and role definitions must already exist in AAP (built-in ones like "Organization Member" ship by default; custom role definitions need to be created first).
  • Idempotency check: run with --check --diff first against a non-production controller to confirm the reconciliation matches your expectations before applying broadly.

Treat RBAC the same way you treat infrastructure: declare it, version it, and let ansible.platform reconcile AAP to match — that's the efficiency and governance win this collection is built for.

References