About Ansible automation portal RHEL appliances
The Ansible automation portal RHEL virtual machine appliances provide pre-configured virtual machines that you can deploy across multiple virtualization platforms.
The appliances are available in the following formats:
- QCOW2 - For Red Hat OpenShift Virtualization and KVM-based environments
- VMDK - For VMware
vSphereinfrastructure
Supported platforms Copy linkLink copied!
You can deploy Ansible automation portal appliances on the following platforms:
- Red Hat OpenShift Virtualization
- Deploy the appliance as a virtual machine within your Red Hat OpenShift Container Platform environment using the QCOW2 image format.
-
VMware
vSphere - Deploy the appliance on VMware infrastructure using ESXi hosts and VMFS datastores with the VMDK image format.
- QEMU for local testing
- Deploy the appliance on your local machine for testing and demonstrations using the QCOW2 image format. This deployment model is not supported for production environments.
Ansible automation portal appliances support AMD64/x86_64 platforms only.
Initial configuration Copy linkLink copied!
The appliance requires configuration at first boot to connect to Ansible Automation Platform and start portal services. You must provide configuration through one of the following methods, listed in priority order:
- Baked-in configuration
- For advanced installations using the Ansible collection to build a customized appliance image with pre-baked settings.
-
VMware
guestinfoproperties -
For VMware deployments, provide SSH keys and portal configuration through
guestinfoproperties set invSphere. - cloud-init user-data
- For cloud and Red Hat OpenShift Virtualization deployments, provide SSH keys and portal configuration through cloud-init user-data. The appliance configures itself automatically on first boot.
- Pre-seeded configuration file
- Place a YAML configuration file at /etc/portal/config.yaml before first boot for automated deployment.
If no configuration source is found at first boot, portal services do not start. You can provide configuration after deployment by editing /etc/portal/configs/app-config/app-config.production.yaml and restarting the portal service.
The initial configuration includes:
- SSH key authentication for administrative access
- Ansible Automation Platform URL, OAuth application credentials, and admin token
- Database settings (built-in or external PostgreSQL)
- Base URL and network configuration
The admin user account is locked by default and console login is disabled. Administrative access is available only through SSH using the key you provided during configuration.
Disconnected environments Copy linkLink copied!
You can deploy Ansible automation portal appliances in disconnected or air-gapped environments. The pre-built appliance images include all required container images and plug-ins, so no external network access is required during initial deployment.
For appliance upgrades in disconnected environments, a mirror registry or OCI archive provides the updated container images. Use the ansible-portal registry-login command to authenticate to a private registry mirror.
Understanding the appliance Copy linkLink copied!
Before configuring or managing the appliance, review how its key components work together.
Configuration files Copy linkLink copied!
The Ansible automation portal RHEL appliance uses two YAML configuration files at /etc/portal/configs/app-config/:
-
app-config.yaml - Infrastructure configuration including the base URL, database connection, TLS, and system defaults. This file is set during initial deployment and is not typically modified.
-
app-config.production.yaml - Application configuration including Ansible Automation Platform connection, OAuth settings, SCM integrations, and catalog synchronization. Edit this file for day-to-day configuration changes. To apply changes, edit the file and restart the Ansible automation portal service. Changes take effect after the restart, which takes approximately 60 seconds.
Service management Copy linkLink copied!
The Ansible automation portal RHEL appliance runs three systemd services that manage Podman containers:
-
portal.service - Ansible automation portal application. Listens on port 443 (HTTPS).
-
postgres.service - PostgreSQL database. Listens on port 5432 (internal container network only). This service is skipped when an external database is configured.
-
devtools.service - Ansible development tools. Provides Ansible Navigator and content creator services for building execution environments and developing Ansible content from the Ansible automation portal interface.
Restarting the portal service also restarts postgres and devtools due to service dependencies.
Use standard systemctl and journalctl commands to manage and inspect these services:
$ sudo systemctl restart portal
$ sudo journalctl -u portal -f
SSL certificates Copy linkLink copied!
The appliance generates self-signed SSL certificates at first boot and stores them at /etc/portal/ssl/. Replace these with certificates from a trusted certificate authority for production use.
Prerequisites for deploying Ansible automation portal on RHEL Copy linkLink copied!
Before you deploy an Ansible automation portal RHEL appliance, verify that your environment meets the system, network, and access requirements.
System requirements Copy linkLink copied!
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 4 vCPU | 6 vCPU |
| Memory | 16 GB | 24 GB |
| Disk space | 40 GB | 60 GB |
| Architecture | AMD64/x86_64 | -- |
| Operating system | RHEL 9.6 or later (included in appliance) | RHEL 9.7 |
The recommended values include headroom for the built-in database. For production deployments, use an external PostgreSQL database. The built-in database is suitable for evaluation and small environments.
Network requirements Copy linkLink copied!
The following table lists the default ports used by the Ansible automation portal RHEL appliance. The HTTPS port is configurable after deployment.
| Direction | Port | Protocol | Purpose |
|---|---|---|---|
| Inbound | 443 (default) | HTTPS | User access to Ansible automation portal |
| Inbound | 22 | SSH | Administrator access to the appliance |
| Outbound | 443 | HTTPS | Communication with the Ansible Automation Platform instance |
| Outbound | 443 | HTTPS | Image pulls from registry.redhat.io (upgrades only, not required with a mirror registry) |
Port 5432 (PostgreSQL) is used internally between containers and is not exposed to the network.
Required access Copy linkLink copied!
- An Ansible Automation Platform 2.5 or later instance with administrator privileges.
- An active Red Hat Ansible Automation Platform subscription.
- An active RHEL subscription (for the KVM host, if applicable).
- The pre-built QCOW2 or VMDK appliance image, available from the Red Hat Ansible Automation Platform downloads page.
- An SSH key pair for appliance access.
Prepare for installation Copy linkLink copied!
Before deploying the appliance, complete the prerequisite steps in the pre-installation configuration documentation. Create an OAuth application and generate an API token. You need the Client ID, Client Secret, and API Token values for the cloud-init configuration.
Optional: If you want to import custom templates from private GitHub or GitLab repositories, create a personal access token for each service before you begin. You provide these tokens in the cloud-init configuration.
Prepare the cloud-init configuration Copy linkLink copied!
The appliance uses cloud-init to apply your configuration at first boot. Cloud-init is a standard tool for automating the initial setup of virtual machines. It creates user accounts, injects SSH keys, and runs custom configuration scripts. The appliance extends cloud-init with custom fields for Ansible Automation Platform credentials and database settings.
Create a cloud-init user-data file with your SSH keys and Ansible Automation Platform credentials.
The following four Ansible Automation Platform fields are required. Without them, Ansible automation portal services do not start:
aap.host_urlaap.tokenaap.oauth.client_idaap.oauth.client_secret
SSH keys are required for access. The appliance has no default password.
All other fields are optional. The Ansible automation portal RHEL appliance auto-generates passwords for the default built-in database deployed during initial installation, backend secrets, and a user-accessible URL if you omit them.
Keep quotation marks around SSH public keys in the cloud-init user-data file.
Minimal cloud-init template Copy linkLink copied!
Replace the placeholder values in angle brackets. All other values auto-generate at first boot.
#cloud-config
users:
- name: <username>
sudo: ALL=(ALL) NOPASSWD:ALL
ssh_authorized_keys:
- "<your-ssh-public-key>"
aap:
host_url: "https://<aap-host>"
token: "<aap-api-token>"
oauth:
client_id: "<oauth-client-id>"
client_secret: "<oauth-client-secret>"
Full cloud-init template Copy linkLink copied!
This template includes all supported fields. Replace values marked with angle brackets. Remove or leave optional sections as-is.
#cloud-config
users:
- name: <username>
sudo: ALL=(ALL) NOPASSWD:ALL
ssh_authorized_keys:
- "<your-ssh-public-key>"
aap:
host_url: "https://<aap-host>"
token: "<aap-api-token>"
check_ssl: true
oauth:
client_id: "<oauth-client-id>"
client_secret: "<oauth-client-secret>"
database:
type: builtin
builtin:
password: "auto"
admin_password: "auto"
security:
backend_secret: "auto"
network:
port: 443
base_url: "https://portal.example.com"
integrations:
github:
url: "github.com"
token: "<github-personal-access-token>"
gitlab:
url: "gitlab.com"
token: "<gitlab-personal-access-token>"
aap.check_ssl-- Set tofalseif your Ansible Automation Platform instance uses a self-signed certificate.network.base_url-- Set this when users access the Ansible automation portal RHEL appliance through a hostname, route, or load balancer. If omitted, the user-accessible URL is auto-detected from the VM IP address.network.port-- The HTTPS listen port. Default is443. If you are using the standard port 443, you do not need to specify the port. If you set a custom port, you must also open that port on any firewall and, for Red Hat OpenShift Virtualization deployments, update the Red Hat OpenShift Container Platform route to use the custom port.integrations-- Optional. Only required if you need to import custom templates from private GitHub or GitLab repositories. Public repository access does not require a token.
External database cloud-init template Copy linkLink copied!
To connect to an existing PostgreSQL database instead of the built-in one, use the following database section:
database:
type: external
external:
host: "<database-host>"
port: 5432
name: "portal_db"
user: "<database-user>"
password: "<database-password>"
ssl: true
The database user requires the CREATEDB privilege.
Save the cloud-init user-data file. You will use it during the platform-specific installation procedure.
Install Ansible automation portal on RHEL with KVM Copy linkLink copied!
Deploy the Ansible automation portal appliance on a RHEL 9 host with KVM using virt-install.
Before you begin Copy linkLink copied!
- A RHEL 9 host with KVM support (Intel VT-x or AMD-V enabled).
- An SSH key pair on the host.
- The Ansible automation portal QCOW2 disk image.
- Minimum 24 GB available memory on the host.
- A completed cloud-init user-data file. See Prerequisites for deploying Ansible automation portal on RHEL.
About this task Copy linkLink copied!
The following procedure provides example commands that you can adapt to your environment.
Procedure Copy linkLink copied!
Results Copy linkLink copied!
SSH into the Ansible automation portal RHEL appliance and confirm that all services are running:
$ ssh -i <private-key> <username>@<vm-ip>
$ sudo systemctl status portal postgres devtools
Example output for a healthy Ansible automation portal RHEL appliance:
portal.service - Automation portal
Active: active (running) since ...
postgres.service - PostgreSQL database
Active: active (running) since ...
devtools.service - Ansible development tools
Active: active (running) since ...
All three services should show active (running).
What to do next Copy linkLink copied!
Continue to Connect and verify Ansible automation portal to complete the post-installation steps.
Remove the VM Copy linkLink copied!
Delete the VM and its storage after an evaluation.
About this task Copy linkLink copied!
To delete the VM and its storage after an evaluation, run the following commands.
Procedure Copy linkLink copied!
$ sudo virsh destroy "$VM_NAME"
$ sudo virsh undefine "$VM_NAME" --remove-all-storage
$ rm -rf "$WORK_DIR"
Install Ansible automation portal on Red Hat OpenShift Virtualization Copy linkLink copied!
Deploy the Ansible automation portal appliance on Red Hat OpenShift Virtualization to run the portal as a virtual machine alongside container workloads within your Red Hat OpenShift Container Platform cluster.
This approach enables you to use your existing OpenShift infrastructure to host the portal.
For more information about Red Hat OpenShift Virtualization, see the About OpenShift Virtualization documentation.
You can install the appliance using the CLI or the OpenShift web console. Both methods require the following prerequisites.
Prerequisites Copy linkLink copied!
- Red Hat OpenShift Container Platform cluster (4.x) with Red Hat OpenShift Virtualization operator installed and configured.
- Cluster administrator or equivalent permissions to create VirtualMachine resources.
- A storage class configured that supports ReadWriteOnce (RWO) access mode for virtual machine disks.
- The Ansible automation portal disk image in QCOW2 format.
- The
virtctlCLI tool installed. You can download it from the OpenShift web console under Virtualization > Overview > Download virtctl. - Access to the OpenShift web console or
ocCLI tool. - Your cloud-init user-data file prepared with Ansible Automation Platform credentials and SSH keys.
- Sufficient cluster resources: minimum 16 GiB allocatable memory for the virtual machine.
Install using the CLI Copy linkLink copied!
- Create a project for the deployment:
$ oc new-project <project-name> - Upload the QCOW2 disk image using
virtctl:$ virtctl image-upload dv <disk-datavolume-name> \ --size=50Gi \ --image-path=/path/to/disk.qcow2 \ --uploadproxy-url=https://cdi-uploadproxy-openshift-cnv.apps.<cluster-domain> \ --wait-secs=600 \ -n <project-name>Expand Option Description --sizeSet to at least 50 Gi. The QCOW2 expands during conversion to raw format and requires additional space. --insecureAdd this flag if the Containerized Data Importer (CDI) upload proxy uses a self-signed certificate. Omit it when the proxy has a trusted certificate. --force-bindAdd this flag if the storage class uses WaitForFirstConsumervolume binding mode.Wait for both upload and processing to complete. The "Processing completed successfully" message confirms that CDI converted the image. For more information about CDI, see the Managing data volumes section of the Red Hat OpenShift Virtualization documentation.
- Create a Secret from the cloud-init file:
$ oc create secret generic <cloudinit-secret-name> \ --from-file=userdata=cloud-init-user-data.yaml \ -n <project-name> - Create a VirtualMachine manifest.
The following example shows a minimal configuration. Replace the resource names and namespace to match your environment:
apiVersion: kubevirt.io/v1 kind: VirtualMachine metadata: name: <vm-name> namespace: <project-name> spec: runStrategy: Always template: spec: domain: devices: disks: - disk: bus: virtio name: rootdisk - disk: bus: virtio name: cloudinitdisk interfaces: - masquerade: {} name: default resources: requests: memory: 16Gi networks: - name: default pod: {} volumes: - name: rootdisk dataVolume: name: <disk-datavolume-name> - name: cloudinitdisk cloudInitNoCloud: secretRef: name: <cloudinit-secret-name>The
dataVolumename must match the DataVolume created byvirtctl image-uploadin step 2. ThesecretRefname must match the Secret created in step 3. - Apply the manifest:
$ oc apply -f <vm-manifest>.yaml - Wait for the VM to reach
Runningstatus:$ oc get vmi -n <project-name> -wThe VM is ready when PHASE shows
Runningand READY showsTrue. - Create a Service and Route to expose Ansible automation portal:
$ virtctl expose vm <vm-name> --port=443 --name=<service-name> -n <project-name> $ oc create route passthrough <route-name> --service=<service-name> --port=443 -n <project-name> $ ROUTE_HOST=$(oc get route <route-name> -o jsonpath='{.spec.host}' -n <project-name>) $ echo "Automation portal URL: https://$ROUTE_HOST" - Update the Ansible automation portal user-accessible URL to match the route.
SSH into the VM:
$ virtctl ssh <username>@<vm-name> -n <project-name>Edit the configuration file:
$ sudo vi /etc/portal/configs/app-config/app-config.production.yamlSet the following three values, replacing
<route-host>with the route hostname from step 7:app: baseUrl: "https://<route-host>" backend: baseUrl: "https://<route-host>" cors: origin: "https://<route-host>"Save the file and restart the Ansible automation portal service. Restarting the
portalservice also restartspostgresanddevtoolsdue to service dependencies:$ sudo systemctl restart portal
Verification
- Verify that the virtual machine is running:
$ oc get vmi -n <project-name>The output shows the virtual machine in
Runningphase withREADYstatus set toTrue. - SSH into the appliance and verify that all services are running:
$ sudo ansible-portal status - Access the portal URL from your browser.
Install using the OpenShift web console Copy linkLink copied!
You can also deploy the appliance from the OpenShift web console without using the CLI.
Prerequisites
- Red Hat OpenShift Container Platform with the Red Hat OpenShift Virtualization operator installed and configured.
- Cluster administrator or equivalent permissions.
- The Ansible automation portal QCOW2 disk image available on your local machine.
- Your cloud-init user-data file prepared with Ansible Automation Platform credentials and SSH keys.
Procedure
- Go to Storage > PersistentVolumeClaims.
- Create a PVC using Data upload form. Upload the QCOW2 image. Set the size to at least 50 Gi.
- Go to Workloads > Secrets. Create a key/value secret with a key named
userdata. Paste the cloud-init user-data contents as the value. - Go to Virtualization > VirtualMachines. Click Create VirtualMachine > From YAML. Apply the manifest from the CLI procedure.
- Wait for the VM status to change to Running.
- Go to Networking > Services. Create a service targeting port 443 on the VM.
- Go to Networking > Routes. Create a passthrough TLS route for the service. Note the route hostname.
- SSH into the VM. Set
app.baseUrl,backend.baseUrl, andbackend.cors.origintohttps://<route-hostname>. - Restart the portal service:
$ sudo systemctl restart portal
Verification
- SSH into the VM and confirm that all services are running:
$ sudo ansible-portal status - Access the portal URL from your browser.
If you encounter upload, boot, or scheduling failures, see Troubleshooting RHEL appliances.
Install Ansible automation portal on VMware vSphere Copy linkLink copied!
Deploy the Ansible automation portal appliance on VMware vSphere using the vSphere web client.
Prerequisites Copy linkLink copied!
- VMware vSphere/vCenter with permissions to create VMs and upload files to a datastore.
- The Ansible automation portal disk image in VMDK format, available from the Red Hat Ansible Automation Platform downloads page.
- Your cloud-init user-data file prepared with Ansible Automation Platform credentials and SSH keys.
- An SSH key pair for appliance access.
genisoimageinstalled on your local machine (for creating the cloud-init ISO).
Install using the vSphere web client Copy linkLink copied!
- Upload the VMDK disk image to a datastore:
- Open the vCenter web client.
- Navigate to Storage > Datastores and select your datastore.
- Click Upload Files and upload the Ansible automation portal VMDK file.
- Save your cloud-init user-data file as
cloud-init-user-data.yaml. Use the cloud-init template from the first boot configuration topic. - Create a cloud-init ISO from your user-data file.
VMware delivers cloud-init configuration to the VM as a small ISO disk image labeled
cidata. Cloud-init expects two files on the ISO:user-data(your configuration) andmeta-data(instance identity):$ cp cloud-init-user-data.yaml user-data $ echo "instance-id: automation-portal" > meta-data $ genisoimage -output cloud-init.iso -volid cidata -joliet -rock user-data meta-data - Upload the cloud-init ISO to the same datastore.
- Create a virtual machine:
- Right-click the cluster or host and select New Virtual Machine > Create a new virtual machine.
- Set the following example values. Replace the name, CPU, and memory to match your environment:
Expand Field Example value Name automation-portalGuest OS Red Hat Enterprise Linux 9 (64-bit) CPU 6 cores Memory 24 GB Hard disk Remove the default disk Network Select your VM network - Click Next and then Finish.
- Attach the VMDK disk and cloud-init ISO to the VM:
- Copy the uploaded VMDK and cloud-init ISO to the VM folder on the datastore.
- Edit the VM settings.
- Click Add hard disk > Existing Hard Disk and browse to the copied VMDK.
- Click Add CD/DVD Drive > Datastore ISO File and browse to the copied cloud-init ISO.
- Save the VM settings.
- Power on the VM. First-boot configuration takes 2-3 minutes.
Verification
- Open the VM console in vSphere or SSH into the VM and confirm that all services are running:
$ sudo ansible-portal status - Access the portal URL from your browser.
Configure the appliance at first boot Copy linkLink copied!
Provide initial configuration for the Ansible automation portal appliance so that portal services can start and connect to Ansible Automation Platform.
You must supply SSH keys and portal settings through one of the supported configuration methods during or before deployment.
Prerequisites Copy linkLink copied!
- The Ansible Automation Platform OAuth application Client ID and Client Secret.
- The Ansible Automation Platform admin token.
- An SSH public key for administrative access.
- The URL of your Ansible Automation Platform instance.
Using cloud-init user-data Copy linkLink copied!
Use this method for Red Hat OpenShift Virtualization, cloud, and KVM/QEMU deployments.
- Create a cloud-init user-data file:
#cloud-config users: - name: admin groups: sudo ssh_authorized_keys: - <your_ssh_public_key> aap: host_url: https://<aap_host> token: <aap_admin_token> oauth: client_id: <oauth_client_id> client_secret: <oauth_client_secret> check_ssl: true database: type: builtinReplace the placeholder values with your Ansible Automation Platform credentials and SSH public key.
The appliance parses the custom
aapanddatabasefields directly from the cloud-init user-data at first boot.The following additional fields are available for cloud-init configuration:
network.base_url-- Set the user-accessible URL (auto-detected from the VM IP address if not specified). Set this when users access Ansible automation portal through a hostname, route, or load balancer.network.port-- Set the HTTPS port (default: 443).security.backend_secret-- Set the backend authentication secret (autogenerates a random value).database.builtin.passwordanddatabase.builtin.admin_password-- Set built-in database passwords (autogenerates random values).database.external.*-- Configure an external PostgreSQL database (host,port,name,user,password,ssl). The database user requires theCREATEDBprivilege.integrations.github.url,integrations.github.token-- Configure GitHub integration (URL defaults togithub.com).integrations.gitlab.url,integrations.gitlab.token-- Configure GitLab integration (URL defaults togitlab.com).backup.enabled,backup.schedule,backup.retention_days-- Configure automated backups.
- Provide the user-data file during deployment:
- For Red Hat OpenShift Virtualization, add a
cloudInitNoCloudvolume to theVirtualMachinemanifest. - For cloud providers (AWS, GCP, Azure), pass the user-data through the instance launch configuration.
- For local KVM/QEMU, create a cloud-init ISO or use the
-smbiosoption to pass user-data.
- For Red Hat OpenShift Virtualization, add a
Using VMware guestinfo properties Copy linkLink copied!
Use this method for VMware vSphere deployments.
- Set the following
guestinfoproperties on the virtual machine in vSphere:guestinfo.portal.ssh_public_key = "<your_ssh_public_key>" guestinfo.portal.config = "<base64_encoded_config_yaml>"Where
<base64_encoded_config_yaml>is the Base64-encoded content of your portal configuration YAML. - Power on the virtual machine. The appliance detects and applies the
guestinfoproperties on first boot.
Using a pre-seeded configuration file Copy linkLink copied!
Use this method for automated deployments with Ansible or Terraform.
- Place a YAML configuration file at
/etc/portal/config.yamlon the appliance disk image before first boot:aap: host_url: https://<aap_host> token: <aap_admin_token> oauth: client_id: <oauth_client_id> client_secret: <oauth_client_secret> database: type: builtin - Boot the appliance. The first-boot service detects and applies the configuration automatically.
Configure after deployment Copy linkLink copied!
If you deployed the appliance without providing configuration, portal services do not start. You can configure the appliance after deployment by editing the configuration files directly.
- SSH into the appliance using the key you provided through cloud-init or another method.
- Edit the application configuration file:
$ sudo vi /etc/portal/configs/app-config/app-config.production.yaml - Restart the portal service:
$ sudo systemctl restart portal
Verification Copy linkLink copied!
- Verify that portal services are running:
$ sudo ansible-portal status - Access the portal URL from your browser.
- Log in using your Ansible Automation Platform credentials.
Connect and verify Ansible automation portal Copy linkLink copied!
After deploying the Ansible automation portal appliance, update the OAuth redirect URI, verify service health, and sign in to the portal.
About this task Copy linkLink copied!
Complete these post-installation steps after deploying the Ansible automation portal appliance on any platform.
Procedure Copy linkLink copied!
Results Copy linkLink copied!
A successful login confirms that the OAuth integration with Ansible Automation Platform is working. The Ansible automation portal catalog displays synchronized job templates from Ansible Automation Platform. If no templates appear, verify that the API token has access to job templates in Ansible Automation Platform.
Deploy a RHEL appliance in a disconnected environment Copy linkLink copied!
Deploy the Ansible automation portal RHEL appliance in a disconnected or air-gapped environment where the appliance has no access to external registries or the internet.
Before you begin Copy linkLink copied!
- You have downloaded the appliance disk image (QCOW2 or VMDK) from the Red Hat Ansible Automation Platform downloads page on a connected system.
- You have a method to transfer the disk image to the disconnected environment (for example, portable media or a secure file transfer system).
- You have a virtualization platform available in the disconnected environment (Red Hat OpenShift Virtualization, VMware vSphere, or KVM).
- You have network connectivity from the appliance to your Ansible Automation Platform instance (internal network).
- You have Ansible Automation Platform credentials: host URL, API token, OAuth client ID, and OAuth client secret.
- You have an SSH key pair for appliance access.
About this task Copy linkLink copied!
The appliance image includes everything needed to run without pulling content from external registries:
- Pre-bundled Ansible plugins
-
Dynamic plugins are extracted at build time and stored at
/usr/share/portal/plugins/. The appliance loads plugins from the local filesystem, not from a registry. - Pre-pulled container images
- The Ansible automation portal and PostgreSQL container images are embedded in the appliance image. No container image pulls occur at runtime.
- Self-signed SSL certificates
- Generated locally at first boot. You can replace them with your own certificates after deployment.
- No registry authentication required
- The appliance starts and runs without registry credentials. Registry authentication is only needed for future upgrades.
Procedure Copy linkLink copied!
Results Copy linkLink copied!
- Verify that the portal URL is accessible from your browser.
- Verify that all services show a healthy status in the
ansible-portal statusoutput.
What to do next Copy linkLink copied!
For appliance upgrades in disconnected environments, see Upgrading in disconnected environments.
Replace self-signed SSL certificates Copy linkLink copied!
The Ansible automation portal RHEL appliance generates self-signed SSL certificates at first boot and stores them at /etc/portal/ssl/. Replace these certificates with certificates from a trusted certificate authority for production use.
Replace the SSL certificates Copy linkLink copied!
Prerequisites:
- A TLS certificate and private key in PEM format, issued by a certificate authority trusted by your organization.
- SSH access to the appliance.
Procedure:
- Copy your certificates to the appliance:
$ sudo cp certificate-file.pem /etc/portal/ssl/cert.pem $ sudo cp private-key-file.pem /etc/portal/ssl/key.pem $ sudo chmod 644 /etc/portal/ssl/cert.pem $ sudo chmod 600 /etc/portal/ssl/key.pem - Restart the Ansible automation portal service:
$ sudo systemctl restart portal
Verification:
- Verify that the Ansible automation portal is using the new certificate:
$ curl -vk https://localhost 2>&1 | grep -i "issuer"The output displays the issuer from your certificate, not the self-signed issuer.
Trust a custom certificate authority Copy linkLink copied!
If your organization uses a custom certificate authority (CA) or a self-signed certificate for your Ansible Automation Platform instance, configure the Ansible automation portal RHEL appliance to trust it.
Prerequisites:
- The CA certificate or self-signed certificate in PEM format.
- SSH access to the appliance.
Procedure:
- Copy the CA certificate or self-signed certificate to the appliance:
$ sudo cp ca-certificate-file.pem /etc/portal/ssl/ca-bundle.crtIf you have multiple CA certificates to trust, concatenate them into a single bundle file before copying it to the appliance.
- Create a Quadlet drop-in to set the
NODE_EXTRA_CA_CERTSenvironment variable:$ sudo mkdir -p /etc/containers/systemd/portal.container.d $ echo -e '[Container]\nEnvironment=NODE_EXTRA_CA_CERTS=/etc/portal/ssl/ca-bundle.crt' \ | sudo tee /etc/containers/systemd/portal.container.d/ca-certs.conf - Reload systemd and restart the Ansible automation portal service:
$ sudo systemctl daemon-reload $ sudo systemctl restart portal
Verification:
- Verify that the environment variable is set in the portal container:
$ sudo podman exec portal env | grep NODE_EXTRA_CA_CERTSThe output displays
NODE_EXTRA_CA_CERTS=/etc/portal/ssl/ca-bundle.crt.
Set a custom user-accessible URL or port Copy linkLink copied!
The Ansible automation portal RHEL appliance auto-detects the user-accessible URL from the VM IP address at each boot. To set a custom hostname or port, update the configuration file and restart the service.
Before you begin Copy linkLink copied!
- SSH access to the appliance.
- The hostname or IP address and port that users will use to access Ansible automation portal.
Procedure Copy linkLink copied!
Results Copy linkLink copied!
Verify that Ansible automation portal is accessible at the new URL:
$ curl -fk https://new-url
A successful response confirms that the URL and port are configured correctly.
Configure an external database Copy linkLink copied!
By default, the Ansible automation portal RHEL appliance runs a built-in PostgreSQL database. For production deployments, connect to an external PostgreSQL database.
Before you begin Copy linkLink copied!
- A PostgreSQL database instance accessible from the appliance.
- A database user with the
CREATEDBprivilege. - The database password.
- SSH access to the appliance.
About this task Copy linkLink copied!
You can provide external database settings in the cloud-init user-data at first boot or configure the database after deployment. For the cloud-init template fields, see External database cloud-init template.
Procedure Copy linkLink copied!
Results Copy linkLink copied!
Check the portal logs to verify the database connection:
$ sudo journalctl -u portal --no-pager | grep -i "database"
The output shows a successful database connection with no errors.
Upgrade the Ansible automation portal RHEL appliance Copy linkLink copied!
The Ansible automation portal RHEL appliance uses RHEL image mode (bootc) for atomic upgrades. Your configuration, data, and secrets are preserved, and you can roll back to the previous image if needed.
If you are upgrading from plug-in version 2.1 to 2.2, you must grant navigation permissions to existing roles. The Templates and History sidebar items now require explicit ansible.templates.view and ansible.history.view permission grants. Without these permissions, non-admin users cannot see the Templates and History navigation items. Administrators and superusers are unaffected.
After upgrading, log in as an administrator, navigate to , and add ansible.templates.view and ansible.history.view to each role that requires access. For more information, see Configure role-based access control for Ansible automation portal.
When you upgrade, the entire system image is replaced atomically. If an upgrade causes issues, you can roll back to the previous image in one command.
Bootc downloads only the layers that changed between the current and new image, making incremental upgrades fast and bandwidth-efficient.
Bootc divides the filesystem into three categories that determine what happens during an upgrade:
| Path | Upgrade behavior | What the appliance stores here |
|---|---|---|
| /usr | Replaced atomically with the new image | Portal scripts, pre-baked Ansible plugins, image version stamp |
| /etc | Three-way merged (your changes are preserved) | Portal configuration (app-config.production.yaml), Quadlet files, Quadlet drop-ins, SSL certificates |
| /var | Never touched by bootc | PostgreSQL database, backups, Podman secrets, generated configs |
Your configuration files in /etc are preserved through upgrades using a three-way merge: bootc compares the original file from the old image, your modified version, and the new file from the new image. Your changes take precedence. Files in /var (database, backups) are never modified by bootc.
For more information about RHEL image mode, see Managing RHEL bootc images.
Prerequisites:
- Back up and restore data before upgrading.
- For connected upgrades, authenticate to
registry.redhat.io(see the Authenticate to the container registry section). - For disconnected upgrades, Upgrade the Ansible automation portal RHEL appliance in a disconnected environment.
Authenticate to the container registry Copy linkLink copied!
To pull new appliance images from registry.redhat.io, authenticate to the registry and save the credentials where bootc can find them.
Bootc and Podman use separate credential stores. The --authfile /etc/ostree/auth.json flag saves credentials to the location that bootc upgrade and bootc switch read. Running podman login without --authfile stores credentials only for Podman and does not authenticate bootc operations.
Procedure:
- SSH into the Ansible automation portal RHEL appliance and log in to the container registry:
$ sudo podman login --authfile /etc/ostree/auth.json registry.redhat.io
Upgrade the appliance Copy linkLink copied!
Procedure:
- Back up and restore data.
- Run the upgrade:
$ sudo bootc upgradeThe upgrade is staged and does not take effect until you reboot. The current version continues running. You can schedule the reboot for a convenient maintenance window.
bootc upgradepulls the latest image for the current tag. To upgrade to a specific version, usebootc switchwith a version tag:$ sudo bootc switch registry.redhat.io/ansible-automation-platform/bootc-automation-portal-rhel9:version - Reboot to activate the new image:
$ sudo systemctl reboot
Verification:
- Verify that the new image is booted:
$ sudo bootc statusThe booted digest matches the digest from the upgrade output. The previous version is retained as a rollback target.
- Check the portal service logs:
$ sudo journalctl -u portal -f - Verify that all services are running:
$ sudo systemctl status portal postgres devtoolsAll three services (
portal,postgres,devtools) showactive (running).
Roll back an upgrade Copy linkLink copied!
Bootc maintains two image slots: the booted image and one rollback image. After an upgrade, the previous version becomes the rollback target. After a rollback, the upgraded version becomes the rollback target. You can switch between the two versions as needed.
If the new version has issues, roll back to the previous image.
Procedure:
- Roll back to the previous image:
$ sudo bootc rollback - Reboot to activate the rollback image:
$ sudo systemctl reboot
Verification:
- Confirm the rollback was applied:
$ sudo bootc statusThe booted image shows the previous digest. The upgraded image is now listed as the rollback target.
- Verify that all services are running:
$ sudo systemctl status portal postgres devtools
What survives an upgrade Copy linkLink copied!
The following table describes what happens to each type of content during a bootc upgrade of the Ansible automation portal RHEL appliance.
| Content | Location | Survives upgrade | Notes |
|---|---|---|---|
| Portal configuration | /etc/portal/configs/ | Yes | Three-way merge preserves your modifications |
| SSL certificates | /etc/portal/ssl/ | Yes | Three-way merge |
| Quadlet drop-ins | /etc/containers/systemd/portal.container.d/ | Yes | Three-way merge |
| Quadlet port customization | /etc/containers/systemd/ | Yes | Three-way merge |
| PostgreSQL data | /var/lib/portal/postgres-data/ | Yes | Never touched by bootc |
| Backups | /var/lib/portal/backups/ | Yes | Never touched by bootc |
| Podman secrets | /var/lib/containers/ | Yes | Never touched by bootc |
| Ansible plugins | /usr/share/portal/plugins/ | Updated | New plugins from the new image |
| Portal scripts | /usr/share/portal/scripts/ | Updated | New scripts from the new image |
| Dynamic plugin configs | /var/lib/portal/dynamic-plugins-root/ | Cleared | Regenerated from new plugins on first start |
Post-upgrade reconciliation Copy linkLink copied!
After reboot, the appliance automatically reconciles Ansible plugins and configuration with the new image version:
- Clears the dynamic plugins directory so that plugins are regenerated from the new image.
- Clears generated configuration files (regenerated on portal start).
- Creates any new directories required by the new image version.
- Fixes file ownership for portal and PostgreSQL directories.
Upgrade the Ansible automation portal RHEL appliance in a disconnected environment Copy linkLink copied!
In disconnected environments, you can upgrade the Ansible automation portal RHEL appliance using a mirror registry. Configure the mirror registry so that bootc upgrade pulls images from your internal registry instead of registry.redhat.io.
Before you begin Copy linkLink copied!
- A mirror registry is accessible from the Ansible automation portal RHEL appliance on the internal network.
- The new appliance image is copied to the mirror registry.
- You have SSH access to the appliance.
About this task Copy linkLink copied!
Once the mirror registry is configured, bootc upgrade checks the mirror automatically.
Procedure Copy linkLink copied!
Results Copy linkLink copied!
The mirror configuration in /etc/containers/registries.conf.d/ survives bootc upgrades because bootc preserves /etc using a three-way merge. You do not need to reconfigure the mirror after each upgrade.
Verify that the new image is booted:
$ sudo bootc status
Verify that all services are running:
$ sudo systemctl status portal postgres devtools
What to do next Copy linkLink copied!
Sync new versions to the mirror
When a new appliance version is available, copy it to the mirror from a connected machine:
- Copy the new image version to the mirror registry:
$ skopeo copy \ docker://registry.redhat.io/ansible-automation-platform/bootc-automation-portal-rhel9:new-version \ docker://mirror.internal.example.com:5000/ansible-automation-platform/bootc-automation-portal-rhel9:new-version - On the appliance, run the upgrade and reboot:
$ sudo bootc upgrade $ sudo systemctl reboot
Cloud-init reference Copy linkLink copied!
The following tables describe all cloud-init fields supported by the Ansible automation portal RHEL appliance.
SSH access (standard cloud-init) Copy linkLink copied!
| Field | Required | Default | Description |
|---|---|---|---|
users[].name |
Yes | -- | Linux username for SSH access. |
users[].sudo |
Yes | -- | Sudo privileges. Use ALL=(ALL) NOPASSWD:ALL. |
users[].ssh_authorized_keys[] |
Yes | -- | One or more SSH public keys. |
Ansible Automation Platform connection Copy linkLink copied!
| Field | Required | Default | Description |
|---|---|---|---|
aap.host_url |
Yes | -- | Ansible Automation Platform URL (for example, https://aap.example.com). |
aap.token |
Yes | -- | Ansible Automation Platform API token with administrator privileges. |
aap.check_ssl |
No | true |
Set false for self-signed Ansible Automation Platform certificates. |
aap.oauth.client_id |
Yes | -- | OAuth 2.0 application client ID. |
aap.oauth.client_secret |
Yes | -- | OAuth 2.0 application client secret. |
Database Copy linkLink copied!
| Field | Required | Default | Description |
|---|---|---|---|
database.type |
No | builtin |
builtin or external. |
database.builtin.password |
No | auto |
PostgreSQL user password. auto generates a random value. |
database.builtin.admin_password |
No | auto |
PostgreSQL admin password. auto generates a random value. |
database.builtin.name |
No | portal_db |
Database name. |
database.builtin.user |
No | portal_user |
Database user. |
database.external.host |
Yes (if external) | -- | External PostgreSQL hostname. |
database.external.port |
No | 5432 |
External PostgreSQL port. |
database.external.name |
No | portal_db |
External database name. |
database.external.user |
No | portal_user |
External database user. Requires the CREATEDB privilege. |
database.external.password |
Yes (if external) | -- | External database password. |
database.external.ssl |
No | true |
Enable SSL for external database connection. |
Security Copy linkLink copied!
| Field | Required | Default | Description |
|---|---|---|---|
security.backend_secret |
No | auto |
Backend authentication secret. auto generates a random value. |
Network Copy linkLink copied!
| Field | Required | Default | Description |
|---|---|---|---|
network.port |
No | 443 |
Ansible automation portal HTTPS listen port. If you are using the standard port 443, you do not need to specify this field. |
network.base_url |
No | Auto-detected | User-accessible URL that users enter in their browser. Set this when users access Ansible automation portal through a hostname, route, or load balancer. If omitted, auto-detected from the VM IP address. |
Source control integrations Copy linkLink copied!
| Field | Required | Default | Description |
|---|---|---|---|
integrations.github.url |
No | github.com |
GitHub hostname. For GitHub Enterprise, omit https://. |
integrations.github.token |
No | -- | GitHub personal access token. |
integrations.gitlab.url |
No | gitlab.com |
GitLab hostname. For self-hosted GitLab, omit https://. |
integrations.gitlab.token |
No | -- | GitLab personal access token. |
Portal CLI commands reference Copy linkLink copied!
The Ansible automation portal appliance provides the ansible-portal management CLI for administration and troubleshooting.
Accessing the appliance Copy linkLink copied!
You can access the appliance using SSH with the key you provided during initial configuration:
ssh -i /path/to/ssh-key/id_ed25519 -p port_number admin@VM_IP
Replace the following placeholders:
/path/to/ssh-key/id_ed25519with the path to your SSH private key.port_numberwith the SSH port number (default is 22).VM_IPwith the IP address or hostname of your appliance.
The ansible-portal CLI Copy linkLink copied!
The ansible-portal command is the primary management interface for the appliance, following Red Hat Ansible tooling conventions (ansible-navigator, ansible-builder, ansible-lint).
ansible-portal <command> [options]
| Command | Description |
|---|---|
status |
Show portal service status and diagnostics. |
backup |
Create portal backup. Use --list to list backups. |
restore file |
Restore from backup archive. Use --latest for most recent. |
registry-login |
Log in to container registry for image upgrades. |
Run ansible-portal command --help for command-specific options.
ansible-portal status Copy linkLink copied!
Displays the current status of all Ansible automation portal services.
Usage:
sudo ansible-portal status # One-shot status display
sudo ansible-portal status --watch # Refresh status every 5 seconds
Description:
Displays the current status of all Ansible automation portal services, including:
- Setup completion status
- PostgreSQL database state and connectivity
- Devtools service state
- Portal service state and plug-in installation status
- Scheduled backup status
- Disk and memory resource usage
Use this command to verify that all services are running correctly after installation or troubleshooting. Use --watch to continuously monitor service status.
ansible-portal backup Copy linkLink copied!
Creates a backup of the portal configuration and data.
Usage:
sudo ansible-portal backup # Interactive backup (select content)
sudo ansible-portal backup --full # Full backup (all items)
sudo ansible-portal backup --minimal # Required items only
sudo ansible-portal backup --list # List existing backups
sudo ansible-portal backup --export /path/to/dir/ # Copy latest backup to a directory
Description:
Creates a backup archive containing the portal configuration, Podman secrets, and data. Use this command before making significant configuration changes or for disaster recovery planning.
backupwithout options starts an interactive backup where you select the content to include.--fullcreates a complete backup of all configuration and data.--minimalbacks up only the required configuration items.--listlists existing backups.--exportcopies the latest backup to the specified directory. If no backup exists, one is created first.
Backup archives contain credentials in plain text. Restrict file permissions on backup archives. Encrypt archives before transferring to remote storage:
gpg --symmetric --cipher-algo AES256 /var/lib/portal/backups/backup-file.tar.gz
Example output:
Portal Backup Tool
==================
1) Full backup (config + database + secrets) [recommended]
2) Config only (config + secrets, no database)
3) Database only
Select backup type [1]: 1
Creating backup...
Backing up configuration... done
Backing up secrets... done
Backing up database... done
Backup created: /var/lib/portal/backups/portal-backup-2026-05-07-143022.tar.gz
ansible-portal restore Copy linkLink copied!
Restores the portal from a backup.
Usage:
sudo ansible-portal restore --list # List available backups
sudo ansible-portal restore --latest # Restore the newest backup
sudo ansible-portal restore --latest --dry-run # Preview restore without changes
sudo ansible-portal restore /path/to/backup.tar.gz # Restore a specific backup file
Description:
Restores the portal configuration, Podman secrets, Quadlet drop-in files, and data from a backup created by ansible-portal backup.
--listlists all available backups.--latestrestores from the most recent backup.--dry-runpreviews what would be restored without making changes.- Specify a file path to restore from a specific backup archive.
Restoring a backup overwrites the current portal configuration. Use --dry-run to preview the restore before executing. Create a backup of the current state before restoring if you want to preserve it.
Example output:
Portal Restore Tool
===================
Restoring from: /var/lib/portal/backups/portal-backup-2026-05-07-143022.tar.gz
Stopping services...
Restoring configuration... done
Restoring secrets... done
Restoring database... done
Starting services...
Restore complete.
Services stop during restore and restart automatically.
ansible-portal registry-login Copy linkLink copied!
Manages container registry credentials for pulling portal images.
Usage:
sudo ansible-portal registry-login # Log in to registry.redhat.io (default)
sudo ansible-portal registry-login registry_host # Log in to a specific registry
sudo ansible-portal registry-login --test # Test stored credentials
sudo ansible-portal registry-login --logout # Remove stored credentials
Description:
Manages authentication to container registries used for pulling Ansible automation portal images and updates.
registry-loginwithout arguments prompts for credentials forregistry.redhat.io.- Specify a registry hostname to authenticate to a different registry, such as a private mirror.
--testverifies that stored credentials are valid by inspecting the registry without downloading images.--logoutclears stored credentials for the registry.
Use this command to configure registry authentication for bootc upgrade operations. In disconnected environments, use this command to authenticate to your private registry mirror.
In disconnected environments where no registry is available, you can bypass the registry authentication gate by creating an override marker:
sudo touch /etc/portal/.registry-auth-override
Configuration management Copy linkLink copied!
The appliance uses two YAML configuration files at /etc/portal/configs/app-config/:
-
app-config.yaml - Infrastructure configuration (base URL, database connection, TLS, system defaults). This file is set during initial deployment and is not typically modified.
-
app-config.production.yaml - Application configuration (Ansible Automation Platform connection, OAuth settings, SCM integrations, catalog sync). Edit this file for day-to-day configuration changes.
Sensitive values such as tokens and passwords are stored as Podman secrets and injected into the portal container through environment variable interpolation (${VAR} syntax in the YAML files).
Updating configuration
To update the portal configuration:
- Edit the application configuration file:
sudo vi /etc/portal/configs/app-config/app-config.production.yaml - Restart the portal service to apply the changes:
sudo systemctl restart portal
Managing secrets Copy linkLink copied!
The portal stores sensitive values as Podman secrets, separate from the configuration files.
| Secret name | Environment variable | Type |
|---|---|---|
portal_backend_secret |
BACKEND_SECRET |
Auto-generated |
portal_postgresql_password |
POSTGRESQL_PASSWORD |
Auto-generated or user-provided |
portal_postgresql_admin_password |
POSTGRESQL_ADMIN_PASSWORD |
Auto-generated |
portal_aap_token |
AAP_TOKEN |
User-provided |
portal_aap_oauth_client_secret |
AAP_OAUTH_CLIENT_SECRET |
User-provided |
portal_github_token |
GITHUB_TOKEN |
Optional |
portal_gitlab_token |
GITLAB_TOKEN |
Optional |
portal_github_app_id |
GITHUB_APP_ID |
User-provided (EE Builder, GitHub App) |
portal_github_app_client_id |
GITHUB_APP_CLIENT_ID |
User-provided (EE Builder, GitHub App) |
portal_github_app_client_secret |
GITHUB_APP_CLIENT_SECRET |
User-provided (EE Builder, GitHub App) |
portal_github_app_private_key |
GITHUB_APP_PRIVATE_KEY |
User-provided (EE Builder, GitHub App) |
portal_github_oauth_client_id |
GITHUB_OAUTH_CLIENT_ID |
User-provided (EE Builder, GitHub OAuth) |
portal_github_oauth_client_secret |
GITHUB_OAUTH_CLIENT_SECRET |
User-provided (EE Builder, GitHub OAuth) |
portal_gitlab_oauth_client_id |
GITLAB_OAUTH_CLIENT_ID |
User-provided (EE Builder, GitLab OAuth) |
portal_gitlab_oauth_client_secret |
GITLAB_OAUTH_CLIENT_SECRET |
User-provided (EE Builder, GitLab OAuth) |
EE Builder secrets (prefixed with portal_github_app_, portal_github_oauth_, or portal_gitlab_oauth_) require a Quadlet drop-in file (ee-builder-secrets.conf) to map Podman secrets to container environment variables. See the Configuring execution environment builder guide for instructions.
The portal-backup utility does not capture EE Builder secrets or custom Quadlet drop-in files. Store secret values and the contents of ee-builder-secrets.conf in a secure external location.
Listing secrets
sudo podman secret ls
Updating a secret
To update a secret value, remove the existing secret and create a new one. Write the value to a temporary file on tmpfs to avoid exposing it in the process list:
sudo podman secret rm portal_aap_token
temp_file=$(mktemp -p /dev/shm) && chmod 600 "$temp_file"
printf '%s' "new_token_value" > "$temp_file"
sudo podman secret create portal_aap_token "$temp_file"
rm -f "$temp_file"
sudo systemctl restart portal
Troubleshooting RHEL appliances Copy linkLink copied!
Common issues and solutions for deploying and managing Ansible automation portal RHEL appliances.
View logs and service status Copy linkLink copied!
Start troubleshooting by checking the status of all services and reviewing recent logs.
Check the status of all services:
$ sudo systemctl status portal postgres devtools
A service that failed to start shows active (failed) or inactive (dead).
View recent portal logs:
$ sudo journalctl -u portal -n 200 --no-pager
Check the bootc image status:
$ sudo bootc status
Portal services do not start Copy linkLink copied!
Symptom: The Ansible automation portal service is not running after boot.
Cause: The Ansible automation portal RHEL appliance requires Ansible Automation Platform credentials in the cloud-init user-data to complete setup. If you provided SSH keys but no aap: section, you can SSH in but Ansible automation portal services do not start.
Resolution:
- Check the portal service logs for errors:
$ sudo journalctl -u portal -b --no-pager - Verify that your cloud-init user-data includes the required
aap:section withhost_url,token,client_id, andclient_secret. - If the configuration is missing or incorrect, edit the configuration file directly:
$ sudo vi /etc/portal/configs/app-config/app-config.production.yamlUpdate
ansible.rhaap.baseUrl,auth.providers.rhaap.production.clientId, and other required values. - If Ansible Automation Platform credentials need to be updated, use Podman secrets:
$ temp_file=$(mktemp -p /dev/shm) && chmod 600 "$temp_file" $ printf '%s' "aap-token" > "$temp_file" $ sudo podman secret rm portal_aap_token $ sudo podman secret create portal_aap_token "$temp_file" $ rm -f "$temp_file"$ temp_file=$(mktemp -p /dev/shm) && chmod 600 "$temp_file" $ printf '%s' "oauth-client-secret" > "$temp_file" $ sudo podman secret rm portal_aap_oauth_client_secret $ sudo podman secret create portal_aap_oauth_client_secret "$temp_file" $ rm -f "$temp_file" - Restart the Ansible automation portal service:
$ sudo systemctl restart portal
OAuth login fails Copy linkLink copied!
Symptom: After clicking Sign in with RHAAP, the browser redirects back to the login page or Ansible Automation Platform returns "Invalid redirect_uri."
Cause: The OAuth redirect URI in Ansible Automation Platform does not match the Ansible automation portal user-accessible URL, or the app.baseUrl, backend.baseUrl, and backend.cors.origin values in the configuration file are not consistent with each other.
Resolution:
- Check the current user-accessible URL and CORS configuration:
$ grep -E 'baseUrl|origin' /etc/portal/configs/app-config/app-config.production.yaml - Verify that
app.baseUrl,backend.baseUrl, andbackend.cors.originall use the same address. - Verify that the OAuth application redirect URI in Ansible Automation Platform matches the format
https://portal-address/api/auth/rhaap/handler/frame. - If the values do not match, update either:
- The OAuth redirect URI in Ansible Automation Platform (if the Ansible automation portal address is correct), or
- The Ansible automation portal user-accessible URL and CORS origin in
app-config.production.yaml(if the OAuth URI is correct).
- Restart the Ansible automation portal service after any configuration change:
$ sudo systemctl restart portal
GitHub login appears instead of RHAAP Copy linkLink copied!
Symptom: The login page shows a "Sign in with GitHub" option instead of "Sign in with RHAAP," or both options appear.
Cause: The app.baseUrl, backend.baseUrl, and backend.cors.origin values in the configuration file do not match the URL used to access the Ansible automation portal RHEL appliance. This commonly happens when accessing the VM by IP address but the configuration uses a domain name, or vice versa. The CORS mismatch can cause the RHAAP provider to fail silently, falling back to a GitHub provider if one is configured.
Resolution:
- Check the configured authentication providers:
$ grep -A 5 'auth:' /etc/portal/configs/app-config/app-config.production.yaml - Verify that the
auth.providerssection containsrhaapand does not containgithub. If agithubprovider is present, remove it. - Verify that
app.baseUrl,backend.baseUrl, andbackend.cors.originall match the URL you use to access the Ansible automation portal RHEL appliance in your browser:$ grep -E 'baseUrl|origin' /etc/portal/configs/app-config/app-config.production.yaml - Restart the Ansible automation portal service after any configuration change:
$ sudo systemctl restart portal
Login fails with a 500 error Copy linkLink copied!
Symptom: After clicking Sign in with RHAAP, the browser shows a 500 Internal Server Error or redirects to an error page instead of completing the login.
Cause: A 500 error during login typically indicates that the Ansible Automation Platform API token or OAuth client secret is invalid, expired, or missing. The Ansible automation portal cannot authenticate with the Ansible Automation Platform instance.
Resolution:
- Check the portal logs for authentication errors:
$ sudo journalctl -u portal -n 100 --no-pager | grep -i -E 'auth|oauth|401|403|500|error' - Verify that the required Podman secrets exist:
$ sudo podman secret ls | grep -E 'aap_token|oauth'You should see both
portal_aap_tokenandportal_aap_oauth_client_secretlisted. If either is missing or the values need to be updated, recreate them:$ temp_file=$(mktemp -p /dev/shm) && chmod 600 "$temp_file" $ printf '%s' "new-aap-token" > "$temp_file" $ sudo podman secret rm portal_aap_token $ sudo podman secret create portal_aap_token "$temp_file" $ rm -f "$temp_file" - Verify that the Ansible Automation Platform instance is reachable from the appliance:
$ curl -sk https://aap-host/api/v2/ping/ - Verify that the OAuth client ID in the configuration matches the OAuth application in Ansible Automation Platform:
$ grep clientId /etc/portal/configs/app-config/app-config.production.yaml - Restart the Ansible automation portal service after any changes:
$ sudo systemctl restart portal
Cannot SSH to the VM Copy linkLink copied!
Symptom: SSH connection refused or permission denied.
Cause: The appliance enforces SSH key-only authentication. Password login is disabled.
Resolution:
- Verify that your SSH private key matches the public key you provided in the cloud-init user-data.
- Verify that you are using the correct username from your cloud-init configuration.
If you have lost access to your SSH key, use platform-specific recovery:
- KVM: Access the VM console with
virsh console vm-nameand add a new SSH key. - Red Hat OpenShift Virtualization: Access the VM console with
virtctl console vm-name -n namespace. - VMware vSphere: Use the vSphere console with
systemd.unit=rescue.targetboot parameter to add a new SSH key.
VM is inaccessible Copy linkLink copied!
Symptom: The VM was deployed without cloud-init user-data. No SSH keys or Ansible Automation Platform credentials are configured.
Cause: The appliance has no default password. Without cloud-init configuration, the VM is not accessible.
Resolution: Redeploy the VM with a cloud-init configuration attached. See Configure the appliance at first boot.
Red Hat OpenShift Virtualization issues Copy linkLink copied!
Symptom: Upload, boot, or scheduling failures when deploying on Red Hat OpenShift Virtualization.
Resolution:
- Upload fails with "effective image size is larger than available storage"
-
Increase
--size(for example, from 40 Gi to 50 Gi). Check the virtual size withqemu-img info disk.qcow2. - Upload hangs at "Waiting for PVC upload pod to be ready"
-
The storage class uses
WaitForFirstConsumerbinding. Add--force-bindto thevirtctlcommand. - VM shows "Boot failed: not a bootable disk"
- The disk image was not properly converted during upload. Verify the upload completed with "Processing completed successfully." If processing was interrupted, delete the DataVolume and PVC and re-upload.
- VM stuck in Scheduling with "Insufficient memory"
- Reduce the VM memory request or add cluster resources.
VMware vSphere troubleshooting Copy linkLink copied!
- Disk conversion fails with vmkfstools
-
- Verify that you have SSH access to the ESXi host.
- Verify that the
disk.vmdkfile was uploaded successfully to the datastore. - Check that you have sufficient permissions to run
vmkfstoolson the ESXi host. - Verify that there is sufficient free space on the datastore for the converted disk.
- Virtual machine fails to boot after attaching the disk
-
- Verify that you selected the correct disk file.
- Verify that the disk is attached to the correct SCSI controller and bus.
- Check the virtual machine boot order settings and ensure the hard disk is the first boot device.
- Cannot upload disk image to datastore
-
- Verify that your user account has permissions to upload files to the datastore.
- Check that there is sufficient free space on the datastore.
- Verify that the vSphere web client is properly connected.
Collect diagnostic information Copy linkLink copied!
If an issue persists, collect the following information before contacting support:
$ sudo systemctl status portal postgres devtools > service-status.txt
$ sudo journalctl -u portal -n 200 > portal-logs.txt
$ sudo journalctl -u postgres -n 100 > postgres-logs.txt
$ sudo journalctl -u devtools -n 100 > devtools-logs.txt
$ sudo bootc status > bootc-status.txt
$ cat /etc/os-release > os-release.txt
SSH key recovery Copy linkLink copied!
After initial configuration, the admin user account is locked and console login is disabled. If you lose SSH access, use one of the following recovery methods for your deployment environment.
Back up your SSH private key before configuring the appliance. If you lose your SSH key, you must use infrastructure-level access (hypervisor console, cloud provider tools) to recover.
Recovery on Red Hat OpenShift Virtualization Copy linkLink copied!
- Access the virtual machine console through the Red Hat OpenShift Container Platform web console.
- Reboot the virtual machine.
- At the GRUB boot menu, press e to edit boot parameters.
- Add
init=/bin/bashto the end of the kernel line. - Press Ctrl+X to boot into an emergency shell.
- Remount the filesystem and add a new SSH key:
mount -o remount,rw / passwd -u admin mkdir -p /home/admin/.ssh echo "your_ssh_public_key" >> /home/admin/.ssh/authorized_keys chown -R admin:admin /home/admin/.ssh chmod 600 /home/admin/.ssh/authorized_keys restorecon -R /home/admin/.ssh passwd -l admin exec /sbin/init
Recovery on VMware vSphere Copy linkLink copied!
- Open the virtual machine console in vCenter.
- Reboot the virtual machine.
- At the GRUB boot menu, press e to edit boot parameters.
- Add
init=/bin/bashto the end of the kernel line. - Press Ctrl+X to boot into an emergency shell.
- Remount the filesystem and add a new SSH key:
mount -o remount,rw / passwd -u admin mkdir -p /home/admin/.ssh echo "your_ssh_public_key" >> /home/admin/.ssh/authorized_keys chown -R admin:admin /home/admin/.ssh chmod 600 /home/admin/.ssh/authorized_keys restorecon -R /home/admin/.ssh passwd -l admin exec /sbin/init
Recovery on KVM Copy linkLink copied!
Shut down the virtual machine and mount the QCOW2 image directly to add a new SSH key:
$ sudo modprobe nbd max_part=8
$ sudo qemu-nbd --connect=/dev/nbd0 disk.qcow2
$ sudo fdisk -l /dev/nbd0
$ sudo mount /dev/nbd0pN /mnt
$ sudo mkdir -p /mnt/home/admin/.ssh
$ echo "your_ssh_public_key" | sudo tee -a /mnt/home/admin/.ssh/authorized_keys
$ sudo chown 1000:1000 /mnt/home/admin/.ssh/authorized_keys
$ sudo chmod 600 /mnt/home/admin/.ssh/authorized_keys
$ sudo umount /mnt
$ sudo qemu-nbd --disconnect /dev/nbd0
Where:
fdisk -l /dev/nbd0lists partitions to identify the root filesystem. The root partition is typically the largest partition.- Replace N in
/dev/nbd0pNwith the correct root partition number from thefdiskoutput.
Account locking behavior Copy linkLink copied!
When the admin account is locked with passwd -l, the system adds a ! prefix to the password hash in /etc/shadow. This disables all password-based authentication (console login, SSH password auth) while SSH key authentication continues to work.
To temporarily unlock the account for recovery, use passwd -u admin. After adding a new SSH key, lock the account again with passwd -l admin for security.