A Concourse resource that passes key-value pairs between jobs
1M+
Implements a resource that passes sets of key-value pairs between jobs without using any external storage with resource like Git or S3.
Pulled by a get step, key-value pairs are provided to the build plan as an
artifact directory with one file per key-value pair. The name of a file is
the “key”, and its contents is the “value”. These key-value pairs can then be
loaded as local build vars using a load_var step.
Pushed by a put step, key-value pairs are persisted in the Concourse SQL
database. For this to be possible, the trick is that they are serialized as
keys and values in version JSON objects. As such, they
are designed to hold small, textual, non-secret data.
In case you're dealing with large text, binary data or secrets, we recommend you opt for other solutions. Indeed, secrets will be best stored in a vault like CredHub, large text files in Git, and binary data in some object storage or Git with Git-LFS, the “Large File Storage” addon.
This resource is a fork of the keyval resource by
@moredhel, thanks for the work done!
.properties-based)Compared to the original keyval resource from SWCE by
@regevbr and @ezraroi,
writing key-value pairs as plain files in some resource folder is more
consistent with usual conventions in Concourse, when it comes to storing
anything in step artifacts. It is also compliant with the ConfigMap pattern
from Kubernetes.
Writing/reading files is always easier in Bash scripts than parsing some Java Properties file, because much less boilerplate code is required.
Inital v1.1.0 release has fixed many defects, that made it not
usable (non-working put steps).
That one implements Bloblang-generated contents, and only
allow creating new key-values through the params of put steps, not through
writing plain files in some artifact directory of tasksteps like we do here.
resource_types:
- name: key-value
type: registry-image
source:
repository: gstack/keyval-resource
resources:
- name: key-value
type: key-value
history_identifier: Optional.
When the “global resources” feature is enabled on your
Concourse installation, and you don't want a single resource history for all
the keyval resources defined in your Concourse installation, then set this
property to a relevant identifier, possibly unique or not. See the
“global resources” section for a detailed
discussion on use-cases and solutions.check Step (check script): Report the latest stored key-value pairsThis is a version-less resource so check behavior is no-op.
It will detect the latest store key/value pairs, if any, and won't provide any version history.
None.
get Step (in script): Fetch the latest stored key-value pairs from the Concourse SQL databaseFetches the given key & values from the stored resource version JSON (in the Concourse SQL database) and write them in their respective files where the key is the file name and the value is the file contents.
"version": { "some_key": "some_value" }
would result in:
$ cat resource/some_key
some_value
None.
put Step (out script): Store new set of key-value pairs to the Concourse SQL databaseConverts each file in the artifact directory designated by directory to a
set of key-value pairs, where file names are the keys and file contents are
the values. This set of key-value pairs is persisted in the version JSON
object, to be stored in the Concourse SQL database.
A value from a file in directory can be overridden by a matching key with
different value in the dictionary given as the overrides parameter. If you
need to store some Concourse ((vars)) value in a key-value resource, then
add it to the overrides parameter of some put step.
directory: Required. The artifact directory to be scanned for files, in
order to generate key-value pairs
overrides: Optional. A dictionary of key-value pairs that will override
any matching pair with same key found in directory.
This example make intentional ellipsis in order to focus on the main ideas behind the “keyval” resource. Seasoned Concourse practitioners can find an illustration here in one catch.
resource_types:
- name: key-value
type: registry-image
source:
repository: gstack/keyval-resource
resources:
- name: build-info
type: key-value
jobs:
- name: build
plan:
- task: build
file: tools/tasks/build/task.yml # <- must declare a 'build-info' output artifact
- put: build-info
params:
directory: build-info
- name: test-deploy
plan:
- in_parallel:
- get: build-info
passed: [ build ]
- task: test-deploy
file: tools/tasks/task.yml # <- must declare a 'build-info' input artifact
The build task writes all the key-value pairs it needs to pass along in
files inside the build-info output artifact directory.
The test-deploy job then reads the files from the build-info resource,
which produces a build-info artifact directory to be used by the
test-deploy task.
This fully-working and detailed example goes deeper in showcasing what the resource can actually do and how. Concourse beginners are recommended to read this as it details very clearly the relation between resource, artifact directories, and tasks.
resource_types:
- name: key-value
type: registry-image
source: { repository: gstack/keyval-resource }
resources:
- name: some-keyval-resource
type: key-value
- name: runner-image
type: registry-image
source: { repository: busybox }
jobs:
- name: step-1-job
plan:
- get: runner-image
- task: write-keyval-aaa-1-task
image: runner-image
config:
platform: linux
outputs: [ { name: created-keyvals-artifact } ]
run:
path: sh
args:
- -exc
- |
echo "1" > created-keyvals-artifact/aaa
- put: some-keyval-resource
params:
directory: created-keyvals-artifact
- name: step-2-job
plan:
- in_parallel:
- get: keyvals-artifact # here artifact directory is
resource: some-keyval-resource # different from resource name
trigger: true
passed: [ step-1-job ]
- get: runner-image
- task: read-aaa-keyval-task
image: runner-image
config:
platform: linux
inputs: [ { name: keyvals-artifact } ]
run:
path: sh
args:
- -exc
- |
cat keyvals-artifact/aaa # -> 1
- task: write-bbb-keyval-task
image: runner-image
config:
platform: linux
inputs: [ { name: keyvals-artifact } ]
outputs: [ { name: keyvals-artifact } ]
run:
path: sh
args:
- -exc
- |
echo "2" > build-info/bbb
- put: some-keyval-resource
params:
directory: keyvals-artifact
overrides:
aaa: "11"
ccc: "3"
- name: step-3-job
plan:
- in_parallel:
- get: some-keyval-resource # artifact dir will have same name
trigger: true
passed: [ step-2-job ]
- get: runner-image
- task: read-aaa-bbb-ccc-keyvals-task
image: runner-image
config:
platform: linux
inputs: [ { name: some-keyval-resource } ]
run:
path: sh
args:
- -exc
- |
cat build-info/aaa # -> 11
cat build-info/bbb # -> 2
cat build-info/ccc # -> 3
The write-keyval-aaa-1-task creates a file named aaa with content 1 to
the created-keyvals-artifact output artifact directory. The
some-keyval-resource resource will read files in the
created-keyvals-artifact directory and store a key-value pair {"aaa": "1"}.
The read-aaa-keyval-task reads the value from the aaa file in
keyvals-artifact input artifact directory provided from the
some-keyval-resource resource. This outputs 1.
The write-bbb-keyval-task creates a file named bbb with content 2 to
keyvals-artifact output artifact directory. Because this directory is same
as keyvals-artifact input artifact directory which already contains aaa.
The some-keyval-resource resource will read all files in the
keyvals-artifact directory and store key-value pairs {"aaa": "1"} and {"bbb": "2"}.
The put: some-keyval-resource in step-2-job provides the overrides
option, which changes the original key-value pair {"aaa": "1"} to {"aaa": "11"} and add a new pair {"ccc": "3"}.
The read-aaa-bbb-ccc-keyvals-task reads values from files in the
some-keyval-resource input artifact directory, as provided by the
some-keyval-resource resource.
When the “global resources” feature is enabled, all resources
with same resource.type and resource.source configuration will share the
same version history. If you leave the resource.source configuration blank
in all your keyval resources, then they will all be considered the exact
same resource by Concourse, sharing the exact same history.
For most keyval resource-related use-case though, this is not releavant and thus requires proper scoping.
In many scearios, the key-value resources is used to transmit
pipeline-specific data between jobs of the same pipeline. In such case,
sharing resource history is most probably irrelevant. In order to avoid this,
you can set the history_identifier to some value that will be unique in your
Concourse installation.
For best portability of your pipeline across different Concourse
installations, we recommend that you use a UUID that can be generated with the
uuidgen command-line tool like this:
$ uuidgen | tr [:upper:] [:lower:]
fc4cb2ba-d0d4-44e2-8589-8fa89a8271fd
Then use it in the resource configuration, so that the resource history is scoped privately:
resources:
- name: key-value
type: key-value
source:
history_identifier: fc4cb2ba-d0d4-44e2-8589-8fa89a8271fd
In some scenarios though, it may be interesting to share the resources history
between different pipelines. Then you can leverage key-value resources that
share the same history_identifier value.
As a result, as soon as a new version is pushed on the shared key-value resources, all other pipelines will see it.
This is interesting in case some pipeline has to trigger other pipelines. A
usual solution is to use a “dummy” semver resource, backed by Git or some
object storage.
Using the keyval resource can bring an elegant alternative. A limitation is
that this resource basically has no version history. At every point in time,
only the last vesion exisits for the resource. This is not an issue for this
use-case, though. Indeed with a “dummy” semver resource, experience shows
that nobody actually pays attention to the version history anyway.
With the keyval resource, the triggering version only need to specify the date and relevant data showing the reason why the pipeline has been triggered. These will appear and properly stay in job build logs, for later inspection.
SWCE/keyval-resourceKey-value pairs are no more written as Java .properties file, but rather one
file per key-value pair. The name of a file is a “key”, and its contents is
the related “value”.
The required file paramerter for put steps is replaced by directory.
moredhel/keyval-resourceThe required directory paramerter has been added to put steps.
The file parameter of put steps is renamed overrides.
Copyright © 2021-present, Benjamin Gandon, Gstack
Like Concourse, the key-value resource is released under the terms of the Apache 2.0 license.
Content type
Image
Digest
sha256:d4f000a52…
Size
9.6 MB
Last updated
about 1 year ago
Requires Docker Desktop 4.37.1 or later.