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.

Ansible Automation Portal VM Appliance: Deploy on RHEL, KVM, OpenShift Virtualization, and VMware in AAP 2.7

By Luca Berton · Published 2026-06-30 · Category: installation

Deploy the Ansible Automation Portal as a pre-built VM appliance on KVM, OpenShift Virtualization, or VMware vSphere using QCOW2 or VMDK images in AAP 2.7.

Ansible Automation Platform 2.7 ships the Ansible automation portal as a pre-built virtual machine appliance — a QCOW2 or VMDK disk image you deploy on your existing virtualization infrastructure without running the AAP containerized or RPM installer. Built on RHEL 9 image mode (bootc), it supports atomic upgrades and rollback, cloud-init first-boot configuration, and deployment on KVM, Red Hat OpenShift Virtualization, and VMware vSphere.

What Is the Portal Appliance?

The Ansible automation portal provides self-service access to Ansible job templates for users who don't need (or shouldn't have) full AAP UI access. Teams use it to expose approved automation as a simple catalog: users pick a template, fill in parameters, and launch — without knowing anything about Ansible.

The appliance packaging means you no longer need to deploy the full containerized AAP stack just to run the portal. The appliance connects to an existing AAP instance over HTTPS using an OAuth credential you supply at first boot.

See also: Deploy and Configure the MCP Server for Ansible Automation Platform: Complete Guide (Containerized and OpenShift)

Deployment Options

PlatformImage FormatNotes
RHEL with KVM / libvirtQCOW2Standard virt-install or Cockpit VM manager
Red Hat OpenShift VirtualizationQCOW2Import via DataVolume or VirtualMachine CRD
VMware vSphereVMDKDeploy with vSphere client or govc

Cloud-Init First-Boot Configuration

The appliance configures itself entirely from a cloud-init user-data file supplied at deployment time — no interactive setup required. A minimal user-data for KVM:

#cloud-config
# Ansible Automation Portal appliance — first-boot configuration
hostname: ansible-portal
fqdn: portal.corp.example.com

users:
  - name: ansible-admin
    groups: wheel
    sudo: ALL=(ALL) NOPASSWD:ALL
    ssh_authorized_keys:
      - ssh-ed25519 AAAAC3Nza... your-public-key

write_files:
  - path: /etc/ansible-portal/config.yml
    content: |
      aap:
        host: https://aap.corp.example.com
        oauth_client_id: portal-appliance
        oauth_client_secret: "{{ vault_portal_oauth_secret }}"
        verify_ssl: true

      portal:
        title: "IT Self-Service Automation"
        support_url: "https://helpdesk.corp.example.com"
        enable_rbac_nav: true

runcmd:
  - systemctl enable --now ansible-portal
  - ansible-portal --validate-config /etc/ansible-portal/config.yml

The oauth_client_id and oauth_client_secret correspond to an Application credential created in AAP:

# Create the portal OAuth application in AAP (ansible.platform module)
cat <<EOF | ansible-playbook -i localhost, /dev/stdin
---
- name: Create portal OAuth application
  hosts: localhost
  connection: local
  tasks:
    - name: Create application
      ansible.platform.application:
        name: portal-appliance
        organization: Default
        client_type: confidential
        authorization_grant_type: password
        redirect_uris: "https://portal.corp.example.com/callback"
        state: present
EOF

KVM Deployment

# Download the QCOW2 appliance from Red Hat registry
podman pull registry.redhat.io/ansible-automation-platform/portal-appliance-rhel9:2.7
podman save registry.redhat.io/ansible-automation-platform/portal-appliance-rhel9:2.7 \
  -o portal-appliance-2.7.tar

# Extract the disk image
mkdir -p /var/lib/libvirt/images/portal
tar xf portal-appliance-2.7.tar --wildcards '*.qcow2' \
  -C /var/lib/libvirt/images/portal/

# Generate cloud-init ISO
genisoimage -output /tmp/portal-cloud-init.iso \
  -volid cidata -joliet -rock \
  user-data meta-data

# Deploy the VM
virt-install \
  --name ansible-portal \
  --memory 4096 \
  --vcpus 2 \
  --disk /var/lib/libvirt/images/portal/portal-appliance.qcow2,format=qcow2 \
  --disk /tmp/portal-cloud-init.iso,device=cdrom \
  --os-variant rhel9.4 \
  --network bridge=br0 \
  --import \
  --noautoconsole

See also: Renew and Change SSL/TLS Certificates in AAP 2.7: Operator-Based OpenShift Installation

OpenShift Virtualization Deployment

# portal-vm.yaml — OpenShift Virtualization VirtualMachine
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: ansible-portal
  namespace: automation
spec:
  running: true
  template:
    spec:
      domain:
        cpu:
          cores: 2
        memory:
          guest: 4Gi
        devices:
          disks:
            - name: rootdisk
              disk:
                bus: virtio
            - name: cloudinit
              cdrom:
                bus: sata
      volumes:
        - name: rootdisk
          dataVolume:
            name: portal-appliance-dv
        - name: cloudinit
          cloudInitNoCloud:
            userData: |
              #cloud-config
              hostname: ansible-portal
              users:
                - name: ansible-admin
                  ssh_authorized_keys:
                    - ssh-ed25519 AAAAC3Nza...
              write_files:
                - path: /etc/ansible-portal/config.yml
                  content: |
                    aap:
                      host: https://aap.corp.example.com
                      oauth_client_id: portal-appliance
                      oauth_client_secret: "REPLACE_ME"
              runcmd:
                - systemctl enable --now ansible-portal
---
apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
  name: portal-appliance-dv
  namespace: automation
spec:
  source:
    registry:
      url: "docker://registry.redhat.io/ansible-automation-platform/portal-appliance-rhel9:2.7"
  pvc:
    accessModes:
      - ReadWriteOnce
    resources:
      requests:
        storage: 20Gi

Atomic Upgrades with bootc

The appliance is built on RHEL 9 image mode (bootc). Upgrades are atomic and rollback-safe — the running system is never modified in place:

# On the running appliance VM
# Check current image version
bootc status

# Pull and stage the next version
bootc upgrade

# Reboot to activate the new image
systemctl reboot

# If something goes wrong, roll back to the previous version
bootc rollback
systemctl reboot

Because the appliance is container-image-backed, upgrades are as simple as pulling a new image tag. Configuration in /etc/ansible-portal/ and portal data persist across upgrades — only the OS and application binaries change.

See also: Install Ansible Automation Platform in Red Hat Ansible OpenShift Platform operator via Operator

Portal Configuration Features in AAP 2.7

RBAC Navigation Menus

Administrators control which users can access portal sections based on their AAP roles. Configure permitted navigation items in the portal administration section:

RoleNavigation Access
Portal AdministratorAll sections
Template OperatorTemplates, History
EE DeveloperEE definitions, Collections
ViewerHistory only

GitHub Apps Authentication

In addition to personal access tokens, the portal now supports GitHub Apps for source control integration:

  • Fine-grained repository permissions scoped to exactly what the portal needs
  • Higher GitHub API rate limits compared to PATs
  • App credentials rotate automatically via GitHub's installation token mechanism

Job Template Filtering with excludeLabels

Use the excludeLabels Helm chart value (for OCP deployments) or portal config key to hide specific job templates from the self-service catalog without managing an explicit inclusion list:

# portal values for OpenShift Helm chart
portal:
  excludeLabels:
    - "visibility=internal"
    - "tier=infrastructure"
    - "env=staging"

Job templates in AAP tagged with any of these labels are hidden from portal users. Add the labels in AAP under the job template's Labels section or via ansible.platform:

- name: Tag infrastructure templates as excluded from portal
  ansible.platform.job_template:
    name: "Database Schema Migration"
    labels:
      - "visibility=internal"
      - "tier=infrastructure"
    state: present

The global header now shows a configurable Support link. The default is https://access.redhat.com/support. Override it to point to your internal help desk:

# /etc/ansible-portal/config.yml
portal:
  support_url: "https://helpdesk.corp.example.com/ansible"

User-Facing Automation Output

Playbook authors can surface results directly to self-service users using ansible.builtin.debug. The portal displays debug messages in the template log output, making it a lightweight results channel:

- name: Provision web server
  hosts: localhost
  connection: local
  tasks:
    - name: Launch EC2 instance
      amazon.aws.ec2_instance:
        name: "{{ server_name }}"
        instance_type: t3.medium
        image_id: ami-0c55b159cbfafe1f0
      register: ec2

    - name: Show connection info to portal user
      ansible.builtin.debug:
        msg: |
          Server provisioned successfully.
          Hostname: {{ ec2.instances[0].public_dns_name }}
          IP: {{ ec2.instances[0].public_ip_address }}
          Connect: ssh ec2-user@{{ ec2.instances[0].public_ip_address }}

The portal renders this debug output in the job log panel that users see after launching a template.

FAQ

Can the portal appliance connect to AAP 2.6?

The appliance is released as part of AAP 2.7. Red Hat supports it with AAP 2.7 instances. Compatibility with 2.6 is not guaranteed.

Does the appliance replace the containerized portal install?

No. The appliance is an additional deployment option for teams that prefer VM-based infrastructure over containerized deployments. The containerized and OCP operator install paths still exist and are the primary supported methods for full AAP deployments.

How do I scale the portal appliance?

The appliance is designed for single-VM deployment. For high-availability portal deployments, use the containerized installer or the OpenShift Helm chart, which support multiple replicas behind a load balancer.

What storage does the appliance need?

The base image requires approximately 10 GB. Plan for 20 GB to accommodate portal data, logs, and future upgrades. Persistent /etc/ansible-portal/ configuration survives bootc upgrades.

Category: installation

Browse all Ansible tutorials · AnsiblePilot Home