I want to have a Kustomize manifest where value for some attribute comes from entire contents of some file or URI.
How can I do this?
I want to have a Kustomize manifest where value for some attribute comes from entire contents of some file or URI.
How can I do this?
Usually with kustomize what you are going to use is an overlay and patches (which is one or multiple files) that are kind of merged into your base file. A Patch overrides an attribute. With those two features you predefine some probable manifest-compositions and just combine them right before you apply them to your cluster.
You can add or edit/set some specific attributes with patches or with kustomize subcommands like so:
kustomize edit set image your-registry.com:$image_tag
# just to identify version in metadata sections for service/deployment/pods - not just via image tag
kustomize edit add annotation appVersion:$image_tag
kustomize build . | kubectl -n ${your_ns} apply -f -
But if you want to have a single manifest file and manipulate the same attributes over and over again (on the fly), you should consider using helm's templating mechanism. This is also an option if kustomize does not allow you to edit that single specific attribute you want to alter.
You just need a values.yaml file (containing key/value pairs) and a template.yaml file. You can pre-set some attributes in the values.yaml - on demand you can override them per CLI. The tool will generate you a k8s manifest with those values backed in.
template file:
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: {{ .Values.appSettings.appName }}
namespace: {{ .Values.appSettings.namespace }}
labels:
name: {{ .Values.appSettings.appName }}
spec:
replicas: 1
template:
metadata:
labels:
name: {{ .Values.appSettings.appName }}
spec:
containers:
- name: {{ .Values.appSettings.appName }}
image: "{{ .Values.appSettings.image }}"
ports:
- containerPort: 8080
[...]
---
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.appSettings.appName }}-svc
namespace: {{ .Values.appSettings.namespace }}
labels:
name: {{ .Values.appSettings.appName }}
spec:
ports:
- port: 8080
targetPort: 8080
selector:
name: {{ .Values.appSettings.appName }}
Values file:
appSettings:
appName: your-fancy-app
appDomain: please_override_via_cli
namespace: please_override_via_cli
CLI:
helm template
--set appSettings.image=your-registry.com/service:$(cat versionTag.txt)
--set appSettings.namespace=your-ns
--set appSettings.appDomain=your-domain.com
./ -f ./values.yaml | kubectl apply -f -
You can include a remote kustomization.yml file but not a single value. You could build your own transformer plugin if you really wanted to, but it's not really in the spirit of Kustomize.
The typical pattern to import complete files with Kustomize is to use ConfigMaps or Secrets
With configMapGenerator and secretGenerator you can import config files or environment variables, that you can then use in a Pod or Deployment by mounting them as volumes (for files) or using envFrom
for environment variables.
For example:
configMapGenerator:
- name: my-env-cm
namespace: my-namespace
envs:
- params.env
- name: my-config-file
behavior: replace
files:
- config.json=config.json # <file name>=<local file to use>
- other_config.json=other_config_file.json
where params.env
is:
FOO=bar
BAZ=qux
The Deployment then looks like:
volumes:
- name: config-file
configMap:
name: my-config-file
containers:
- name: myapp
env:
- name: FOO_FROM_CM
valueFrom:
configMapKeyRef:
name: my-env-cm
key: FOO
# or directly import all env variables
envFrom:
- configMapRef:
name: my-env-cm
# for files:
volumeMounts:
- mountPath: /etc/config
name: config-file
# config.json and other_config.json will be mounted under /etc/config/
I've even seen people mounting scripts in ConfigMaps to pass as a parameter to their pod (which admittedly can raise security concerns)