SDD 0017 - Maintenance with Renovate

Author

Simon Rüegg

Owner

Simon Rüegg

Reviewers (SIG)

Date

2019-11-05

Status

implemented

Summary

This is the concept how we use Renovate to do maintenance on Git repos. This includes dependencies (Helm, docker) of Commodore components.

See projectsyn/commodore-renovate on GitHub for the implementation of this SDD.

Motivation

Whenever a dependency is tracked in a project, it needs to be maintained. This includes programming language libraries, Docker images, Helm charts and many other formats. Doing this manually is a tedious and error prone process which is why we need something to automate this as far as possible. Renovate is a tool with the sole purpose to solve this issue and already supports many such dependency types.

Goals

We extend Renovate by the necessary feature to support us in doing maintenance on Git repos.

Non-Goals

This should only cover maintenance of dependencies tracked in Git repos, not a general maintenance solution. Neither should it cover the managing of the created PRs ("PR Dashboard").

Design Proposal

Renovate requires two components to be implemented to support a specific dependency type: The datasource and a manager. A datasource is in charge of discovery for new versions of dependencies. It can be reused by multiple managers (for example the docker datasource is used by both the Dockerfile and Kubernetes manager). A manager implements the dependency or language specific format in which dependencies are tracked. For example a package.json in Node projects or a go.mod file for Golang projects. At the very minimum a manager must implement a method to extract the dependencies from such a file and another method to update the dependency in the same file.

Commodore Components

These components are the building blocks for all our infrastructure. It’s therefore crucial to keep them up to date and well maintained. Commodore components can have different dependencies which need to be tracked and updated.

Helm Charts

Commodore components can use Helm charts as dependencies which will get rendered in the commodore compile process. These Helm charts come from https://v3.helm.sh/docs/topics/registries/[Helm registries] and are tracked with https://semver.org/[semver] version numbers. Renovate already supports Helm charts as a data source to track various repositories for new Helm chart versions. To implement a manager for commodore-helm we decided on a standard format how Commodore components should reference Helm charts:

parameters:
  crossplane:
    namespace: syn-crossplane
    charts:
      crossplane: 0.4.0
      cert-manager: 0.11.0
...

  kapitan:
    dependencies:
    - type: https
      source: https://charts.crossplane.io/alpha/crossplane-${crossplane:charts:crossplane}.tgz
      unpack: True
      output_path: dependencies/crossplane/helmcharts
    - type: https
      source: https://charts.jetstack.io/cert-manager-${crossplane:charts:cert-manager}.tgz
      unpack: True
      output_path: dependencies/crossplane/helmcharts

Each class YAML file of a Commodore component can specify Helm charts in a charts dictionary. Keys in this dict are the chart name and the values are the version numbers. In the kapitan.dependencies section each Helm chart needs to be specified as an appropriate dependency. The Helm charts tgz file is referenced as an HTTPS link and unpack: true needs to be specified. Renovate can then match the chart versions specified in the charts dict with the according dependency and is able to track and update them.

Docker Images

Referenced Docker images in components can also be maintained by Renovate:

parameters:
  crossplane:
    namespace: syn-crossplane
    images:
      aws_stack:
        image: docker.io/crossplane/stack-aws
        tag: v0.2.0
      cloudscale_stack:
        image: docker.io/vshn/stack-cloudscale
        tag: v0.0.1

The images dictionary in a class file specifies the docker images for this component. Each image contains a image property which specifies the full image path (including the registry) and a tag property which specifies the image tag. These images can then be used by the component via variables: "`${crossplane:images:cloudscale_stack:image}:${crossplane:images:cloudscale_stack:tag}" `or "`inv.parameters.crossplane.images.cloudscale_stack.image" `in Jsonnet.

Implementation Details/Notes/Constraints [optional]

Risks and Mitigations [optional]

Drawbacks [optional]