Things are pretty hectic here on the developer advocacy team. We spent last week at Devoxx Belgium in Antwerp, and this week we’ll be jetting around Europe and North America as part of the Getting Git Right tour. But, in the time I’ve had at my desk in Amsterdam, I’ve hacked together some cool workflows using Bamboo and Docker (more on that in a later blog post). This has meant getting some instances of Stash and Bamboo up and running, often repeatedly as I experimented with different techniques. And because I’m lazy (or possibly virtuous), I’ve been automating the process as I go, minimizing the number of manual steps required so I can create and destroy instances of our products on a whim—cattle rather than pets.

In the case of Stash, I’ve now tuned the process to the point where I can do a full production-grade install of Stash either to a Vagrant VM or a server with no manual steps. This requires a few non-standard tricks and some insider knowledge, so I thought I’d share them with the wider community here. First, I’ll walk through the steps required to configure a new Stash instance and provide the solution to automate that step. Then, I’ll provide an Ansible role and playbook to fully automate the installation and setup using current best practices.

Configuring Stash

Stash has one optional (but recommended) configuration step and two must do’s. These are:

Configure a database. Configure the license. Create an administrator account.

Configure the database

Database migration is pretty good in Stash, so it’s possible to just use the in-memory database at first and move to a production RDBMS later. However, since I’m all about laziness, I don’t want to do that. And luckily, Stash makes this easy. Its JDBC configuration is stored in a property file under its home. If it finds this file during installation it will just quietly use the settings it finds and move on to the next step.

So, to automate the database configuration:

Create the directory $STASH_HOME/shared/ In that directory create the file stash-config.properties and fill in your database JDBC details. For example, for a PostgreSQL DB the file would look like:



jdbc.driver=org.postgresql.Driver

jdbc.url=jdbc:postgresql://databasehost:5432/stashdb

jdbc.user=stash

jdbc.password=DBPASSWORD!



Configure the license and administrator

This is where the real trickiness comes in. Stash provides a REST API for querying and updating the license, and also for creating users and granting permissions. But there’s a chicken-and-egg problem here: only an admin user can access these REST resources, but we need to access them to create the administrator. Fun, eh?

A little inside knowledge comes in handy here. Many Atlassian tools ship with a dev-mode, which runs them in a state suitable for development and debugging at the cost of some security. In the case of Stash, the dev-mode installs a temporary (24-hour) license and sets up a temporary administrator account with a default password. Obviously this is horribly insecure, but we can use this (temporarily!) to get the chicken out of the egg:

Start up Stash in developer mode by setting the JVM property atlassian.dev.mode=true . The simplest way to do this is to set the JAVA_OPTS environment variable, e.g: export JAVA_OPTS=-Datlassian.dev.mode=true

. The simplest way to do this is to set the environment variable, e.g: Inject the Stash license via the license REST resource using the temporary admin login (admin/admin)

Add a new user via user administration REST resource

Elevate this user to a “System Administrator” via the user permissions REST resource.

Remove the developer-mode flag from JAVA_OPTS and restart the Stash server

Remove the admin and user users created by developer-mode.

From this point on any additional configuration can performed via the REST API using the administrator you just configured.

Automating with Ansible

Because I do this create/destroy cycle a lot, I’ve created some Ansible roles and playbooks to fully automate this process. It should be noted that these are currently somewhat specific to my preferred setup; in particular they assume Debian/Ubuntu packaging and use systemd for running Stash. The Vagrant setup goes as far as to coerce Ubuntu into using systemd! However they are good documentation-by-example and should hopefully serve as a reference for creating your own automated installs even if you’re not familiar with Ansible. They’re all available in my Bitbucket repository:

https://bitbucket.org/ssmith/atlassian-ansible

The scripts are a work-in-progress, so YMMV, but a quick overview of the steps the Stash role performs may help:

Installs any prerequisites (e.g. a Java VM and Git) Creates dedicated user to run Stash (recommended) Downloads and unpacks Stash Configures the Stash Tomcat with minimal write permissions (highly recommended) Creates the Stash home Configures the JDBC settings Configures a systemd service unit and uses it to set the necessary environment variables At this point the Stash server will be running, possibly in devmode depending on how the role is called (see below) If in devmode… Inject the license Create the admin user and grant permissions

To use this role it should be called twice. Once in devmode, and again in “normal” mode. For example, a playbook using it may look like:



---

- hosts: all

sudo: true

vars:

# Ideally these should be provided on the ansible-playbook command-line

# and stored somewhere secure

- stash_license: "YOUR_STASH_LICENSE_WITHOUT_NEWLINES"

- stash_admin_user: "admin"

- stash_admin_passwd: "A_SECURE_PASSWORD"

roles:

# 1st run does full setup in devmode

– { role: stash, stash_setup: true }

# 2nd reverts to non-devmode by overwriting the systemd service

– role: stash

Conclusion

The sysadmin world has been moving towards configuration-as-code for some time, but not all applications are amenable to automation. Atlassian is also working to make our applications more friendly to the virtuously lazy administrator. In particular, the Stash team is looking into making the above tricks unnecessary by exposing a dedicated setup API, although it isn’t available yet. But for the time being, I hope this helps you simplify your provisioning of Stash, either in production or in a Vagrant VM for testing of your deployments and upgrades.