Ansible AWX Backup and Restore: A Practical Disaster Recovery Guide

I have been working with Ansible AWX on Kubernetes, and one thing I don't want to overlook is backup and recovery.

Getting AWX installed and running is one part of the job. Knowing what to do when the database is lost, a server fails, or the Kubernetes environment needs to be rebuilt is another.

I wanted to understand how to protect an existing AWX deployment and, more importantly, how to recover it without depending on the original Kubernetes nodes.

In this article, I am going through the AWX Operator backup and restore approach, the data that needs to be protected, and the things I would check before considering a recovery plan ready for production.

I am using the configuration of a real Kubernetes-based AWX environment as the reference. Hostnames and internal IP addresses have been left out.

1. My AWX environment

The environment I am referring to has two Kubernetes nodes running Ubuntu Server.

Component Version / Configuration
Operating system Ubuntu Server 22.04
Kubernetes 1.30.x
Container runtime containerd 1.7.24
Network plugin Calico
AWX Operator 2.19.1
Ansible AWX 24.6.1
PostgreSQL 15
Deployment method Helm
Namespace awx
Storage Kubernetes Local Persistent Volume

The AWX custom resource is named ansible-awx.

The main application components are:

  • AWX web
  • AWX task
  • PostgreSQL
  • AWX Operator

PostgreSQL uses persistent storage on the worker node. AWX web and task run as separate Kubernetes workloads.

The AWX configuration also has:

projects_persistence: false 

This is worth keeping in mind when planning a backup. The database and AWX configuration are important, but I also need to understand where project files, playbooks, inventories, and other external dependencies are stored.

2. What exactly needs to be backed up?

Before creating a backup, I wanted to understand what the AWX Operator actually includes.

The AWX Operator 2.19.1 backup role documents these components:

  1. Custom deployment-specific values from the AWX custom resource.
  2. PostgreSQL database backup.
  3. AWX secret key.
  4. Administrator password secret.
  5. Broadcast WebSocket secret.
  6. Database configuration.

This is important because copying only the PostgreSQL data directory is not the same as backing up the complete AWX deployment.

The secret key is particularly important. AWX uses it to protect sensitive information stored in the database. Losing the corresponding key can prevent the recovered instance from accessing encrypted data correctly.

I would therefore keep the database backup and the associated AWX secrets together as one recovery set.

I would also retain the AWX custom resource, Helm configuration, and any external configuration needed to rebuild the environment.

3. How the AWX Operator backup works

One useful feature of the AWX Operator is that it provides an AWXBackup custom resource.

Instead of manually copying files from a running PostgreSQL container, I can ask the operator to perform the backup.

The backup process stores its output on a PersistentVolumeClaim (PVC). The resulting backup archive can then be used by the operator's restore process.

For my deployment, the relevant names are:

Namespace: awx AWX deployment: ansible-awx Operator: 2.19.1 

The following example uses those names.

4. Preparing storage for the backup

This is the part I would plan carefully before creating the backup.

The backup needs somewhere to be stored. I would not rely on the same worker node and filesystem that hold the production PostgreSQL data as the only backup location.

If that node or its storage becomes unavailable, both the database and the backup could be affected.

I would use a separate backup storage location, ideally one that is independent of the Kubernetes cluster.

The AWX Operator supports an existing PVC through the backup_pvc setting.

For example, a backup PVC could be created using an approved backup StorageClass:

apiVersion: v1 kind: PersistentVolumeClaim metadata: name: awx-backup-pvc namespace: awx spec: accessModes: - ReadWriteOnce storageClassName: <backup-storage-class> resources: requests: storage: 20Gi 

Replace <backup-storage-class> with a StorageClass that actually exists in the cluster and is suitable for backup storage.

The capacity of 20Gi is only an example. I would size it after checking the current AWX database size, expected backup growth, and retention requirements.

Before proceeding, I would check:

kubectl get storageclass kubectl get pvc -n awx kubectl describe pvc awx-backup-pvc -n awx 

I would not assume that the existing PostgreSQL Local StorageClass is automatically suitable for backups. In particular, the backup should eventually be copied to storage independent of the production worker node.

5. Creating an AWX backup

Once the backup PVC is available, I can define an AWXBackup resource.

Create a file named awx-backup.yaml:

apiVersion: awx.ansible.com/v1beta1 kind: AWXBackup metadata: name: awx-backup-2026-11-03 namespace: awx spec: deployment_name: ansible-awx backup_pvc: awx-backup-pvc 

The important value here is:

deployment_name: ansible-awx 

This must match the name of the AWX custom resource being backed up.

The PVC name must also match the claim created for backup storage.

After reviewing the manifest and obtaining the required approval, the backup can be started with:

kubectl apply -f awx-backup.yaml 

This creates the backup custom resource. The operator then manages the backup process.

I would monitor it rather than assuming that creating the resource means the backup has completed.

Check the resource:

kubectl get awxbackup -n awx 

Check its details:

kubectl describe awxbackup awx-backup-2026-11-03 -n awx 

Check the operator logs:

kubectl logs deployment/awx-operator-controller-manager \ -n awx -c awx-manager --since=1h 

I would look for the backup operation's completion status and any errors reported by the operator.

6. Finding the backup location

After the backup has completed, the operator records information about the backup PVC and backup directory in the AWXBackup status.

I can retrieve the backup PVC name with:

kubectl get awxbackup awx-backup-2026-11-03 \ -n awx \ -o jsonpath='{.status.backupClaim}' echo 

To retrieve the backup directory:

kubectl get awxbackup awx-backup-2026-11-03 \ -n awx \ -o jsonpath='{.status.backupDirectory}' echo 

I would record both values.

They are useful if I need to recover from the backup later, particularly if the original AWXBackup custom resource is no longer available.

7. Keeping the backup outside Kubernetes

Creating a backup on a PVC is only one part of the process.

I would not consider the recovery plan complete if the only copy of the backup remains on the same Kubernetes cluster.

For example, if the cluster has a major storage failure, a backup stored only on a PVC inside that cluster might not be accessible.

My approach would be:

  1. Wait for the AWX Operator backup to finish.
  2. Confirm the backup PVC and backup directory.
  3. Copy the completed backup data to approved external storage.
  4. Keep the AWX configuration and required secrets protected separately as appropriate.
  5. Record the backup date, AWX version, Operator version, and backup location.
  6. Apply the organisation's retention and access-control policies.

The external destination could be an approved backup server, object storage, or another storage platform managed by the infrastructure team.

I would encrypt backup copies in transit and at rest, restrict access, and make sure retention policies do not remove the only usable recovery copy.

I would also avoid copying PostgreSQL's live data directory directly while the database is running. The operator's backup mechanism is the appropriate starting point for this workflow.

8. What should I keep with the backup?

Along with the backup archive, I would retain a small amount of deployment information.

For this environment, I would keep:

Item Why I keep it
AWX backup archive Database and AWX backup contents
AWX custom resource YAML Deployment-specific configuration
Helm values and release information Operator installation details
AWX Operator version Helps reproduce the same operator environment
AWX version Identifies the application version
PostgreSQL version Important for recovery compatibility
Required Kubernetes secrets Needed for the deployment, handled securely
Storage configuration Helps recreate the required PVCs
Network and service configuration Helps restore access to AWX

I would never store passwords, encryption keys, or Kubernetes credentials in a public Git repository.

The recovery copy of the secret material needs the same level of protection as the database backup itself.

9. Understanding the AWX restore process

The AWX Operator also provides an AWXRestore custom resource.

This is used to restore an AWX deployment from a backup created by the operator.

There are two useful pieces of information to understand:

  • deployment_name: the name of the AWX deployment to create.
  • backup_name: the name of the AWXBackup resource containing the backup information.

The operator's documented restore process creates a deployment from the backup.

For a disaster recovery exercise, I would prefer to restore into a separate recovery environment rather than immediately replacing the original production deployment.

That gives me a chance to verify the restored database, AWX interface, credentials, inventories, and job execution without putting the running environment at risk.

10. Example AWX restore manifest

Here is an example of an AWXRestore resource:

apiVersion: awx.ansible.com/v1beta1 kind: AWXRestore metadata: name: awx-restore-test namespace: awx-recovery spec: deployment_name: ansible-awx-recovery backup_name: awx-backup-2026-11-03 

This example assumes the recovery namespace and the backup resource are available in the way required by the operator.

If the backup PVC is in a different namespace, the restore resource can instead reference the backup PVC and backup directory using the backup_pvc, backup_pvc_namespace, and backup_dir fields supported by the operator.

For example:

apiVersion: awx.ansible.com/v1beta1 kind: AWXRestore metadata: name: awx-restore-test namespace: awx-recovery spec: deployment_name: ansible-awx-recovery backup_pvc: awx-backup-pvc backup_pvc_namespace: awx backup_dir: <backup-directory-from-awxbackup-status> 

The directory value must be the actual backupDirectory reported by the completed backup resource.

The recovery namespace must already exist, and the backup PVC must be accessible to the restore workflow.

I would verify the exact backup source and namespace before applying the restore manifest.

Important: The operator's documented in-place restore procedure has prerequisites involving the existing AWX custom resource and PostgreSQL PVC. It instructs administrators to remove the old AWX resource and database PVC before restoring over that deployment. Those are destructive operations. I would not run them against a live production deployment as part of a routine backup test.

For that reason, I would use a separate recovery environment for the first restore exercise.

11. Checking the restored AWX deployment

After starting a recovery exercise, I would monitor the restore resource and the resulting Kubernetes workloads.

Check the restore resource:

kubectl get awxrestore -n awx-recovery 

Describe it:

kubectl describe awxrestore awx-restore-test \ -n awx-recovery 

Check the AWX resource:

kubectl get awx -n awx-recovery 

Check the pods:

kubectl get pods -n awx-recovery 

Check the services:

kubectl get svc -n awx-recovery 

Once the application is available, I would verify the following:

  • Can I log in to the AWX web interface?
  • Are the expected organisations and teams present?
  • Are inventories and hosts present?
  • Are projects available?
  • Are job templates present?
  • Are credentials available and usable?
  • Can I launch a test job?
  • Are the expected schedules and workflows present?
  • Are there any database or application errors?

I would use a safe test inventory and a harmless job template during the recovery test.

A successful restore operation should not be judged only by whether the pods are running. The actual AWX data and application functions need to be checked as well.

12. My disaster recovery checklist

If I were preparing this AWX environment for disaster recovery, these are the checks I would want to have documented.

Check What I want to confirm
Backup creation AWX Operator reports successful completion
Database backup Database data is included
Secret preservation Required AWX secrets are protected
Backup storage Backup copy exists outside the original cluster
Retention More than one recovery point is available
Version information AWX and Operator versions are recorded
Recovery environment Kubernetes and storage are ready
Restore operation AWX restore completes
Application validation Inventories, credentials, templates, and jobs work
Recovery documentation Steps and dependencies are recorded

I would also define the recovery objectives with the application and infrastructure teams.

Two terms matter here:

RPO (Recovery Point Objective): How much data can the organisation afford to lose, measured in time?

RTO (Recovery Time Objective): How long can AWX remain unavailable before service needs to be restored?

These targets help decide how frequently backups should run and how quickly the recovery environment needs to be available.

13. A few things I would not overlook

There are a few points I would keep in mind when working with AWX backup and restore.

The encryption key matters.

Keeping a database dump without the corresponding AWX secret key is not a complete recovery strategy.

The backup needs independent storage.

A backup on the same node as the production database does not protect against every node or storage failure.

Local Persistent Volumes need special planning.

Since the PostgreSQL storage in this environment is local to a Kubernetes worker, the recovery plan needs to account for that node dependency. A replacement environment needs an appropriate storage configuration.

Projects and external dependencies need attention.

The AWX custom resource has projects_persistence: false. I would check how project content is supplied and whether the source repositories and any required execution environment images are still available.

A restore should be tested.

I would not wait until a production incident to discover that a backup cannot be restored.

Conclusion

For me, backing up AWX is not just about saving a PostgreSQL database.

The AWX database, encryption key, administrator credentials, deployment configuration, and supporting storage all have a part in recovering the service.

The AWX Operator makes the backup and restore workflow easier to manage through its custom resources, but the surrounding storage and recovery planning still need attention.

My preferred approach is to create operator-managed backups, keep independent copies outside the Kubernetes cluster, document the versions and configuration, and test recovery in a separate environment.

That way, if something happens to the original infrastructure, I have a recovery plan that I can actually follow rather than trying to work everything out during an outage.

I would rather spend time testing a recovery process beforehand than find out during an incident that the backup was never enough.

References

Thanks,
Sireesha K