Skip to content

GitLab CI template for Cloud Native Buildpacks

This project implements a GitLab CI/CD template to transform your application source code into images that can run on any cloud with Cloud Native Buildpacks.

Usage

This template can be used both as a CI/CD component or using the legacy include:project syntax.

Use as a CI/CD component

Add the following to your gitlab-ci.yml:

include:
  # 1: include the component
  - component: gitlab.com/to-be-continuous/cnb/gitlab-ci-cnb@2.4.2
    # 2: set/override component inputs
    inputs:
      builder-image: "registry.hub.docker.com/heroku/buildpacks:20" # ⚠ this is only an example

Use as a CI/CD template (legacy)

Add the following to your gitlab-ci.yml:

include:
  # 1: include the template
  - project: 'to-be-continuous/cnb'
    ref: '2.4.2'
    file: '/templates/gitlab-ci-cnb.yml'

variables:
  # 2: set/override template variables
  CNB_BUILDER_IMAGE: "registry.hub.docker.com/heroku/buildpacks:20" # ⚠ this is only an example

Understanding the CNB template

Global configuration

The CNB template uses some global configuration used throughout all jobs.

Input / Variable Description Default value
builder-image / CNB_BUILDER_IMAGE The CNB builder image used to build your application image
depending on your needs, choose the most appropriate one
registry.hub.docker.com/paketobuildpacks/builder:base
platform-api / CNB_PLATFORM_API The CNB platform API version 0.9

Available Builders

Depending on your needs and preferences, you are free to choose whichever CNB compliant builder (simply override the CNB_BUILDER_IMAGE variable):

Input / Variable Builder Image Description
Google gcr.io/buildpacks/builder:v1 Ubuntu 18 base image with buildpacks for .NET, Go, Java, Node.js, and Python
Heroku registry.hub.docker.com/heroku/buildpacks:20 Base builder for Heroku-20 stack, based on ubuntu:20.04 base image
Paketo (base) registry.hub.docker.com/paketobuildpacks/builder:base Ubuntu bionic base image with buildpacks for Java, .NET Core, NodeJS, Go, Python, Ruby, Apache HTTPD, NGINX and Procfile
Paketo (full) registry.hub.docker.com/paketobuildpacks/builder:full Ubuntu bionic base image with buildpacks for Java, .NET Core, NodeJS, Go, Python, PHP, Ruby, Apache HTTPD, NGINX and Procfile
Paketo (tiny) registry.hub.docker.com/paketobuildpacks/builder:tiny Tiny base image (bionic build image, distroless-like run image) with buildpacks for Java, Java Native Image and Go

Images

The CNB template builds a container image that may be pushed as two distinct images, depending on a certain workflow:

  1. snapshot: the image is first built and pushed to some container registry as the snapshot image. It can be seen as the raw result of the build, but still untested and unreliable.
  2. release: once the snapshot image has been thoroughly tested (both by package-test stage jobs and/or acceptance stage jobs after being deployed to some server), then the image is pushed one more time as the release image. This second push can be seen as the promotion of the snapshot image being now tested and reliable.

In practice:

  • the snapshot image is always pushed by the template (pipeline triggered by a Git tag or commit on any branch),
  • the release image is only pushed:
    • on a pipeline triggered by a Git tag,
    • on a pipeline triggered by a Git commit on master.

The snapshot and release images are defined by the following variables:

Input / Variable Description Default value
snapshot-image / CNB_SNAPSHOT_IMAGE CNB snapshot image $CI_REGISTRY_IMAGE/snapshot:$CI_COMMIT_REF_SLUG
release-image / CNB_RELEASE_IMAGE CNB release image $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME

As you can see, the CNB template is configured by default to use the GitLab container registry. You may perfectly override this and use another container registry, but be aware of a few things:

  • the CNB_SNAPSHOT_IMAGE requires a container registry that allows tag overwrite,
  • the CNB_RELEASE_IMAGE may use a container registry that doesn't allow tag overwrite, but:
    1. you should avoid overwriting a Git tag (at it will obviously fail while trying to (re)push the image),
    2. you have to deactivate publish on main (or master) branch by setting the $CNB_PROD_PUBLISH_STRATEGY variable to none (as it would lead to the main tag being overwritten).

Registries and credentials

As seen in the previous chapter, the CNB template uses by default the GitLab registry to push snapshot and release images. Thus it makes use of credentials provided by GitLab itself to login (CI_REGISTRY_USER / CI_REGISTRY_PASSWORD).

But when using other registry(ies), you'll have also to configure appropriate credentials.

Using the same registry for snapshot and release

If you use the same registry for both snapshot and release images, you shall use the following configuration variables:

Input / Variable Description
🔒 CNB_REGISTRY_USER container registry username for image registry
🔒 CNB_REGISTRY_PASSWORD container registry password for image registry

Using different registries for snapshot and release

If you use different registries for snapshot and release images, you shall use separate configuration variables:

Input / Variable Description
🔒 CNB_REGISTRY_SNAPSHOT_USER container registry username for snapshot image registry
🔒 CNB_REGISTRY_SNAPSHOT_PASSWORD container registry password for snapshot image registry
🔒 CNB_REGISTRY_RELEASE_USER container registry username for release image registry
🔒 CNB_REGISTRY_RELEASE_PASSWORD container registry password for release image registry

Secrets management

Here are some advices about your secrets (variables marked with a 🔒):

  1. Manage them as project or group CI/CD variables:
    • masked to prevent them from being inadvertently displayed in your job logs,
    • protected if you want to secure some secrets you don't want everyone in the project to have access to (for instance production secrets).
  2. In case a secret contains characters that prevent it from being masked, simply define its value as the Base64 encoded value prefixed with @b64@: it will then be possible to mask it and the template will automatically decode it prior to using it.
  3. Don't forget to escape special characters (ex: $ -> $$).

Jobs

cnb-build job

This job builds the image and publishes it to the snapshot repository.

It is bound to the package-build stage, and uses the following variables:

It uses the following variable:

Input / Variable Description Default value
app-dir / CNB_APP_DIR Absolute root directory in final image /workspace
src-app-dir / CNB_SRC_APP_DIR Relative path to the application source code base directory in your repository .

This job produces output variables that are propagated to downstream jobs (using dotenv artifacts):

Input / Variable Description Example
cnb_image snapshot image name with tag registry.gitlab.com/acme/website/snapshot:main
cnb_image_digest snapshot image name with digest (no tag) registry.gitlab.com/acme/website/snapshot@sha256:b7914a91...
cnb_repository snapshot image bare repository (no tag nor digest) registry.gitlab.com/acme/website/snapshot
cnb_tag snapshot image tag main
cnb_digest snapshot image digest sha256:b7914a91...

They may be freely used in downstream jobs (for instance to deploy the upstream built image, whatever the branch or tag).

User-Provided variables support

User-Provided variables must be prefixed with CNB_X_

ℹ User-Provided variables are variables passed with the --env option using pack

Examples or User-Provided variables:

  • BP_PHP_WEB_DIR (supported by the Paketo PHP buildpack) must be declared as CNB_X_BP_PHP_WEB_DIR,
  • BP_KEEP_FILES (supported by the Paketo Go buildpack) must be declared as CNB_X_BP_KEEP_FILES,
  • MAVEN_SETTINGS_PATH (supported by the Heroku Maven buildpack) must be declared as CNB_X_MAVEN_SETTINGS_PATH,
  • GOOGLE_GOLDFLAGS (supported by the Google Go buildpack) must be declared as CNB_X_GOOGLE_GOLDFLAGS.

cnb-trivy job

This job performs a Vulnerability Static Analysis with Trivy on your built image.

Without any configuration Trivy will run in standalone mode.

If you want to run Trivy in client/server mode, you need to set the CNB_TRIVY_ADDR environment variable.

variables:
  CNB_TRIVY_ADDR: "https://trivy.acme.host"

It is bound to the package-test stage, and uses the following variables:

Input / Variable Description Default value
trivy-image / CNB_TRIVY_IMAGE The docker image used to scan images with Trivy registry.hub.docker.com/aquasec/trivy:latest
trivy-addr / CNB_TRIVY_ADDR The Trivy server address (for client/server mode) (none: standalone mode)
trivy-security-level-threshold / CNB_TRIVY_SECURITY_LEVEL_THRESHOLD Severities of vulnerabilities to be displayed (comma separated values: UNKNOWN, LOW, MEDIUM, HIGH, CRITICAL) UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL
trivy-disabled / CNB_TRIVY_DISABLED Set to true to disable Trivy analysis (none)
trivy-args / CNB_TRIVY_ARGS Additional trivy client arguments --ignore-unfixed --vuln-type os
trivy-db-repository / CNB_TRIVY_DB_REPOSITORY OCI repository to retrieve Trivy Database from none (use Trivy default ghcr.io/aquasecurity/trivy-db)
trivy-java-db-repository / CNB_TRIVY_JAVA_DB_REPOSITORY OCI repository to retrieve Trivy Java Database from none (use Trivy default ghcr.io/aquasecurity/trivy-java-db:1)_

In addition to a textual report in the console, this job produces the following reports, kept for one day:

Report Format Usage
reports/cnb-trivy-*.native.json native Trivy report format (json) DefectDojo integration
This report is generated only if DefectDojo template is detected
reports/cnb-trivy-*.gitlab.json Trivy report format for GitLab format GitLab integration

cnb-publish job

This job pushes (promotes) the built image as the release image using skopeo.

Input / Variable Description Default value
skopeo-image / CNB_SKOPEO_IMAGE The Docker image used to run skopeo quay.io/skopeo/stable:latest
publish-args / CNB_PUBLISH_ARGS Additional skopeo copy arguments (none)
prod-publish-strategy / CNB_PROD_PUBLISH_STRATEGY Defines the publish to production strategy. One of manual (i.e. one-click), auto or none (disabled). manual

This job produces output variables that are propagated to downstream jobs (using dotenv artifacts):

Input / Variable Description Example
cnb_image release image name with tag registry.gitlab.com/acme/website:main
cnb_image_digest release image name with digest (no tag) registry.gitlab.com/acme/website@sha256:b7914a91...
cnb_repository release image bare repository (no tag nor digest) registry.gitlab.com/acme/website
cnb_tag release image tag main
cnb_digest release image digest sha256:b7914a91...

They may be freely used in downstream jobs (for instance to deploy the upstream built image, whatever the branch or tag).