Ansible playbooks and roles for setting up Beaglebone Black boards, and for deploying the Ninjablock software on systems that have otherwise been properly set up.
This project originally grew out of a desire to have a documented fully reproducible mechanism for taking a bare-bones (no pun intended) Ubuntu image from ELinux all the way to a fully installed Ninjablocks device.
The later batches of Ninjablocks (mine is from those delivered 2013, from the 2012 Ninjablocks Kickstarter) are essentially Beaglebone Black boards (with a 2GB eMMC) with an Arduino-based cape. It ran Ubuntu 13.04, with installation of software controlled by a byzantine maze of shell scripts. Most software was very outdated, and the Ninjablocks software itself was not only far from the latest versions available from the company's Github repositories, but also contained a good deal of local (uncommitted) changes. All this made it very difficult or impossible to test upgrades of any of the various components while retaining the possibility to either re-run or roll back changes.
The ELinux Ubuntu "console" images are quite minimal, and therefore before Ninjablocks can be deployed on top of them, they must undergo a variety of networking and other basic system configuration and software setup steps. This part is entirely independent of Ninjablocks, and has been separated into its own 'role'.
The following playbooks and roles are currently available:
-
bbb.yml
: playbook that applies thebbb-init
role to hosts in thefreshly-imaged
group.The playbook can start from a BBB plugged into the USB port of the host computer running Ansible and reachable at the default USB gadget IP 192.168.7.2. To limit the playbook to this use-case, append
--limit bb-usb
to theansible-playbook
command line (see below). -
roles/bbb-init
: role that initializes Beaglebone Black boards, starting from a (quite minimal) Elinux Ubuntu "console" image. Tasks in the role include setting timezone, changing hostname, configuring wireless network, ensuring network is up, and end in a reboot. The role's play will fail if it fails to either find working network (which will typically be via ethernet), or to bring up wireless network. -
ninjas.yml
: playbook that applies theninjablock
role to hosts in theninjas
group. You can ignore this playbook and theninjablock
role if you aren't looking to install a Ninjablock. -
roles/ninjablock
: role that installs all Ninjablocks software and dependencies. So that it can be applied independently, the role is intentionally not declared dependent onbbb-init
, although in practice almost all tasks in the role will fail if network and other system setup tasks have not been performed yet.
The playbooks can be run in the following way:
$ ansible-playbook -k -K -v <playbook>
Local configuration variables can be set (and others overridden) on
the command line using -e key=value
:
$ ansible-playbook -k -K -v -e timezone=America/New_York bbb.yml
The following variables are by default expected to be set from the command line; they have no default, and the corresponding system set up tasks are skipped for those that aren't set:
timezone
: name of timezone, if it is to be configurednew_hostname
: hostname to change the board towpa_ssid
: SSID of wireless network to which the board should be able to connect. Wireless network configuration is skipped if not set.wpa_passkey
: passkey for the wireless network.wpa_keymgmt
: wireless key management, defaults toWPA-PSK
.
Typical applications will likely not have a whole farm of
BBBs. Ansible allows limiting the hosts to which a playbook is applied
via the --limit
parameter. For example, to limit to the default
hostname under which a board with the Ubuntu image would appear on the
local network, you would do this:
$ ansible-playbook -k -K -v -e timezone=America/New_York bbb.yml --limit arm.local
Obviously, all the tasks executed by the Ansible playbooks could be effected by shell scripts as well, and most use-cases (including my own) will likely not involve a whole complex farm of BBB boards. So why not just run a bunch of shell scripts on the one or two target boards?
Based on spending countless hours trying to reverse engineer how a Ninjablock environment is set up and deployed factory-wise, shell scripts can be byzantine and very challenging to decipher in terms of what they do under which conditions with which outcomes. Shell scripts are also almost always written to assume a certain starting environment. If this starting point can't be reliably recreated, for example because the exact starting image isn't available - or, for that matter, desirable - anymore, then shell scripts are at increased risk of failing at some step(s) in typically difficult to diagnose and debug ways.
Though perhaps not as evident but IMO as or even more important, Ansible playbooks have status-checking built in through their declarative nature. Most tasks are (or can be) written by declaring the desired state. If this state is already present, no action is taken. This makes is possible to run the same playbook whether none, some, or all of the tasks have already been done previously, without any alterations such as conditionals etc.
Obviously, you must have Ansible installed. A version of at least 1.9+
is required. (At present, the roles on purpose do not use features
available only since Ansible 2.+. This means that for example on Mac
OSX, installing Ansible by homebrew
will suffice.)
The Beaglebone board is assumed to be a Beaglebone Black; the bbb
playbook may also work with other boards in the Beaglebone family, but
this is untested (and I only own BBBs).
At present, the Linux distribution is assumed to be Ubuntu, release 14.04 ("trusty"). This is in part because Ninjablocks, which originally motivated this project, use Ubuntu, and in part because (at least for "console") the Ubuntu images from ELinux require (in my experience anyway) much more setup to have functioning network and a reasonable system basis than the Debian images. I intend to expand the roles to Debian in the future. (One issue here is that Debian Jessie uses systemd, whereas Ubuntu Trusty still uses Upstart.)
This code is released under the terms of the MIT License, please see file LICENSE.