AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

AAP 2.6 Migration from AWX: Complete Upgrade and Data Migration Guide

By Luca Berton · Published 2024-01-01 · Category: installation

Migrate from AWX to AAP 2.6 with zero data loss. Export inventories, credentials, job templates, workflows, and schedules.

Why Migrate from AWX to AAP?

AWX is the open-source upstream of AAP's Automation Controller. While AWX is free, AAP 2.6 provides enterprise features that AWX lacks:

| Feature | AWX | AAP 2.6 | |---------|-----|---------| | Support | Community only | Red Hat 24/7 support | | Platform Gateway | ❌ | ✅ Unified entry point | | Automation Hub | ❌ (Galaxy only) | ✅ Private Hub | | Event-Driven Ansible | ❌ | ✅ EDA Controller | | Automation Mesh | ❌ | ✅ Distributed execution | | Lightspeed AI | ❌ | ✅ AI-assisted automation | | Certified Content | ❌ | ✅ Red Hat certified collections | | FIPS compliance | ❌ | ✅ | | Multi-year lifecycle | No (rolling release) | ✅ 18-month support | | Subscription | Free | Managed Nodes or RPM |

See also: How to Upgrade from AAP 2.4 to AAP 2.6 — Step-by-Step Guide

Migration Planning

Pre-Migration Inventory

Document everything in AWX before migrating:

# Export full AWX configuration
awx export --all > awx-export.json

# Or use the API curl -s -k -H "Authorization: Bearer $AWX_TOKEN" \ "https://awx.example.org/api/v2/organizations/" | jq '.results[].name'

curl -s -k -H "Authorization: Bearer $AWX_TOKEN" \ "https://awx.example.org/api/v2/inventories/" | jq '.results[] | {name: .name, id: .id}'

curl -s -k -H "Authorization: Bearer $AWX_TOKEN" \ "https://awx.example.org/api/v2/job_templates/" | jq '.results[] | {name: .name, id: .id, playbook: .playbook}'

curl -s -k -H "Authorization: Bearer $AWX_TOKEN" \ "https://awx.example.org/api/v2/workflow_job_templates/" | jq '.results[] | {name: .name, id: .id}'

Migration Checklist

• [ ] Export organizations • [ ] Export credentials (re-create — passwords don't export) • [ ] Export inventories (static and dynamic sources) • [ ] Export projects (SCM URLs and branches) • [ ] Export job templates (with surveys) • [ ] Export workflow templates (with topology) • [ ] Export schedules • [ ] Export notification templates • [ ] Export teams and user mappings • [ ] Document custom credential types • [ ] Document instance groups • [ ] Note any custom venvs → map to EEs

Export from AWX

Using awx CLI

# Install awx CLI
pip install awxkit

# Configure export CONTROLLER_HOST=https://awx.example.org export CONTROLLER_USERNAME=admin export CONTROLLER_PASSWORD="{{ vault_awx_password }}"

# Export everything awx export --all > awx-full-export.json

# Export specific resources awx export --organizations > orgs.json awx export --inventories > inventories.json awx export --job_templates > templates.json awx export --workflow_job_templates > workflows.json awx export --credentials > credentials.json awx export --projects > projects.json awx export --schedules > schedules.json

Using Ansible Playbook

---
- name: Export AWX configuration
  hosts: localhost
  gather_facts: false
  collections:
    - ansible.controller

vars: awx_host: "https://awx.example.org" awx_username: admin awx_password: "{{ vault_awx_password }}" export_dir: ./awx-export/

tasks: - name: Create export directory ansible.builtin.file: path: "{{ export_dir }}" state: directory

- name: Export organizations ansible.builtin.uri: url: "{{ awx_host }}/api/v2/organizations/?page_size=200" user: "{{ awx_username }}" password: "{{ awx_password }}" force_basic_auth: true validate_certs: false register: orgs

- name: Save organizations ansible.builtin.copy: content: "{{ orgs.json | to_nice_json }}" dest: "{{ export_dir }}/organizations.json"

- name: Export inventories with variables ansible.builtin.uri: url: "{{ awx_host }}/api/v2/inventories/?page_size=200" user: "{{ awx_username }}" password: "{{ awx_password }}" force_basic_auth: true validate_certs: false register: inventories

- name: Save inventories ansible.builtin.copy: content: "{{ inventories.json | to_nice_json }}" dest: "{{ export_dir }}/inventories.json"

- name: Export job templates ansible.builtin.uri: url: "{{ awx_host }}/api/v2/job_templates/?page_size=200" user: "{{ awx_username }}" password: "{{ awx_password }}" force_basic_auth: true validate_certs: false register: templates

- name: Save job templates ansible.builtin.copy: content: "{{ templates.json | to_nice_json }}" dest: "{{ export_dir }}/job_templates.json"

See also: AAP 2.6 Upgrade Guide: RHEL 8→9, RPM→Containerized Migration Paths

Import to AAP 2.6

Using awx CLI Import

# Point to new AAP
export CONTROLLER_HOST=https://gateway.example.org
export CONTROLLER_USERNAME=admin
export CONTROLLER_PASSWORD="{{ vault_aap_password }}"

# Import (creates resources that don't exist) awx import < awx-full-export.json

Import via Playbook

---
- name: Import configuration to AAP 2.6
  hosts: localhost
  gather_facts: false
  collections:
    - ansible.platform

vars: gateway_url: "https://gateway.example.org" controller_user: admin controller_pass: "{{ vault_aap_password }}" export_dir: ./awx-export/

tasks: # Organizations first (other resources depend on them) - name: Create organizations ansible.platform.organization: controller_host: "{{ gateway_url }}" controller_username: "{{ controller_user }}" controller_password: "{{ controller_pass }}" name: "{{ item.name }}" description: "{{ item.description | default('') }}" state: present loop: "{{ lookup('file', export_dir + '/organizations.json') | from_json | json_query('results[*]') }}"

# Credentials (must re-create with new passwords) - name: Create credentials ansible.platform.credential: controller_host: "{{ gateway_url }}" controller_username: "{{ controller_user }}" controller_password: "{{ controller_pass }}" name: "{{ item.name }}" organization: "{{ item.summary_fields.organization.name }}" credential_type: "{{ item.summary_fields.credential_type.name }}" inputs: "{{ credential_inputs[item.name] }}" state: present loop: "{{ lookup('file', export_dir + '/credentials.json') | from_json | json_query('results[*]') }}"

# Projects - name: Create projects ansible.platform.project: controller_host: "{{ gateway_url }}" controller_username: "{{ controller_user }}" controller_password: "{{ controller_pass }}" name: "{{ item.name }}" organization: "{{ item.summary_fields.organization.name }}" scm_type: "{{ item.scm_type }}" scm_url: "{{ item.scm_url }}" scm_branch: "{{ item.scm_branch }}" state: present loop: "{{ lookup('file', export_dir + '/projects.json') | from_json | json_query('results[*]') }}"

Key Differences to Handle

Virtual Environments → Execution Environments

AWX uses Python virtual environments. AAP 2.6 uses container-based EEs:

# List AWX venvs
ls /var/lib/awx/venv/

# For each venv, capture installed packages /var/lib/awx/venv/custom/bin/pip freeze > custom-requirements.txt

Build equivalent EEs:

---
version: 3
images:
  base_image:
    name: registry.redhat.io/ansible-automation-platform-26/ee-minimal-rhel9:latest
dependencies:
  python:
    # Paste from custom-requirements.txt
    - netmiko>=4.0
    - napalm>=5.0
  galaxy:
    collections:
      - cisco.ios
      - arista.eos

API URL Changes

| AWX | AAP 2.6 | |-----|---------| | /api/v2/ | /api/controller/v2/ (via Gateway) | | Direct controller URL | Gateway URL |

Update all API integrations, CI/CD pipelines, and scripts.

Instance Groups → Automation Mesh

AWX instance groups are container groups or local groups. AAP 2.6 uses Automation Mesh with Receptor for distributed execution.

See also: Ansible 12 Upgrade Guide: Breaking Changes, Data Tagging & What to Test First

Post-Migration Validation

- name: Validate AAP migration
  hosts: localhost
  tasks:
    - name: Verify organizations
      ansible.builtin.uri:
        url: "{{ gateway_url }}/api/controller/v2/organizations/"
        headers:
          Authorization: "Bearer {{ token }}"
      register: orgs
      failed_when: orgs.json.count < expected_org_count

- name: Verify job templates ansible.builtin.uri: url: "{{ gateway_url }}/api/controller/v2/job_templates/" headers: Authorization: "Bearer {{ token }}" register: templates failed_when: templates.json.count < expected_template_count

- name: Test-launch critical templates ansible.platform.job_launch: controller_host: "{{ gateway_url }}" controller_username: "{{ controller_user }}" controller_password: "{{ controller_pass }}" job_template: "{{ item }}" extra_vars: dry_run: true loop: - "Infrastructure Health Check" - "Compliance Scan" register: test_jobs

- name: Report migration status ansible.builtin.debug: msg: | Migration Validation: - Organizations: {{ orgs.json.count }} - Job Templates: {{ templates.json.count }} - Test Jobs: {{ test_jobs.results | map(attribute='status') | list }}

FAQ

Can I run AWX and AAP side by side during migration?

Yes. Install AAP 2.6 on new infrastructure and migrate gradually. Keep AWX running until all templates are validated on AAP. Use a cutover date to switch DNS/integrations.

Will my AWX playbooks work on AAP?

Playbooks are 100% compatible. The differences are in the platform (API URLs, EEs vs venvs, Gateway), not the automation content. Your roles, playbooks, and collections work identically.

Do I need to re-enter all credentials?

Yes. Credential secrets don't export for security reasons. Prepare a vault file with all credential values before migration. Better yet, migrate to an external secret backend (HashiCorp Vault, CyberArk) during the move.

What about AWX job history?

Job history doesn't migrate. AAP starts with a clean job log. If you need historical records for compliance, export AWX job data to an external system before decommissioning.

Is there a direct database migration path?

No. AWX and AAP use different database schemas. The supported path is API-based export/import. Red Hat does not support direct database migration between AWX and AAP.

Conclusion

Migrating from AWX to AAP 2.6 is a structured process: export from AWX, recreate credentials, import to AAP, convert venvs to EEs, and validate. The automation content (playbooks, roles, collections) is fully compatible — only the platform configuration needs migration. Plan for a parallel run period and validate thoroughly before decommissioning AWX.

Related Articles

AAP 2.6 Architecture and Components: Complete GuideAAP 2.6 Execution Environments: Build, Manage, and Deploy Custom EEsAAP 2.6 REST API Guide: Automate the Automation PlatformAAP 2.6 Comparison: What Changed from AAP 2.5AAP 2.6 Credential Management: Vaults, External Secrets, and Machine Credentials

Category: installation

Browse all Ansible tutorials · AnsiblePilot Home