At MaestroDev we have been building what may be called, for lack of a better name, a DevOps Orchestration Engine, and is long overdue to talk about what we have been doing there and most importantly, how.
The basics of the application is to tie together the different systems involved in a Continuous Delivery cycle: Continuous Integration server, SCM, build tools, packaging tools, cloud resources, notification systems,… and streamline the process through these different tools. So it hooks into a bunch of popular tools to orchestrate interactions between them, an example:
This workflow, or as we call it, composition, will
- download a war file from a Maven repository (previously built by Jenkins)
- start an Amazon EC2 instance with Tomcat preinstalled
- deploy the war
- checkout the acceptance tests from Git
- run some tests with Maven (Selenium tests using SauceLabs) against that instance
- wait for an user to confirm before moving to the next step (to record the human approval or to do some extra manual tests if needed)
- destroy the Amazon EC2 instance
Maestro provides a nice web UI that gives visibility over the composition execution and an aggregated log from all the tools that run during the composition in a single place.
But the power comes with the combination of compositions together, as there are tasks for typical flows, such as running forking and joining compositions, call another composition in case of a failure, or waiting for a composition to finish.
Here we have a more complex setup with five compositions tied together.
- * – A composition that calls compositions 1 and 2.
- 1 – A Jenkins build
- 2 – The acceptance tests composition mentioned before
- 2a – Notification composition in case the acceptance tests fail
- 3 – Deployment to production
So you can see that compositions are not just limited to build, test, deploy. The tasks can be combined as needed to build your specific process.
Tasks are contributed by plugins, easily written in Ruby or Java, and define what fields are needed in the UI and what to do with those fields and the composition context. Maestro includes a lot of prebuilt tasks, publicly available on GitHub, from executing shell scripts to Jenkins job creation or Amazon Route 53 record management, but anything.
All the tasks share a common context and use sensible defaults, so if the scm checkout path is not defined it creates a specific working directory for the composition, and that is reused by the Maven, Ant,… plugins to avoid copying and pasting the fields. That’s also how a EC2 deprovision task doesn’t need any configuration if there was a provision task before in the composition, it will just deprovision those instances started previously in the composition by default.
You can take a look at our Maestro public instance, showing some examples and builds of public projects, mostly Puppet modules that are automatically built and deployed to the Puppet Forge, and Maestro plugins build and release compositions. In next posts I’ll be talking about the technologies used and distributed architecture of Maestro.
Next: (II) Architecture
