kyaml-a2c is a command line utility and a go library which converts Kubernetes manifest annotations to field comments.
Flux's Image Automation Controller uses comments in Kubernetes manifests as a way to configure the fields that will be patched as new images are released as part of a GitOps workflow.
Here's an example of a HelmRelease
resource where spec.values.image.repository
and spec.values.image.tag
will be
updated by the image automation controller when a new image that matches the podinfo
ImagePolicy is pushed to GitHub
Container Registry.
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: podinfo
namespace: default
spec:
values:
image:
repository: ghcr.io/stefanprodan/podinfo # {"$imagepolicy": "flux-system:podinfo:name"}
tag: 5.0.0 # {"$imagepolicy": "flux-system:podinfo:tag"}
The $imagepolicy
markers in the field comments are what determine which fields will be patched by Flux when a new
image is released.
This works well if the manifests are written manually, but it doesn't work with most manifest generation tools because
they can't generate comments. It's common nowadays manifests to be generated from jsonnet
templates, but it's
impossible to produce comments in yaml files from those templates.
kyaml-a2c
can be used as part of the manifest generation pipeline to convert standard Kubernetes annotations to
field comments.
The manifest above can be generated by running kyaml-a2c
with the following input:
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
annotations:
comment.kyaml.io/set.spec.values.image.repository: '{"$imagepolicy": "flux-system:podinfo:name"}'
comment.kyaml.io/set.spec.values.image.tag: '{"$imagepolicy": "flux-system:podinfo:tag"}'
name: podinfo
namespace: default
spec:
values:
image:
repository: ghcr.io/stefanprodan/podinfo
tag: 5.0.0
The file will be patched in-place and the value of the annotations will be set as field comments of
spec.values.image.repository
and spec.values.image.tag
.
The binary can be downloaded from the releases or installed with go
go install github.com/toddkazakov/kyaml-a2c@latest
After you install the tool, you can run it by providing the path to the manifests
$GOPATH/bin/kyaml-a2c --path=./examples
cat ./examples/manifests.yaml
Configuration Options:
--path
REQUIRED - takes a path to a file or a directory containing the kubernetes manifests--prefix
- the annotation key prefix. Defaults tocomment.kyaml.io/set.
Kubernetes resource annotations are key/value pairs. kyaml-a2c
looks for annotations keys which start with the
configured prefix (defaults to comment.kyaml.io/set.
) followed by the field path in the yaml file. The path segement
separator is .
. A comment with the annotation value will be added to the referenced field.
kyaml-a2c
will only set comments to scalar fields and will ignore field that don't exist.
Input:
annotations:
comment.kyaml.io/set.spec.values.image.tag: '{"$imagepolicy": "flux-system:podinfo:tag"}'
Output:
...
spec:
values:
image:
repository: ghcr.io/stefanprodan/podinfo # '{"$imagepolicy": "flux-system:podinfo:tag"}
...
Input:
annotations:
comment.kyaml.io/set.spec.containers.[name=nginx].image: '{"$imagepolicy": "flux-system:nginx:image"}'
comment.kyaml.io/set.spec.containers.[1].image: '{"$imagepolicy": "flux-system:debian:image"}'
Output:
...
spec:
volumes:
- name: html
emptyDir: {}
containers:
- name: 1st
image: nginx # {"$imagepolicy": "flux-system:nginx:image"}
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
- name: 2nd
image: debian # {"$imagepolicy": "flux-system:debian:image"}
volumeMounts:
- name: html
mountPath: /html
command: ["/bin/sh", "-c"]
args:
- while true; do
date >> /html/index.html;
sleep 1;
done
...