Skip to content

Jsonnet library for managing Spinnaker Applications, Pipelines and Projects

License

Notifications You must be signed in to change notification settings

karlskewes/spin-libsonnet

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

spin-libsonnet - Spinnaker Jsonnet

Spinnaker application, pipeline and projects as code, inspired by kube-libsonnet.

NOTE: this is a different take to the upstream library: spinnaker/sponnet

Getting started

Install dependencies:

go install github.com/google/go-jsonnet/cmd/jsonnet@latest
go install github.com/google/go-jsonnet/cmd/jsonnetfmt@latest
go install github.com/google/go-jsonnet/cmd/jsonnet-lint@latest
go install github.com/spinnaker/spin@latest

Create working directory:

mkdir -p tutorial
cd tutorial/

Create application:

cat <<EOF > myapp.jsonnet
local spin = import '../spin.libsonnet';

spin.application('myapp', '[email protected]')
EOF

# render jsonnet to json
jsonnet myapp.jsonnet > myapp.json

Optionally save application to Spinnaker:

spin application save --application-name myapp --file myapp.json

Create pipeline with a Wait stage:

cat <<EOF > mypipeline.jsonnet
local spin = import '../spin.libsonnet';

spin.pipeline('mypipeline', 'myapp') + {
  stages+: [
    spin.wait(),
  ],
}
EOF

# render jsonnet to json
jsonnet mypipeline.jsonnet > mypipeline.json

Optionally save pipeline to Spinnaker:

spin pipeline save --file mypipeline.json

Contributing

See CONTRIBUTING.md.

Alternatives

There are other Spinnaker pipeline solutions available:

Why not sponnet

Initially we assisted with the sponnet project and used it to generate all applications and pipelines. Each pipeline looked something like the example pipeline in the sponnet repository.

This client-side pipeline templating was a good improvement from our previous roer pipeline templating but presented challenges.

For our platform team, making changes to all pipeline files was tedious. This was a common occurrence as we added new target accounts and other pipeline functionality.

For our product teams, changing an application name and updating artifact names was awkward. We declared these variables at the top of the file, but the entire pipeline complexity was exposed. This was at odds with our desire to scale our platform team sublinearly and enable product teams to self service.

We decided to approach the problem from first principles and looked around for inspiration with the following requirements:

  • client-side templating that enables a git workflow
  • supports a simple DSL for product teams with ability to extend
  • uses jsonnet composition (myObject+: { newKey: someValue }) to enable adhoc extension or replacement anywhere in json object (explorable compexity)
  • basic constructors of common elements

Builder Pattern vs Composition

The Sponnet library (application.libsonnet, pipeline.libsonnet) resembles the one of the largest open source jsonnet projects around; Ksonnet.

The Ksonnet library uses a object.withKey1(value),withKey2(value) builder pattern, chaining attributes together.

This has two main drawbacks:

  1. duplication of key names in function definitions: withKey1(Key1)
  2. referencing other keys within a .with...() method is hard to follow.

See the below contrast between a builder pattern and jsonnet composition.

{
  local doSomeConvention(v) = std.asciiUpper(v),

  // builder pattern
  object():: {
    key1: 'some-default-value',
    withKey1(key1):: self + { key1: key1 },
    withKey2(key2):: self + { key2: key2 },
  },

  myObject: $.object()  // plus chained values below
            .withKey1('some value')  // overwrite default
            .withKey2(doSomeConvention($.myObject.key1)) // full path required!
            { key3: 'extra value' }, // still possible to compose


  // composition pattern
  object2:: {
    key1: 'some-default-value',
  },
  myObject2: $.object2 {
    key1: 'some override value',  // overwrite default
    key2: doSomeConvention(self.key1), // use of self keyword
    key3: 'extra value',
  },

}

Builder example: https://github.com/grafana/jsonnet-libs/blob/master/oauth2-proxy/oauth2-proxy.libsonnet

Composition example: https://github.com/bitnami-labs/kube-libsonnet/blob/master/examples/wordpress/frontend.jsonnet

About

Jsonnet library for managing Spinnaker Applications, Pipelines and Projects

Resources

License

Stars

Watchers

Forks

Packages

No packages published