Spinnaker extensibility reaches new heights with Plugins hero graphic

Spinnaker extensibility reaches new heights with Plugins

Jul 13, 2020 by Ryan Pei

Before plugins existed…

Just last year, anyone who wanted to extend or customize Spinnaker faced a dilemma – go with something straightforward but a little hacky, or invest significant time and effort. Some “quick but hacky” methods may be familiar to you: SpEL expressions, custom run jobs, webhooks… these all work well in a pinch. But these are limited in functional scope, re-usability, and range of interoperability with different tools. In terms of more robust means of extending Spinnaker, you could either create extensions via classpath injection or fork Spinnaker services. If others wanted your extension, you might be able to add it directly to the open-source Spinnaker project. But these options require in-depth knowledge of Spinnaker’s codebase, so few teams outside the core community made these more heavyweight extensions.

This situation left us at Armory in a bind; we like to experiment and build cool new things with Spinnaker, but each small experiment was burdensome. Furthermore, the community was frustrated with the growing size and scope of each Spinnaker service. As specialized features piled onto services like Orca and Clouddriver, these grew from humble microservices into monoliths. The community wanted to bring the Spinnaker project back to a “lean core” model while still welcoming innovative contributors.

So, to meet this challenge…

Enter stage left StageDefinitionBuilder – the plugin framework

Our team thought about new ways to extend Spinnaker to achieve the happy medium between “quick but hacky” and “robust but rigorous.” We decided to introduce a plugin framework. Since Spinnaker is primarily comprised of Java microservices, we opted for a well-established plugin framework for Java applications, PF4J. We added extension points throughout the project to form the main integration points of this framework. Then, by using these extension points (or not using them at all, a bit more on this later), anyone can make their own extensions via a plugin.

I introduced a lot of vocab here, so allow me to define these words:

Plugin – In the context of Spinnaker, a plugin is an extension adding new functionality or updating existing functionality onto a Spinnaker service. A plugin is added via Halyard (and soon, Kleat) via a plugin configuration.

In terms of what should be a plugin versus what shouldn’t, this depends on several factors:

  • IF you want a reusable extension that requires code changes in Spinnaker
  • AND you don’t want to fork Spinnaker
  • AND you don’t think your extension belongs in the core open source project
  • THEN you likely want a plugin (some examples of plugins can be found here)

Extension point – Plugins need a way to extend Spinnaker functionality. An extension point is a designated interface class in the Spinnaker project intended explicitly for plugins to extend. Interfaces and abstract classes in Java are already extendable, so these extension points are like an API contract for plugin developers. An example of an extension point is StageDefinitionBuilder, which can be extended by plugins known colloquially as “custom stages”. A custom stage appears to a user like any other “default” stage. Plugins using this extension point comprise these custom stages. Note that a plugin does not require an extension point. A plugin can extend any interface or abstract class. There’s also a way to create plugins using Spring components, but we won’t get into detail on that yet.

Plugin framework – The framework includes these extension points and the PF4J libraries that enable these plugins in Spinnaker.

Note that plugins can also span across several Spinnaker services, not just one. This image below depicts two examples of plugins; one is an EventListener-based plugin (EventListener being an extension point in Echo) and the other is a custom stage plugin which spans several services. This custom stage plugin may extend StageDefinitionBuilder in Orca as well as interfaces in Clouddriver, while adding custom stage UI components in Deck. Both of these plugins change or add to the functionality of these pre-existing services.

Plugin architecture example
So now that you know what plugins are, we’ll discuss what kinds of nifty functionality these plugins can add.

What do I use plugins for?

Possibilities are endless, but we foresee five categories of extensions for which plugins should be the best way forward:

Custom stages

These stages already exist in other, non-plugin forms, such as the custom run job and the custom webhook stage. But none of these enable creating any kind of stage you want (while the custom run job is popular, it is limited to implementation via a K8s job, doesn’t enable several desired stage task features, and doesn’t allow much UI customization in Deck).

When creating a new stage, first familiarize yourself with custom run jobs and custom webhooks in case these methods are sufficient for you. Otherwise, you can create a custom stage plugin. Some examples:

Custom resources and resource handlers

Resources, such as infrastructure resources or pipeline dependencies, cover essentially everything Spinnaker manages and automates. Plugins can handle your own custom resources:

Cloud providers

Cloud providers, in the context of Clouddriver, refer to target platforms where Spinnaker can deploy workloads, such as Kubernetes, EC2, Cloud Foundry, etc. Before the plugin framework, adding a new cloud provider was a notoriously difficult task. We’re expecting to see more of these cloud providers developed as plugins, as these are easier for those with less familiarity with Spinnaker’s codebase.

An example of how a cloud provider plugin might look, at least for the back-end, is illustrated by this one for Hashi Nomad. Some key components:

A complete cloud provider plugin will also add custom stages (e.g. a custom Deploy stage) and Deck updates to aid with visualizing new types of cloud resources.

Integrations

Plugins also enable more integration points with other tools. This is an improvement over older means of integrating with these tools, such as the Armory Jira stage (which only enables auto-updates to Jira from Spinnaker, not the other way around) or the echo REST webhook, e.g:

Custom UI/UX

Lastly, custom visualizations of information in Spinnaker are an ideal application for plugins. Think SDLC audit trails, deployment graphs, interactive dashboards, etc. The community has not yet publicly shared examples of these, but this is a popular customization theme.

Where do these plugins end up?

The community puts example plugins on GitHub. Soon there will be public project(s) hosting plugins meant for production use, such as the observability plugin. Teams can host their own plugin repositories and make them public or private.

How does this impact the Spinnaker project?

The main motivation for this plugin framework, as mentioned earlier, was to move the project towards a lean core model. Alongside this lean core there’ll be a rich ecosystem of extensions enabling a diverse range of features. This makes it easier for contributors to add new Spinnaker services. This does NOT mean Spinnaker will feel less full-featured “out-of-the-box”; plugins add only a few more steps to your deployment, which we cover below.

How do I get started? I want to try using a plugin.

Take a look at the Plugin User Guide This video tutorial may help, too. Join Gardening Days July 16-23 for expert help (plus prizes and recognition) with your Spinnaker plugin and extension projects.

And how do I create a plugin?

Check out the Developer How To section on the Spinnaker docs site.

For development of a plugin once you have a dev environment ready, take a look at the Plugin Creators Guide.

If you have any questions or feedback, get in touch with us on the #plugins channel, we’re more than happy to talk with you!

Recently Published Posts

Introducing Pipelines-as-Code Plugin for Open Source Spinnaker

Jul 21, 2023

Easily Scale and Automate with Version Control in Git Developers choose best-of-breed version control systems like GitHub for a reason: they need the ability to collaborate and improve code together.  But a broken Spinnaker deployment pipeline can often be the last thing standing in the way of getting your application to market.  Until now. Armory’s […]

Read more

What is FedRAMP and Why It Matters

Jun 8, 2023

What’s FedRAMP? Federal Risk and Authorization Management Program (FedRAMP) is a government-wide program that provides a standardized approach to security assessment, authorization, and continuous monitoring for cloud products and services. FedRAMP is important since it’s the gold standard for assessing cloud service providers (CSP) within the government. Under this program, authorized FedRAMP cloud service providers […]

Read more

New Spinnaker Operator Updates Now available for the Spinnaker Community

Mar 15, 2023

Stay up-to-date with the latest Kubernetes release with Spinnaker. The Armory crew has worked diligently the past several weeks to release a new stable version of OSS Operator (1.3.0). This is the first release in just over 18 months and is now available for the open source community.  What Changed? The Spinnaker Operator is the […]

Read more