ARA Records Ansible on Ubuntu 24.04 on Azure User Guide
Overview
ARA Records Ansible (ARA) is an open source, self hosted reporting tool for Ansible. A lightweight callback plugin captures every play, task, host and result as your playbooks run and sends it to a small API server, which stores the data and renders it in a clean web interface backed by a REST API. Point Ansible at the recorder, run your playbooks exactly as you already do, and a durable, queryable record of what ran, on which hosts, in what order and what changed builds up automatically.
The cloudimg image serves ARA 1.8.0 behind an nginx reverse proxy on a hardened, fully patched Ubuntu 24.04 LTS base. The Django API and UI application runs under gunicorn on the loopback interface (127.0.0.1:8000), nginx serves it on port 80, and Ansible plus the ara callback are installed on the appliance so it can record runs out of the box. The image is secure by default: unlike a manual install, it does not expose an unauthenticated read or write path. Both the reporting UI and the REST API require authentication, no administrator account and no shared password ship in the image, and a fresh application secret key and a unique administrator credential are generated on the first boot of every instance. Backed by 24/7 cloudimg support.
What is included:
- ARA Records Ansible 1.8.0 served by gunicorn behind nginx, managed by systemd
- The ARA reporting web UI and the REST API on
:80, both requiring authentication - Secure by default: read and write access are gated, with no open endpoint
- No default administrator: a unique admin credential is generated per instance on first boot
- A fresh Django secret key generated on the first boot of every instance
- Ansible (ansible-core) and the ara callback preinstalled so the appliance records runs out of the box
- The application server bound to
127.0.0.1:8000only, never exposed directly to the network nginx.serviceandara-web.serviceas enabled systemd units- 24/7 cloudimg support
Prerequisites
An active Azure subscription, an SSH key pair, and a VNet plus subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a sensible starting point; size up as your recorded history grows. NSG inbound: allow 22/tcp from your management network and 80/tcp for the reporting UI and API. ARA serves plain HTTP on port 80; for production, terminate TLS in front of it with your own domain. The application server is never exposed directly: it listens on 127.0.0.1:8000 only, so port 8000 stays off the network.
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for ARA Records Ansible by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTP (80). Then Review + create then Create.
Step 2 - Deploy from the Azure CLI
az vm create \
--resource-group <your-rg> \
--name ara \
--image <marketplace-image-urn> \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
Then open port 80 to the reporting UI and API:
az vm open-port --resource-group <your-rg> --name ara --port 80
Step 3 - Confirm the services are running
SSH in as azureuser and confirm nginx and the ARA application are active. Note that the application server listens only on 127.0.0.1:8000 while nginx serves the UI and API on port 80.
systemctl is-active nginx ara-web
Check the installed version and that gunicorn is bound to loopback only:
/opt/ara/venv/bin/python -c "from ara.setup import ara_version as v; print('ARA', v)"

Step 4 - Confirm secure by default and retrieve your admin credential
The image is secure by default. The open liveness endpoint answers without authentication, but the reporting UI and the REST API return 401 until you present the per instance administrator credential. Confirm it:
curl -s -o /dev/null -w 'GET /healthcheck/ -> HTTP %{http_code}\n' http://127.0.0.1/healthcheck/
curl -s -o /dev/null -w 'GET / (no auth) -> HTTP %{http_code}\n' http://127.0.0.1/
A 401 on / confirms there is no open read or write path. Your unique administrator credential was generated on first boot and written to a root only file. Read it over SSH:
sudo cat /root/ara-credentials.txt

Step 5 - Sign in to the reporting UI
Browse to http://<vm-public-ip>/. Your browser will prompt for a username and password: enter the ara.username and ara.password from the credentials file. The reporting UI opens on the Playbooks page, which lists every recorded Ansible run with its status, duration, controller, and host, task and result counts.

Step 6 - Record a playbook run
The appliance is preconfigured to record into the local ARA server: /etc/ara/ansible.cfg enables the ara callback and points it at http://127.0.0.1. View it:
cat /etc/ara/ansible.cfg
A helper on the appliance runs a small demo playbook through the ara callback, then reads it back through the authenticated API to prove the end to end record round trip. Run it:
sudo /usr/local/sbin/ara-record-check.sh

Step 7 - Explore a recorded run
Click any run on the Playbooks page to open its detail: the execution metadata, the Ansible, ara and Python versions, a summary of hosts, tasks, results, plays and files, and the full task results below.

The Tasks page lists every recorded task across your runs, with its action, name, path and status, so you can see at a glance which task failed on which host.

The Hosts page summarises the hosts that appeared in your runs and the results recorded against each.

Step 8 - Point your own Ansible control node at ARA
To record runs from a control node elsewhere, install ARA's client in that environment and enable the callback, then set the API client to HTTP and point it at this appliance with your administrator credential:
pip install ara
export ANSIBLE_CALLBACK_PLUGINS="$(python3 -m ara.setup.callback_plugins)"
export ANSIBLE_CALLBACKS_ENABLED=ara_default
export ARA_API_CLIENT=http
export ARA_API_SERVER=http://<vm-public-ip>
export ARA_API_USERNAME=ara
export ARA_API_PASSWORD=<the ara.password from /root/ara-credentials.txt>
ansible-playbook your-playbook.yml
Each subsequent ansible-playbook run is recorded into ARA and appears immediately in the reporting UI. You can add more users, or scope read and write access per user, from the Django admin at /admin/ or with sudo /usr/local/sbin/ara-manage createsuperuser.
Security notes
- ARA serves plain HTTP on port 80. For production, put it behind your own TLS terminating reverse proxy or an Azure Application Gateway with a certificate for your domain, and restrict port 80 in the NSG to trusted networks. A common approach is
certbotwith your-domain on a front end proxy. - The reporting UI and the REST API both require authentication, so there is no unauthenticated read or write path. Only the
/healthcheck/liveness endpoint, which reports up or down status only, is open. - The application server listens on
127.0.0.1:8000only and is never exposed directly; only nginx on port 80 faces the network. - The image ships with no administrator and no shared password, and no application secret key is baked into it. A fresh secret key and a unique administrator credential are generated on the first boot of every instance and written to a root only file, so there are no default credentials to rotate.
- Keep the VM patched. The image ships fully patched with unattended security upgrades enabled.
Support
cloudimg images come with 24/7 support. If you have any questions about this ARA Records Ansible image or need help with your deployment, contact us through the cloudimg website.