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 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.

FromTo RPM (RHEL 9)To Container (RHEL 9)To Container (RHEL 10)To OCP Operator
AAP 2.5 RPM on RHEL 8MigrateMigrateMigrateMigrate
AAP 2.5 RPM on RHEL 9UpgradeMigrateMigrateMigrate
AAP 2.5 Container on RHEL 9N/AUpgradeMigrateMigrate
AAP 2.5 Container on RHEL 10N/AN/AUpgradeMigrate
AAP 2.5 OCP OperatorN/AN/AN/AUpgrade
Upgrade = direct, in-place upgrade. The installer updates packages and database schema on the existing host.

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.

See also: AAP 2.7 Upgrade Path: RPM Installer Removed, Containerized-Only, and the Mandatory 2.6 Stepping Stone

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_KEY migrates automatically with the database
  • RBAC, users, teams, and credentials are intact on day one
Cons:
  • 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_KEY dependency
Cons:
  • 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
Choose database-centric when job history, credential continuity, and a supported Red Hat path are required. Choose clean-rebuild when technical debt is significant and you have time to build CaC exports before the migration window.

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-pip

Step 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.sh

Step 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.sh

Step 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: true

See 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.

Category: installation

Browse all Ansible tutorials · AnsiblePilot Home