The two most important concepts to understand in kontinue are sources
, and workflows
.
*unit* -------------------------- *build* ---------------------- *deploy* ------------- *integration*
[src-code, golang-image] [src-code, builder-base-image] [src-code, redis-image] [src-code]
A source is anything that PRODUCES versions. This is often a way of injecting external data into your system.
apiVersion: experimental.kontinue.io/v1
kind: GitSource
metadata:
name: repo
spec:
url: https://gitlab.eng.vmware.com/kontinue/example-app
provider: gitlab
secretRef: {name: git-token}
branchFilter: 'feature/*' #<============ all feature branches
---
apiVersion: experimental.kontinue.io/v1
kind: RegistrySource
metadata:
name: golang-1-15
spec:
repository: golang
tagList: ['1.15'] #<============ only '1.15' tag
---
apiVersion: experimental.kontinue.io/v1
kind: RegistrySource
metadata:
name: golang-1-14
spec:
repository: golang
tagList: ['1.14'] #<============ only '1.14' tag
---
apiVersion: experimental.kontinue.io/v1
kind: RegistrySource
metadata:
name: redis
spec:
repository: gcr.io/sys-2b0109it/demo/bitnami/redis
tagList: ['latest']
---
apiVersion: experimental.kontinue.io/v1
kind: RegistrySource
metadata:
name: builder-base
spec:
repository: gcr.io/paketo-buildpacks/builder
tagList: ['base']
A workflow is something that CONSUMES versions from 1 or more sources.
The configuration of a workflow is split into two parts: Workflow
and WorkflowTemplate
.
The WorkflowTemplate
defines a sequence of steps
to run.
Within each step
you can:
- submit resources to kubernetes
- monitor their status
- expose results as
outputs
apiVersion: experimental.kontinue.io/v1
kind: WorkflowTemplate
metadata:
name: app
spec:
sources:
- repo
- golang
- builder
- redis
steps:
- name: unit #<========== UNIT
sources: [repo, golang]
templates:
- template:
apiVersion: tekton.dev/v1beta1
kind: TaskRun #<========== using tekton
metadata:
generateName: 'app-unit-'
spec:
serviceAccountName: example-app-sa
taskRef:
name: unit-tests
params: #<========== version info
- name: git-url
value: '{{ .Sources.repo.url }}'
- name: git-revision
value: '{{ .Sources.repo.revision }}'
- name: image
value: '{{ .Sources.golang.url }}@{{ .Sources.golang.revision }}'
- name: build #<========== BUILD
sources: [repo, builder]
outputs:
- name: latestImage #<========== outputs
valueFrom:
template:
jsonPath: '{.status.latestImage}'
templates:
- template:
kind: Build #<========== using kpack
apiVersion: kpack.io/v1alpha1
metadata:
generateName: 'app-'
spec:
tags: [ 'kontinue/example-app' ]
serviceAccount: example-app-sa
builder:
image: '{{ .Sources.builder.url }}@{{ .Sources.builder.revision }}'
source:
git:
url: '{{ .Sources.repo.url }}'
revision: '{{ .Sources.repo.revision }}'
- name: deploy #<========== DEPLOY
sources: [repo, redis]
inputs: #<========= inputs
- name: latestImage
valueFrom:
output:
step: build
name: latestImage
outputs:
- name: serviceName
valueFrom:
template:
jsonPath: '{.metadata.name}'
templates:
- lifecycle: DeleteAfterRun #<========= clean up
template:
apiVersion: kappctrl.k14s.io/v1alpha1
kind: App #<========= using kapp
metadata:
generateName: 'app-'
spec:
serviceAccountName: apps-deployer
fetch:
- git:
url: '{{ .Sources.repo.url }}'
ref: '{{ .Sources.repo.revision }}'
secretRef: {name: git-credentials}
template:
- ytt:
values:
app: '{{ .Inputs.latestImage }}'
redis: '{ .Sources.redis.revision }}'
paths:
- config/manifests #<========== manifests
deploy:
- kapp: {}
- name: integration #<========== INTEGRATION
sources: [repo]
inputs:
- name: serviceName
valueFrom:
output:
step: deploy
name: serviceName
templates:
- template:
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
generateName: 'app-integr-'
spec:
serviceAccountName: example-app-sa
taskRef:
name: integration-tests
params:
- name: addr
value: '{{ .Inputs.serviceName }}:8080'
- name: git-url
value: '{{ .Sources.repo.url }}'
- name: git-revision
value: '{{ .Sources.repo.revision }}'
apiVersion: experimental.kontinue.io/v1
kind: CompletionRule
metadata:
name: kpack-build
spec:
resource:
kind: Build
apiVersion: kpack.io/v1alpha1
failed:
- condition:
type: "Succeeded"
status: "False"
succeeded:
- condition:
type: "Succeeded"
status: "True"
The Workflow
brings together the Sources
and WorkflowTemplate
, and defines how it should execute.
apiVersion: experimental.kontinue.io/v1
kind: Workflow
metadata:
name: app
spec:
workflowTemplateRef:
name: app #<============== template
sources: #<============== sources impact execution
- name: repo
sourceRefs: #<============== targets multiple branches (feature/*)
- {name: repo, kind: GitSource}
# run-1 *unit* --- *build* --- *deploy* --- *integration*
#
# run-2 *unit* --- *build* --- *deploy* --- *integration*
- name: golang
sourceRefs: #<============== multiple source refs
- {name: golang-1-14, kind: RegistrySource}
- {name: golang-1-15, kind: RegistrySource}
# run-1 *unit* -+- *build* --- *deploy* --- *integration*
# |
# *unit* -+
- name: builder
sourceRefs:
- {name: builder-base, kind: RegistrySource}
- name: redis
sourceRefs:
- {name: redis, kind: RegistrySource}
run-1 *unit (1.14, digest-1)* -----+----- *build* --------- *deploy* --------- *integration*
(feature/a, sha-1) |
*unit (1.15, digest-2)* -----+
run-2 *unit (1.14, digest-1)* -----+----- *build* --------- *deploy* --------- *integration*
(feature/b, sha-2) |
*unit (1.15, digest-2)* -----+
run-3 *unit (1.14, digest-1)* -----+----- *build* --------- *deploy* --------- *integration*
(feature/c, sha-2) |
*unit (1.15, digest-2)* -----+
...later...
run-4 *unit (1.14, digest-1)* -----+----- *build* --------- *deploy* --------- *integration*
(feature/a, sha-11) |
*unit (1.15, digest-2)* -----+