Introduction
AWX is an open source community project which provides a web-based user interface, REST API, and task engine built on top of Ansible. It is the cutting-edge upstream for Ansible Controller, and enables users to better control their usage of Ansible in IT environments. It is especially useful for bigger environments, but even smaller environments can benefit from using AWX.
Sadly, since version 18.0.0, deploying AWX to a single host is no longer supported and Kubernetes should be used instead. However, in some cases (especially smaller setups), you want to run AWX without the overhead Kubernetes provides.
This guide covers the setup and basic configuration of AWX on Ubuntu 20.04, however, it should work just fine on other distributions with only minor changes.
Requirements
The Ansible Tower Installation and Reference Guide states the following minimum requirements:
- 2 CPU cores
- 4 GB RAM
- 20 GB storage
A Hetzner cloud server of type CX21 neatly fits those requirements (we even get more storage than we need). Any other, bigger cloud server (or even bare metal) would also work, but we're choosing a CX21 for this guide.
You will also need a domain name pointing to the server's IP address. And root access to the server.
Step 1 - Setting Up the Server
For the sake of simplicity, we expect you to already have a fresh installation of Ubuntu 20.04 on your server.
Step 1.1 - Configuring the Firewall
First up, we want to configure some basic Firewall rules for our server. When using a cloud server, you can use the integrated Firewall feature.
The following inbound permissive Firewall rules should be configured:
Source | Protocol | Port | Comment |
---|---|---|---|
Any | ICMP | - | Ping |
Any | TCP | 22 | SSH |
Any | TCP | 80 | HTTP |
Any | TCP | 443 | HTTPS |
Step 1.2 - Installing Required Packages
Docker Engine
The following commands will configure APT for the Docker repository:
apt install ca-certificates curl gnupg lsb-release
mkdir -v -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list
Now, install Docker Engine with the following commands:
apt update
apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
Additional Packages
We will also need some additional packages from the Ubuntu repository. Install them with the following command:
apt install git ansible make nginx certbot python3-certbot-nginx python3-setuptools-scm python3.9
Step 1.3 - Creating Systemd Unit
To make things a bit easier, we can create a systemd unit to control AWX.
Create a systemd service unit file /etc/systemd/system/awx.service
with the following content:
[Unit]
Description=AWX service (using Docker Compose)
Requires=docker.service
After=docker.service
[Service]
User=awx
WorkingDirectory=/opt/awx/awx
ExecStart=/usr/bin/docker compose -f tools/docker-compose/_sources/docker-compose.yml up
ExecStop=/usr/bin/docker compose -f tools/docker-compose/_sources/docker-compose.yml down
[Install]
WantedBy=multi-user.target
After that, run the following commands to enable the new systemd service:
systemctl daemon-reload
systemctl enable awx
After you complete the instructions in the next section (Step 2 - Installing AWX), you will be able to start/stop awx with commands:
systemctl start awx
systemctl stop awx
Step 2 - Installing AWX
Step 2.1 - Creating AWX User
Run the following command to add a new user that will be used to manage AWX:
useradd -s /bin/bash -m -d /opt/awx awx
-s /bin/bash
— Set login shell to/bin/bash
for interactive login.-m
— Create a home directory.-d /opt/awx
— Use custom home directory path.awx
— Login name.
And then add that user to the docker
group:
gpasswd -a awx docker
Step 2.2 - Checkout AWX Repository
To install AWX, we first need to clone the git repository. It contains some useful scripts that make running it locally quite a bit easier.
First, switch to the newly created awx
user. You can do that with this command:
su - awx
At the time of writing, version 21.10.0
was the available latest version.
You can find the latest version on AWX releases page.
Replace 21.10.0
with whatever is the latest version when you're running this command.
Additionally, we clone the awx-logos
repository to replace the placeholder images with the official AWX logos.
git clone -b 21.10.0 https://github.com/ansible/awx.git
git clone https://github.com/ansible/awx-logos.git
Step 2.3 - Configuring AWX
Now that we grabbed the latest version of AWX, it's time to configure it. We want to create our own branch to simplify merging our changes with later versions of AWX.
This can be done with the following command:
cd awx
git switch -c my-awx
switch
— A git command to switch between branches.-c <new-branch-name>
— Specifies a branch name to be created and switched.
First, we copy the respective assets from the awx-logos
repository into AWX:
cp ../awx-logos/awx/ui/client/assets/favicon.ico \
../awx-logos/awx/ui/client/assets/logo-header.svg \
../awx-logos/awx/ui/client/assets/logo-login.svg \
awx/ui/public/static/media/
Once that's done, we want to start editing our config files.
As a baseline, you want to set the hostname you're running AWX on and disable Debug-mode.
Do not forget to replace awx.example.com
with the hostname used for AWX:
echo "CSRF_TRUSTED_ORIGINS = ['awx.example.com']" >> tools/docker-compose/ansible/roles/sources/files/local_settings.py
echo "ALLOWED_HOSTS = ['awx.example.com']" >> tools/docker-compose/ansible/roles/sources/files/local_settings.py
echo "DEBUG = False" >> tools/docker-compose/ansible/roles/sources/files/local_settings.py
Depending on your setup, you might want to change additional options.
For example, if you want to use an external PostgreSQL database, you can configure it in tools/docker-compose/inventory
.
Once all changes are done, you want to commit them.
For that, you might need to configure your git identity.
You can do so with:
git commit -m "AWX config changes"
Step 2.4 - Building Docker Image
Building the image for Docker is as easy as it gets. Simply run the following command and grab a coffee (building the image might take a few minutes).
make docker-compose-build
Step 2.5 - Rendering Docker Compose Manifest
To render the Docker Compose manifest for AWX:
make awx/projects docker-compose-sources
Step 2.6 - Generating UI Files
By default, a source deployment of AWX comes without UI files, so we have to build them. Keep in mind that this does take several minutes, depending on your server.
docker compose -f tools/docker-compose/_sources/docker-compose.yml run --rm awx_1 make clean-ui ui-devel
Step 2.7 - Running AWX
Once the UI files have been built, we can start AWX with:
systemctl start awx
Upon the first run, AWX will apply database migrations, which might take a while. You can check the progress with
journalctl -f -u awx
If you see repeated errors about inotify watches
Failed to watch /awx_devel/awx; upper limit on inotify watches reached!
then increase the amount of inotify watches with the following commands:
echo 'fs.inotify.max_user_watches=524288' > /etc/sysctl.d/99-awx.conf
sysctl -p /etc/sysctl.d/99-awx.conf
Once AWX is ready, we want to change the password for the admin
user:
docker exec -ti tools_awx_1 awx-manage changepassword admin
AWX is now configured and should be running. But we're not quite done yet...
Step 3 - Configuring Nginx
This one should be quite easy, so we're not going into greater detail here.
However, it boils down to the following steps (as user root
):
Step 3.1 - Creating Nginx Config
In this example, I have the following configuration as the only contents of /etc/nginx/sites-available/default
.
Depending on your setup, you might want to change things a bit.
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name awx.example.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://localhost:8013;
}
}
After changing your nginx config, reload it with
systemctl reload nginx
Step 3.2 - Setting Up Certbot for Let’s Encrypt Certificates
This one is particularly easy.
Simply run certbot
and follow the instructions on-screen.
By default, you should be able to leave everything as-is.
At the very end, when you're asked if you want to set up a redirect, select option 2 (set up redirect).
Step 4 - Finishing Touches / Extras
Step 4.1 - Settings in the AWX Front-end
Once AWX is up and running, you want to change some additional settings in the front end.
Visit https://awx.example.com/#/settings/miscellaneous_system/details
and set the options below.
Don't worry about the logo.
This is the official development logo by AWX, as you apparently can't use the real logo due to trademark restrictions.
- Adjust the
Base URL of the service
- Add
"HTTP_X_FORWARDED_FOR"
toRemote Host Headers
Step 4.2 - Extra: Upgrading AWX
Upgrading AWX is quite straightforward and takes just a few minutes.
First, you need to stop AWX:
systemctl stop awx
After that, fetch the latest changes from the git repository.
As user awx
, run these commands.
Make sure to replace X.Y.Z
with the latest version from the AWX releases page.
cd /opt/awx/awx
git fetch --all --tags
git merge X.Y.Z
After that, simply repeat the following sections:
- Step 2.4 - Building Docker Image
- Step 2.5 - Rendering Docker Compose Manifest
- Step 2.6 - Generating UI Files
Finally, you can start the new version:
systemctl start awx
Just keep in mind that the first start might take a bit longer again, as there might be database migrations that need to be applied.
That's all you need to do to upgrade AWX to the latest version.
Conclusion
You've now set up your very own AWX instance.
Your next steps will probably be to further configure it by adding your inventory and linking it with your git repositories containing your playbooks. Once you've configured those two things, you should be ready to run your very first play on AWX.
In general, the Ansible Tower User Guide is a good way to learn more about AWX, even if the UI differs slightly between AWX and Ansible Tower.