AAP 2.6 Upgrade Guide: RHEL 8 to 9 and RPM to Containerized Migration
By Luca Berton · Published 2026-05-19 · Category: installation
Complete guide to AAP 2.6 migration: RHEL 8 to 9, RPM to containerized, database-centric vs clean-rebuild migration approaches with step-by-step procedures.
Upgrading to Ansible Automation Platform 2.6 often involves more than a version bump — it can mean moving from RHEL 8 to RHEL 9 and from an RPM-based installation to a containerized deployment. This guide covers which paths are supported, how to choose between the two migration strategies, and the detailed procedure for each.
Migration Matrix: What You Can Do From Each Starting Point
The matrix below shows every supported path from AAP 2.5 to AAP 2.6. "Upgrade" means an in-place upgrade of the existing system. "Migrate" means backup, fresh install, and restore.
| From | To RPM (RHEL 9) | To Container (RHEL 9) | To Container (RHEL 10) | To OCP Operator |
|---|---|---|---|---|
| AAP 2.5 RPM on RHEL 8 | Migrate | Migrate | Migrate | Migrate |
| AAP 2.5 RPM on RHEL 9 | Upgrade | Migrate | Migrate | Migrate |
| AAP 2.5 Container on RHEL 9 | N/A | Upgrade | Migrate | Migrate |
| AAP 2.5 Container on RHEL 10 | N/A | N/A | Upgrade | Migrate |
| AAP 2.5 OCP Operator | N/A | N/A | N/A | Upgrade |
Migrate = backup the database, install AAP 2.6 fresh on the target system, restore the backup.
If you are on RHEL 8 or changing topology (e.g., RPM to containerized), you always take the Migrate path regardless of source version.
Two Migration Approaches
Database-Centric Migration (Officially Supported)
The database is the source of truth. Everything migrates — job history, users, passwords, credentials, logs, RBAC assignments.
How it works: dump the PostgreSQL database from the source system, run a fresh AAP 2.6 install on the target, restore the dump, let the new installer apply schema migrations.
Pros:
- Fully supported by Red Hat
- Preserves all data including job history and secrets
SECRET_KEYmigrates automatically with the database- RBAC, users, teams, and credentials are intact on day one
- May require intermediate environments for RHEL 8 hosts (the "upgrade dance" to RHEL 9 first)
- Carries over technical debt (orphaned objects, old logs, stale credentials)
- Time-consuming for large databases (tens of GB of job logs)
Clean-Rebuild Migration (Community Best Practice)
Start fresh on AAP 2.6, then replay your configuration from code. Job history is not migrated — only live configuration.
How it works: export current configuration as code using the ansible.platform collection, install AAP 2.6 fresh, re-import configuration, reconfigure credentials from your secrets manager.
Pros:
- Clean slate — no orphaned objects or stale data carried forward
- Forces documentation of all configuration (often a long-overdue cleanup)
- Faster restore times after a fresh install
- Secrets stay in the secrets manager (Vault, CyberArk) — no
SECRET_KEYdependency
- Job history is not preserved
- Requires pre-migration investment in Configuration as Code
- Credentials must be re-entered manually or re-imported from a secrets manager
Pre-Migration Checklist
Run these checks on the source system before starting either approach.
# Check AAP version
automation-controller-service version
# Check RHEL version
cat /etc/redhat-release
# Check disk space — need at least 2x DB size free
df -h /var /tmp
# List active job templates (for inventory before clean-rebuild)
awx job_templates list --all -f human
# Check database size
sudo -u postgres psql -c "\l+"Export your current configuration with the ansible.platform collection (useful for both approaches, essential for clean-rebuild):
---
- name: Export AAP configuration as code
hosts: localhost
connection: local
vars:
controller_hostname: "https://aap.example.com"
controller_username: "admin"
controller_password: "{{ vault_admin_password }}"
controller_validate_certs: true
tasks:
- name: Export all objects
ansible.builtin.include_role:
name: infra.controller_configuration.export
vars:
controller_export_all: true
controller_export_dir: "./aap-config-backup/"See also: How to Upgrade from AAP 2.4 to AAP 2.6 — Step-by-Step Guide
Database-Centric Migration Procedure
Step 1 — Backup the Source Database
# On the source AAP host, stop services first
sudo systemctl stop automation-controller
sudo systemctl stop automation-hub
sudo systemctl stop automation-eda
# Dump the AAP database
sudo -u postgres pg_dumpall --clean > /backup/aap-full-$(date +%Y%m%d).sql
# Capture SECRET_KEY (needed for credential decryption on restore)
sudo cat /etc/tower/SECRET_KEY > /backup/SECRET_KEY.bak
# Backup configuration files
sudo tar czf /backup/aap-configs-$(date +%Y%m%d).tar.gz \
/etc/tower/ \
/etc/ansible-automation-platform/ \
/var/lib/awx/
# Verify backup is not empty
ls -lh /backup/Step 2 — Prepare the Target System
For RHEL 8 → RHEL 9 migrations, provision a new RHEL 9 host. Do not in-place upgrade RHEL 8 to 9 while AAP is installed — the Red Hat-supported path uses a fresh RHEL 9 host.
# On the new RHEL 9 target — register with Red Hat
sudo subscription-manager register --auto-attach
# Enable AAP 2.6 repositories
sudo subscription-manager repos \
--enable ansible-automation-platform-2.6-for-rhel-9-x86_64-rpms
# For containerized AAP — install the setup bundle prerequisites
sudo dnf install -y podman python3-pipStep 3 — Install AAP 2.6 Fresh
# Download the AAP 2.6 setup bundle
# (obtain URL from Red Hat Customer Portal)
tar xvf ansible-automation-platform-setup-bundle-2.6*.tar.gz
cd ansible-automation-platform-setup-bundle-2.6*/
# Configure inventory — point to the new host
# Key setting: use_internal_db=false if restoring external DB
cp inventory inventory.bak
vi inventory
# Run the installer (first pass — creates empty DB)
sudo ./setup.shStep 4 — Restore the Database
# Stop AAP services on the target before restoring
sudo systemctl stop automation-controller
sudo systemctl stop automation-hub
# Restore database from backup
sudo -u postgres psql < /backup/aap-full-20260519.sql
# Restore SECRET_KEY (must match source or credentials won't decrypt)
sudo cp /backup/SECRET_KEY.bak /etc/tower/SECRET_KEY
sudo chmod 0600 /etc/tower/SECRET_KEY
# Run the installer again — applies schema migrations to restored DB
sudo ./setup.shStep 5 — Verify the Migration
---
- name: Verify AAP 2.6 migration
hosts: localhost
connection: local
tasks:
- name: Check controller version
ansible.builtin.uri:
url: "https://aap-new.example.com/api/v2/ping/"
user: "{{ vault_aap_admin }}"
password: "{{ vault_aap_password }}"
force_basic_auth: true
validate_certs: true
register: ping_result
- name: Assert correct version
ansible.builtin.assert:
that: "'2.6' in ping_result.json.version"
success_msg: "AAP 2.6 confirmed: {{ ping_result.json.version }}"
- name: Verify credential count matches source
ansible.builtin.uri:
url: "https://aap-new.example.com/api/v2/credentials/?page_size=1"
user: "{{ vault_aap_admin }}"
password: "{{ vault_aap_password }}"
force_basic_auth: true
register: cred_count
- name: Display credential count
ansible.builtin.debug:
msg: "Credentials migrated: {{ cred_count.json.count }}"Clean-Rebuild Migration Procedure
Step 1 — Export Configuration from Source
---
- name: Export AAP configuration for clean-rebuild
hosts: localhost
vars:
controller_hostname: "https://aap-old.example.com"
controller_username: "admin"
controller_password: "{{ vault_admin_password }}"
tasks:
- name: Export organizations
ansible.builtin.include_role:
name: infra.controller_configuration.export
vars:
controller_export_all: true
controller_export_dir: "./aap-cac-export/"
- name: List exported files
ansible.builtin.find:
paths: "./aap-cac-export/"
patterns: "*.yaml"
register: exported
- name: Show export summary
ansible.builtin.debug:
msg: "Exported {{ exported.matched }} configuration files"Step 2 — Install AAP 2.6 Fresh
Follow the same install steps as the database-centric procedure (Steps 2–3 above), but do NOT restore the database. Let the installer create a clean empty database.
Step 3 — Re-import Configuration
---
- name: Import AAP configuration to AAP 2.6
hosts: localhost
vars:
controller_hostname: "https://aap-new.example.com"
controller_username: "admin"
controller_password: "{{ vault_admin_password }}"
tasks:
- name: Import organizations
ansible.builtin.include_role:
name: infra.controller_configuration.dispatch
vars:
controller_configuration_dir: "./aap-cac-export/"Step 4 — Re-import Credentials from Vault
---
- name: Import credentials from HashiCorp Vault
hosts: localhost
tasks:
- name: Read credentials from Vault
community.hashi_vault.vault_kv2_get:
path: "secret/data/aap/credentials"
url: "{{ vault_url }}"
token: "{{ vault_token }}"
register: vault_creds
- name: Create machine credentials in AAP
ansible.controller.credential:
name: "{{ item.name }}"
credential_type: Machine
organization: "{{ item.organization }}"
inputs:
username: "{{ item.username }}"
password: "{{ item.password }}"
controller_host: "https://aap-new.example.com"
controller_username: admin
controller_password: "{{ vault_admin_password }}"
loop: "{{ vault_creds.data.data.machine_creds }}"
no_log: trueSee also: Ansible Automation Platform Upgrade Guide: Migration Path from AAP 2.4 and 2.5 to 2.6
FAQ
Can I in-place upgrade RHEL 8 to RHEL 9 while AAP is installed?
No. Red Hat does not support in-place RHEL 8 to 9 upgrades with AAP installed. Provision a new RHEL 9 host and migrate AAP to it.
My database is 50 GB of job logs. Is there a way to slim it down before migrating?
Yes. Purge old job events in the controller before taking the backup: Settings → Jobs → Days before stale job deletion. Set to 30 days and run a cleanup before the migration window to reduce dump size significantly.
Do I need to migrate to RHEL 9 before upgrading to AAP 2.6 RPM?
Yes. AAP 2.6 RPM requires RHEL 9. If you are on AAP 2.5 RPM on RHEL 8, you must move to a RHEL 9 host first (Migrate row in the matrix above).
Does a containerized AAP 2.6 install still need a separate PostgreSQL host?
Containerized AAP 2.6 can run PostgreSQL as a container alongside the application containers, or connect to an external managed database. For production, an external PostgreSQL 15 instance (on RHEL 9 or managed DB) is recommended.
How long does the database restore take?
Restore time scales roughly linearly with database size. A 10 GB dump typically takes 20–40 minutes. A 50 GB dump can take several hours. Plan your maintenance window accordingly and test the restore procedure in a staging environment first.
Can I do a blue-green migration — keep the old system running until cutover?
Yes, and this is the recommended approach when possible. The old AAP 2.5 instance stays online (read-only jobs only) while you validate the new AAP 2.6 instance. After validation, update DNS to point to the new host and decommission the old one.
Related Articles
Category: installation