🔥Let's Do DevOps: Building Ansible AWX with Vagrant in ~10 minutes
This blog series focuses on presenting complex DevOps projects as simple and approachable via plain language and lots of pictures. You can do it!
Hey all!
This guide walks through how to bring up Ansible AWX (the upstream open-source version of RedHat’s Ansible Tower) on your local computer using Vagrant. This can be great to play with AWX and test it. You could also use this ephemeral AWX instance on your workstation to build some what-if scenarios without spending a dime or touching any production infrastructure.
First, let’s talk about what AWX is and how Vagrant can help us effortlessly build this instance.
AWS: The Ansible Platform
RedHat maintains an open-source platform for running Ansible jobs called AWX. This code is available to review and use for free. From this codebase RedHat builds and maintains a commercial product, Ansible Tower. These projects are extremely similar, but I’m a big fan of open source projects, so you’ll hear me mostly refer to this as AWX.
Ansible: YAML the Apps
Ansible is another open-source tool from RedHat. It’s an agent-less application management and automation suite tool. Due to its flexible nature, it’s been built into some other automation flows, notably image generation and local provisioning, e.g. Vagrant.
It’s pretty cool to see the same tool building a local operating system within a Vagrant flow and also connecting to dozens or hundreds of remote servers and instructing them on how to provisioning and configure their applications and configuration.
VirtualBox
Virtualbox is an open source virtualization tool for your workstation. It’s sometimes a little rough around the edges but open source, so well supported by tons of tools. And you don’t have to deal with VMware’s wonky licensing web page (and yearly licensing model for upgrades? Come on.)
Vagrant: Painless Ephemeral Infrastructure
HashiCorp maintains an open source tool called Vagrant that helps spin up virtual environments, including complex multi-node deployments, as well as configure the applications within them.
As part of this blog, we’ll walk through how to deploy a CentOS7 box, about a dozen packages, then the 4 (!) containers that drive the AWX Ansible runner platform, configure it, and bring it up so you can access it on your local workstation.
That’s tons of work, but it’s almost entirely scripted and automated through the interplay of Vagrant and Ansible. Let’s get started.
Buying the Licensing
Lol, I’m just kidding. All of this software is free, as in beer and speech. Let’s actually do some work.
Install Vagrant + VirtualBox +Â Ansible
You can download and install vagrant here.
You can download and install virtualbox here.
Ansible can only be run from a Unix-like system, including MacOS systems (sorry Windows folks!). So that means we’ll need to also install Ansible. This one is a little harder since it isn’t a self-container installer. You can either use pip or my favorite package manager: brew.
Instructions on downloading and installing are here.
Now that our tooling is in order, let’s sync some code and get started.
On the Shoulders of Giants
Building all of this ourselves would take an extraordinary amount of time. Thankfully we don’t have to! Jeff Geerling has built and published a large number of Ansible roles to do all the things we need to, including deploying AWX.
He maintains a massive repo of cool stuff here:
geerlingguy/ansible-vagrant-examples
This repository contains a collection of example virtual machines running various applications. The VMs are created via…github.com
Sync this repo to your computer using git:
git clone git@github.com:geerlingguy/ansible-vagrant-examples.git
Next, let’s tell the ansible-galaxy tool to read our requirements for the AWX project and install them. CD into the AWX folder (ansible-vagrant-examples/awx) and run the following command:
ansible-galaxy install -r requirements.yml
You’ll see the ansible-galaxy tool download several requirements. It’ll look something like this:
kyler@computer awx % ansible-galaxy install -r requirements.yml
- downloading role 'repo-epel', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-repo-epel/archive/3.0.0.tar.gz
- extracting geerlingguy.repo-epel to /Users/kyler/Downloads/awx2/kymidd/ansible-vagrant-examples/awx/roles/geerlingguy.repo-epel
- geerlingguy.repo-epel (3.0.0) was installed successfully
- downloading role 'git', owned by geerlingguy
(etc)
Scrape the Rust Off
Note: I’ve opened PRs against both of the involved repos here, so these changes may no longer be necessary. Just in case they are, I’ll walk through them, but if you review the files and see the changes already made, then my PR is merged and you can skip to the next section!Â
PR1: https://github.com/geerlingguy/ansible-vagrant-examples/pull/84
PR2: https://github.com/geerlingguy/ansible-role-awx/pull/35
Update December 2020: Both PRs are now merged, and you should be able to skip any modifications and just run the build. Please let me know if you can’t!
Now, we can run a few commands and kick this off, but from the time JeffG published his code and now, the AWX installer has gotten a little rusty. We’ll need to make a few changes to the main installer and the roles before this will work correctly.
First, in the ansible-vagrant-examples/awx/provisioning/playbook.yml, we’ll need to update a few variables. After your changes your variable block should look like this:
vars:
awx_version: "devel"
nodejs_version: "6.x"
docker_compose_version: "1.27.4"
pip_install_packages:
- name: docker
docker_users:
- vagrant
Then we’ll move on to the AWX installer role that JeffG maintains. It’s here:
awx/roles/geerlingguy.awx/tasks/main.yml
Jump into that file, and we’ll need to add a few tasks. The last task in this file is:
- include: awx-install-playbook.yml
when: awx_run_install_playbook
We’ll need to do a few more things for AWX to start properly. Add the following tasks at the bottom.
- name: Pause for 30 seconds to permit awx_task to start
pause:
seconds: 30
- name: Restart container service
service:
name: docker
state: restarted
Remember, this is YAML so your spacing is necessary. Your new file should look like this:
Now we’re ready to build AWX!
Vagrant: Do the Thing!
Now Vagrant is ready to do some magic for us. Navigate to the root of the ansible-vagrant-examples/awx folder and run:
vagrant up
Vagrant will start doing all sorts of cool stuff to download this host, build it, configure it, all the things.
Be patient — this process takes about 10 minutes on my modern macbook pro. Hopefully after about 10 minutes you’ll see something like this that signifies everything has gone well:
If so, you now have AWX running on your computer! Woot!
Let’s go visit it: http://192.168.6.65. You can login with admin / password.
When you first visit you might see AWX doing some database work. This should only take a few minutes. If it’s been longer than 10 minutes I sometimes need to restart the docker service to get things back on track. If you need to (and only if you need to) you can restart the docker service:
vagrant ssh
sudo service docker restart
Cleaning Up
When you are finished with your work for the day you have two options. You can either suspend this host (to retain your changes). Next time you power it up you won’t need to spend 10 minutes waiting for it to build — it’s just a VM powering on.
vagrant suspend
Or you can destroy this host. This is a great way to start fresh if things go wrong and you want to rebuild entirely. Note that next time you’ll need to wait the 10-ish minutes for this host to build again.
! Second note: This command will destroy your AWX host and data. Make sure you've backed up whatever you need on this host before running.
vagrant destroy
Close It Up
In the coming weeks I’m going to walk through all sorts of cool stuff with AWX and Ansible. Upcoming awesomeness:
Dynamic host inventories — So your jobs always target live hosts, AWX can sync with cloud metadata providers and organize hosts into groups.
Credentials — AWX has an unintuitive method of managing multiple credentials for a single job template. We’ll walk through how to manage them and how to build our own credentials templates.
Ansible Linting — We can sync AWX with a CI system, like GitHub or Azure DevOps where we can store our Ansible code, requirements, inventory scripts, static inventories, and more. We can even test Ansible code on PR creation to make sure spacing is correct.
Thanks all! Good luck out there.
kyler