ARA for Debian

Are you ready for a quick post on how to deploy ARA on a Debian 11 server? Of course you are, you SuperChadGPT, leetcode, automaton. To bring the miracle of ARA to life we'll reach down in the primordial package manager to setup MariaDB and Gunicorn; a perfect paring for this twisted marriage of applications. Once everything is setup, ARA will be bound to localhost running the API server and storing robust logs.

💡
If you're unfamiliar with ARA (ARA Records Ansible) and/or not using Tower, you're probably still running Ansible like a caveman. Check out this link: https://ara.recordsansible.org - you're welcome.

While I don't think ARA will change your life, it will make you realize your automation is fundamentally flawed and your logging is inadequate. As ARA puts it, "ARA Records Ansible and makes it easier to understand and troubleshoot." In other words, ARA is like a tour guide for the torture chamber you call deployment code and centralization makes it possible to share your atrocities with teammates; shared pain is good pain.


Let's dive into the installation process of ARA, which is surprisingly simple. First we need to install some system packages. So let's get dirty with the following command:

apt install -y mariadb-server python3-full python3-dev default-libmysqlclient-dev build-essential

Once we've got that out of the way, we'll create a virtual environment and install some Python packages:

python3 -m venv /opt/ara/server
/opt/ara/server/bin/pip install ara[server] gunicorn passlib mysqlclient

Next we need to create a system user for ARA. Yes, a system user:

useradd --system --home-dir /var/lib/ara --shell /sbin/nologin ara

Now that we've got our user set up, let's create a systemd service unit for ARA:

[Unit]
Description=ARA Records Ansible API with gunicorn
After=network.target

[Service]
Slice=filecoin.slice
CPUAccounting=true
IOAccounting=true
MemoryAccounting=true
TasksAccounting=true
User=ara
RuntimeDirectory=ara-api
WorkingDirectory=/opt/ara
Environment=ARA_SETTINGS=/var/lib/ara/settings.yaml
ExecStart=/opt/ara/server/bin/gunicorn --workers=8 --bind 127.0.0.1 ara.server.wsgi
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target
ARA systemd unit file

But wait, we're not done yet! We need to create the database and user for ARA to function. Once you've logged into mariadb, run these commands:

create database ara_server;
create user 'ara'@'localhost' identified by 'secrete';
grant all on ara_server.* to 'ara'@'localhost' with grant option;

Now create the ARA server configuration file at /var/lib/ara/settings.yaml. Here's what that looks like:

default:
  ALLOWED_HOSTS:
  - ::1
  - 127.0.0.1
  - localhost
  - '*'
  BASE_DIR: /var/lib/ara
  BASE_PATH: /
  CORS_ORIGIN_ALLOW_ALL: true
  CORS_ORIGIN_REGEX_WHITELIST: []
  CORS_ORIGIN_WHITELIST:
  - http://127.0.0.1:8000
  - http://localhost:3000
  CSRF_TRUSTED_ORIGINS: []
  DATABASE_CONN_MAX_AGE: 0
  DATABASE_ENGINE: django.db.backends.mysql
  DATABASE_HOST: localhost
  DATABASE_NAME: ara_server
  DATABASE_OPTIONS: {}
  DATABASE_PASSWORD: secrete
  DATABASE_PORT: 3306
  DATABASE_USER: ara
  DEBUG: false
  DISTRIBUTED_SQLITE: false
  DISTRIBUTED_SQLITE_PREFIX: ara-report
  DISTRIBUTED_SQLITE_ROOT: /var/www/logs
  EXTERNAL_AUTH: true
  LOGGING:
    disable_existing_loggers: false
    formatters:
      normal:
        format: '%(asctime)s %(levelname)s %(name)s: %(message)s'
    handlers:
      console:
        class: logging.StreamHandler
        formatter: normal
        level: INFO
        stream: ext://sys.stdout
    loggers:
      ara:
        handlers:
        - console
        level: INFO
        propagate: 0
    version: 1
  LOG_LEVEL: INFO
  PAGE_SIZE: 100
  READ_LOGIN_REQUIRED: false
  SECRET_KEY: SuperSecreteKey
  TIME_ZONE: UTC
  WRITE_LOGIN_REQUIRED: false
ARA configuration file /opt/ara/settings.yaml
💡
Read up on all of the possible server configuration options https://ara.readthedocs.io/en/latest/api-configuration.html

Migrate the ARA database because now you have to use the database you created before with the following command:

export ARA_SETTINGS=/var/lib/ara/settings.yaml
/opt/ara/server/bin/ara-manage migrate

And lets create an admin user for ARA with the following command:

/opt/ara/server/bin/ara-manage createsuperuser --username=admin

Here's the last step required to get things running:

systemctl daemon-reload
systemctl start ara-api.service

Now What?

On your Ansible client, which for the sake of this post is assumed to be on the same node running ARA, we need to ensure we install the ara package wehever ansible is installed. There are a number of ways to install ara, but for the sake of simplicity I'm assuming you're using pip.

pip install ara

With the package installed, export some config and run ansible normally.

export ANSIBLE_CALLBACK_PLUGINS="$(python3 -m ara.setup.callback_plugins)"
export ARA_API_CLIENT="http"
export ARA_API_SERVER="http://127.0.0.1:8000"
export ANSIBLE_LOAD_CALLBACK_PLUGINS=True

After you're done running ansible normally, you can use the Web UI or CLI to begin your ARA interrogation of what all happened from within your playbooks.

ARA CLI
ara playbook list
+----+-----------+---------------------------+------+-----------------+--------------+-------+---------+-------+-----------------------------+-----------------+
| id | status    | controller                | user | ansible_version | path         | tasks | results | hosts | started                     | duration        |
+----+-----------+---------------------------+------+-----------------+--------------+-------+---------+-------+-----------------------------+-----------------+
|  1 | completed | ara-server                | root | 2.14.4          | Ad-Hoc: ping |     1 |       1 |     1 | 2023-04-05T16:13:51.889066Z | 00:00:00.336984 |
+----+-----------+---------------------------+------+-----------------+--------------+-------+---------+-------+-----------------------------+-----------------+
ARA Web UI
ARA UI

The End

So now that ARA is running you can use it; earth shaking conclusion I know... The CLI tools and Web UI make it possible for humans to start reviewing deployment travesties. The tools let you more effectively poke fun at teammates, and once everyone is done laughing, folks can come together and create change which improves the platform for everyone; all cynicism aside, ARA is an incredible companion for operations teams that leverage Ansible.