<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Kustomize – Kustomize Plugins</title>
    <link>https://kubernetes-sigs.github.io/kustomize/guides/plugins/</link>
    <description>Recent content in Kustomize Plugins on Kustomize</description>
    <generator>Hugo -- gohugo.io</generator>
    
	  <atom:link href="https://kubernetes-sigs.github.io/kustomize/guides/plugins/index.xml" rel="self" type="application/rss+xml" />
    
    
      
        
      
    
    
    <item>
      <title>Guides: Builtin Plugins</title>
      <link>https://kubernetes-sigs.github.io/kustomize/guides/plugins/builtins/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://kubernetes-sigs.github.io/kustomize/guides/plugins/builtins/</guid>
      <description>
        
        
        &lt;h1 id=&#34;builtin-plugins&#34;&gt;Builtin Plugins&lt;/h1&gt;
&lt;p&gt;A list of kustomize&amp;rsquo;s builtin plugins - both
generators and transformers.&lt;/p&gt;
&lt;p&gt;For each plugin, an example is given for&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;implicitly triggering
the plugin via a dedicated kustomization
file field (e.g. the &lt;code&gt;AnnotationsTransformer&lt;/code&gt; is
triggered by the &lt;code&gt;commonAnnotations&lt;/code&gt; field).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;explicitly triggering the plugin
via the &lt;code&gt;generators&lt;/code&gt; or &lt;code&gt;transformers&lt;/code&gt; field
(by providing a config file specifying the
plugin).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The former method is convenient but limited in
power as most of the plugins arguments must
be defaulted.  The latter method allows for
complete plugin argument specification.&lt;/p&gt;
&lt;h2 id=&#34;_annotationtransformer_&#34;&gt;&lt;em&gt;AnnotationTransformer&lt;/em&gt;&lt;/h2&gt;
&lt;h3 id=&#34;usage-via-kustomizationyaml&#34;&gt;Usage via &lt;code&gt;kustomization.yaml&lt;/code&gt;&lt;/h3&gt;
&lt;h4 id=&#34;field-name-commonannotations&#34;&gt;field name: &lt;code&gt;commonAnnotations&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Adds annotions (non-identifying metadata) to add
all resources. Like labels, these are key value
pairs.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;commonAnnotations:
  oncallPager: 800-555-1212
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;usage-via-plugin&#34;&gt;Usage via plugin&lt;/h3&gt;
&lt;h4 id=&#34;arguments&#34;&gt;Arguments&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Annotations map[string]string&lt;/p&gt;
&lt;p&gt;FieldSpecs  []&lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/fieldspec.go&#34;&gt;config.FieldSpec&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&#34;example&#34;&gt;Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: builtin
kind: AnnotationsTransformer
metadata:
  name: not-important-to-example
annotations:
  app: myApp
  greeting/morning: a string with blanks
fieldSpecs:
- path: metadata/annotations
  create: true
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;_configmapgenerator_&#34;&gt;&lt;em&gt;ConfigMapGenerator&lt;/em&gt;&lt;/h2&gt;
&lt;h3 id=&#34;usage-via-kustomizationyaml-1&#34;&gt;Usage via &lt;code&gt;kustomization.yaml&lt;/code&gt;&lt;/h3&gt;
&lt;h4 id=&#34;field-name-configmapgenerator&#34;&gt;field name: &lt;code&gt;configMapGenerator&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Each entry in this list results in the creation of
one ConfigMap resource (it&amp;rsquo;s a generator of n maps).&lt;/p&gt;
&lt;p&gt;The example below creates three ConfigMaps. One with the names and contents of
the given files, one with key/value as data, and a third which sets an
annotation and label via &lt;code&gt;options&lt;/code&gt; for that single ConfigMap.&lt;/p&gt;
&lt;p&gt;Each configMapGenerator item accepts a parameter of
&lt;code&gt;behavior: [create|replace|merge]&lt;/code&gt;.
This allows an overlay to modify or
replace an existing configMap from the parent.&lt;/p&gt;
&lt;p&gt;Also, each entry has an &lt;code&gt;options&lt;/code&gt; field, that has the
same subfields as the kustomization file&amp;rsquo;s &lt;code&gt;generatorOptions&lt;/code&gt; field.&lt;/p&gt;
&lt;p&gt;This &lt;code&gt;options&lt;/code&gt; field allows one to add labels and/or
annotations to the generated instance, or to individually
disable the name suffix hash for that instance.
Labels and annotations added here will not be overwritten
by the global options associated with the kustomization
file &lt;code&gt;generatorOptions&lt;/code&gt; field.  However, due to how
booleans behave, if the global &lt;code&gt;generatorOptions&lt;/code&gt; field
specifies &lt;code&gt;disableNameSuffixHash: true&lt;/code&gt;, this will
trump any attempt to locally override it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# These labels are added to all configmaps and secrets.
generatorOptions:
  labels:
    fruit: apple

configMapGenerator:
- name: my-java-server-props
  behavior: merge
  files:
  - application.properties
  - more.properties
- name: my-java-server-env-vars
  literals:	
  - JAVA_HOME=/opt/java/jdk
  - JAVA_TOOL_OPTIONS=-agentlib:hprof
  options:
    disableNameSuffixHash: true
    labels:
      pet: dog
- name: dashboards
  files:
  - mydashboard.json
  options:
    annotations:
      dashboard: &amp;quot;1&amp;quot;
    labels:
      app.kubernetes.io/name: &amp;quot;app1&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It is also possible to
&lt;a href=&#34;https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#define-the-key-to-use-when-creating-a-configmap-from-a-file&#34;&gt;define a key&lt;/a&gt;
to set a name different than the filename.&lt;/p&gt;
&lt;p&gt;The example below creates a ConfigMap
with the name of file as &lt;code&gt;myFileName.ini&lt;/code&gt;
while the &lt;em&gt;actual&lt;/em&gt; filename from which the
configmap is created is &lt;code&gt;whatever.ini&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;configMapGenerator:
- name: app-whatever
  files:
  - myFileName.ini=whatever.ini
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;usage-via-plugin-1&#34;&gt;Usage via plugin&lt;/h3&gt;
&lt;h4 id=&#34;arguments-1&#34;&gt;Arguments&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/configmapargs.go&#34;&gt;types.ConfigMapArgs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&#34;example-1&#34;&gt;Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: builtin
kind: ConfigMapGenerator
metadata:
  name: mymap
envs:
- devops.env
- uxteam.env
literals:
- FRUIT=apple
- VEGETABLE=carrot
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;_imagetagtransformer_&#34;&gt;&lt;em&gt;ImageTagTransformer&lt;/em&gt;&lt;/h2&gt;
&lt;h3 id=&#34;usage-via-kustomizationyaml-2&#34;&gt;Usage via &lt;code&gt;kustomization.yaml&lt;/code&gt;&lt;/h3&gt;
&lt;h4 id=&#34;field-name-images&#34;&gt;field name: &lt;code&gt;images&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Images modify the name, tags and/or digest for images
without creating patches.  E.g. Given this
kubernetes Deployment fragment:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;containers:
- name: mypostgresdb
  image: postgres:8
- name: nginxapp
  image: nginx:1.7.9
- name: myapp
  image: my-demo-app:latest
- name: alpine-app
  image: alpine:3.7
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;one can change the &lt;code&gt;image&lt;/code&gt; in the following ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;postgres:8&lt;/code&gt; to &lt;code&gt;my-registry/my-postgres:v1&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;nginx tag &lt;code&gt;1.7.9&lt;/code&gt; to &lt;code&gt;1.8.0&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;image name &lt;code&gt;my-demo-app&lt;/code&gt; to &lt;code&gt;my-app&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;alpine&amp;rsquo;s tag &lt;code&gt;3.7&lt;/code&gt; to a digest value&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;all with the following &lt;em&gt;kustomization&lt;/em&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;images:
- name: postgres
  newName: my-registry/my-postgres
  newTag: v1
- name: nginx
  newTag: 1.8.0
- name: my-demo-app
  newName: my-app
- name: alpine
  digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;usage-via-plugin-2&#34;&gt;Usage via plugin&lt;/h3&gt;
&lt;h4 id=&#34;arguments-2&#34;&gt;Arguments&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;ImageTag   &lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/image.go&#34;&gt;image.Image&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;FieldSpecs []&lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/fieldspec.go&#34;&gt;config.FieldSpec&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&#34;example-2&#34;&gt;Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: builtin
kind: ImageTagTransformer
metadata:
  name: not-important-to-example
imageTag:
  name: nginx
  newTag: v2
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;_labeltransformer_&#34;&gt;&lt;em&gt;LabelTransformer&lt;/em&gt;&lt;/h2&gt;
&lt;h3 id=&#34;usage-via-kustomizationyaml-3&#34;&gt;Usage via &lt;code&gt;kustomization.yaml&lt;/code&gt;&lt;/h3&gt;
&lt;h4 id=&#34;field-name-commonlabels&#34;&gt;field name: &lt;code&gt;commonLabels&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Adds labels to all resources and selectors&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;commonLabels:
  someName: someValue
  owner: alice
  app: bingo
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;usage-via-plugin-3&#34;&gt;Usage via plugin&lt;/h3&gt;
&lt;h4 id=&#34;arguments-3&#34;&gt;Arguments&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Labels  map[string]string&lt;/p&gt;
&lt;p&gt;FieldSpecs []&lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/fieldspec.go&#34;&gt;config.FieldSpec&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&#34;example-3&#34;&gt;Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: builtin
kind: LabelTransformer
metadata:
  name: not-important-to-example
labels:
  app: myApp
  env: production
fieldSpecs:
- path: metadata/labels
  create: true
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;_namespacetransformer_&#34;&gt;&lt;em&gt;NamespaceTransformer&lt;/em&gt;&lt;/h2&gt;
&lt;h3 id=&#34;usage-via-kustomizationyaml-4&#34;&gt;Usage via &lt;code&gt;kustomization.yaml&lt;/code&gt;&lt;/h3&gt;
&lt;h4 id=&#34;field-name-namespace&#34;&gt;field name: &lt;code&gt;namespace&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Adds namespace to all resources&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namespace: my-namespace
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;usage-via-plugin-4&#34;&gt;Usage via plugin&lt;/h3&gt;
&lt;h4 id=&#34;arguments-4&#34;&gt;Arguments&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/objectmeta.go&#34;&gt;types.ObjectMeta&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;FieldSpecs []&lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/fieldspec.go&#34;&gt;config.FieldSpec&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&#34;example-4&#34;&gt;Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: builtin
 kind: NamespaceTransformer
 metadata:
   name: not-important-to-example
   namespace: test
 fieldSpecs:
 - path: metadata/namespace
   create: true
 - path: subjects
   kind: RoleBinding
   group: rbac.authorization.k8s.io
 - path: subjects
   kind: ClusterRoleBinding
   group: rbac.authorization.k8s.io
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;_patchesjson6902_&#34;&gt;&lt;em&gt;PatchesJson6902&lt;/em&gt;&lt;/h2&gt;
&lt;h3 id=&#34;usage-via-kustomizationyaml-5&#34;&gt;Usage via &lt;code&gt;kustomization.yaml&lt;/code&gt;&lt;/h3&gt;
&lt;h4 id=&#34;field-name-patchesjson6902&#34;&gt;field name: &lt;code&gt;patchesJson6902&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Each entry in this list should resolve to
a kubernetes object and a JSON patch that will be applied
to the object.
The JSON patch is documented at &lt;a href=&#34;https://tools.ietf.org/html/rfc6902&#34;&gt;https://tools.ietf.org/html/rfc6902&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;target field points to a kubernetes object within the same kustomization
by the object&amp;rsquo;s group, version, kind, name and namespace.
path field is a relative file path of a JSON patch file.
The content in this patch file can be either in JSON format as&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; [
   {&amp;quot;op&amp;quot;: &amp;quot;add&amp;quot;, &amp;quot;path&amp;quot;: &amp;quot;/some/new/path&amp;quot;, &amp;quot;value&amp;quot;: &amp;quot;value&amp;quot;},
   {&amp;quot;op&amp;quot;: &amp;quot;replace&amp;quot;, &amp;quot;path&amp;quot;: &amp;quot;/some/existing/path&amp;quot;, &amp;quot;value&amp;quot;: &amp;quot;new value&amp;quot;}
 ]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;or in YAML format as&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;- op: add
  path: /some/new/path
  value: value
- op: replace
  path: /some/existing/path
  value: new value
&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;patchesJson6902:
- target:
    version: v1
    kind: Deployment
    name: my-deployment
  path: add_init_container.yaml
- target:
    version: v1
    kind: Service
    name: my-service
  path: add_service_annotation.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The patch content can be an inline string as well:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;patchesJson6902:
- target:
    version: v1
    kind: Deployment
    name: my-deployment
  patch: |-
    - op: add
      path: /some/new/path
      value: value
    - op: replace
      path: /some/existing/path
      value: &amp;quot;new value&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;usage-via-plugin-5&#34;&gt;Usage via plugin&lt;/h3&gt;
&lt;h4 id=&#34;arguments-5&#34;&gt;Arguments&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Target &lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/patchtarget.go&#34;&gt;types.PatchTarget&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Path   string&lt;/p&gt;
&lt;p&gt;JsonOp string&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&#34;example-5&#34;&gt;Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: builtin
kind: PatchJson6902Transformer
metadata:
  name: not-important-to-example
target:
  group: apps
  version: v1
  kind: Deployment
  name: my-deploy
path: jsonpatch.json
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;_patchesstrategicmerge_&#34;&gt;&lt;em&gt;PatchesStrategicMerge&lt;/em&gt;&lt;/h2&gt;
&lt;h3 id=&#34;usage-via-kustomizationyaml-6&#34;&gt;Usage via &lt;code&gt;kustomization.yaml&lt;/code&gt;&lt;/h3&gt;
&lt;h4 id=&#34;field-name-patchesstrategicmerge&#34;&gt;field name: &lt;code&gt;patchesStrategicMerge&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Each entry in this list should be either a relative
file path or an inline content
resolving to a partial or complete resource
definition.&lt;/p&gt;
&lt;p&gt;The names in these (possibly partial) resource
files must match names already loaded via the
&lt;code&gt;resources&lt;/code&gt; field.  These entries are used to
&lt;em&gt;patch&lt;/em&gt; (modify) the known resources.&lt;/p&gt;
&lt;p&gt;Small patches that do one thing are best, e.g. modify
a memory request/limit, change an env var in a
ConfigMap, etc.  Small patches are easy to review and
easy to mix together in overlays.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;patchesStrategicMerge:
- service_port_8888.yaml
- deployment_increase_replicas.yaml
- deployment_increase_memory.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The patch content can be a inline string as well.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;patchesStrategicMerge:
- |-
  apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: nginx
  spec:
    template:
      spec:
        containers:
          - name: nginx
            image: nignx:latest
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that kustomize does not support more than one patch
for the same object that contain a &lt;em&gt;delete&lt;/em&gt; directive. To remove
several fields / slice elements from an object create a single
patch that performs all the needed deletions.&lt;/p&gt;
&lt;h3 id=&#34;usage-via-plugin-6&#34;&gt;Usage via plugin&lt;/h3&gt;
&lt;h4 id=&#34;arguments-6&#34;&gt;Arguments&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Paths []&lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/patchstrategicmerge.go&#34;&gt;types.PatchStrategicMerge&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Patches string&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&#34;example-6&#34;&gt;Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: builtin
kind: PatchStrategicMergeTransformer
metadata:
  name: not-important-to-example
paths:
- patch.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;_patchtransformer_&#34;&gt;&lt;em&gt;PatchTransformer&lt;/em&gt;&lt;/h2&gt;
&lt;h3 id=&#34;usage-via-kustomizationyaml-7&#34;&gt;Usage via &lt;code&gt;kustomization.yaml&lt;/code&gt;&lt;/h3&gt;
&lt;h4 id=&#34;field-name-patches&#34;&gt;field name: &lt;code&gt;patches&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Each entry in this list should resolve to an Patch
object, which includes a patch and a target selector.
The patch can be either a strategic merge patch or a
JSON patch. it can be either a patch file or an inline
string. The target selects
resources by group, version, kind, name, namespace,
labelSelector and annotationSelector. A resource
which matches all the specified fields is selected
to apply the patch.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;patches:
- path: patch.yaml
  target:
    group: apps
    version: v1
    kind: Deployment
    name: deploy.*
    labelSelector: &amp;quot;env=dev&amp;quot;
    annotationSelector: &amp;quot;zone=west&amp;quot;
- patch: |-
    - op: replace
      path: /some/existing/path
      value: new value
  target:
    kind: MyKind
    labelSelector: &amp;quot;env=dev&amp;quot;        
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;namespace&lt;/code&gt; fields of the patch target selector are
automatically anchored regular expressions. This means that the value &lt;code&gt;myapp&lt;/code&gt;
is equivalent to &lt;code&gt;^myapp$&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;usage-via-plugin-7&#34;&gt;Usage via plugin&lt;/h3&gt;
&lt;h4 id=&#34;arguments-7&#34;&gt;Arguments&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Path string&lt;/p&gt;
&lt;p&gt;Patch string&lt;/p&gt;
&lt;p&gt;Target *&lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/selector.go&#34;&gt;types.Selector&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&#34;example-7&#34;&gt;Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: builtin
kind: PatchTransformer
metadata:
  name: not-important-to-example
patch: &#39;[{&amp;quot;op&amp;quot;: &amp;quot;replace&amp;quot;, &amp;quot;path&amp;quot;: &amp;quot;/spec/template/spec/containers/0/image&amp;quot;, &amp;quot;value&amp;quot;: &amp;quot;nginx:latest&amp;quot;}]&#39;
target:
  name: .*Deploy
  kind: Deployment
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;_prefixsuffixtransformer_&#34;&gt;&lt;em&gt;PrefixSuffixTransformer&lt;/em&gt;&lt;/h2&gt;
&lt;h3 id=&#34;usage-via-kustomizationyaml-8&#34;&gt;Usage via &lt;code&gt;kustomization.yaml&lt;/code&gt;&lt;/h3&gt;
&lt;h4 id=&#34;field-names-nameprefix-namesuffix&#34;&gt;field names: &lt;code&gt;namePrefix&lt;/code&gt;, &lt;code&gt;nameSuffix&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Prepends or postfixes the value to the names
of all resources.&lt;/p&gt;
&lt;p&gt;E.g. a deployment named &lt;code&gt;wordpress&lt;/code&gt; could
become &lt;code&gt;alices-wordpress&lt;/code&gt; or  &lt;code&gt;wordpress-v2&lt;/code&gt;
or &lt;code&gt;alices-wordpress-v2&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;namePrefix: alices-
nameSuffix: -v2
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The suffix is appended before the content hash if
the resource type is ConfigMap or Secret.&lt;/p&gt;
&lt;h3 id=&#34;usage-via-plugin-8&#34;&gt;Usage via plugin&lt;/h3&gt;
&lt;h4 id=&#34;arguments-8&#34;&gt;Arguments&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Prefix     string&lt;/p&gt;
&lt;p&gt;Suffix     string&lt;/p&gt;
&lt;p&gt;FieldSpecs []&lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/fieldspec.go&#34;&gt;config.FieldSpec&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&#34;example-8&#34;&gt;Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: builtin
kind: PrefixSuffixTransformer
metadata:
  name: not-important-to-example
prefix: baked-
suffix: -pie
fieldSpecs:
  - path: metadata/name
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;_replicacounttransformer_&#34;&gt;&lt;em&gt;ReplicaCountTransformer&lt;/em&gt;&lt;/h2&gt;
&lt;h3 id=&#34;usage-via-kustomizationyaml-9&#34;&gt;Usage via &lt;code&gt;kustomization.yaml&lt;/code&gt;&lt;/h3&gt;
&lt;h4 id=&#34;field-name-replicas&#34;&gt;field name: &lt;code&gt;replicas&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Replicas modified the number of replicas for a resource.&lt;/p&gt;
&lt;p&gt;E.g. Given this kubernetes Deployment fragment:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;kind: Deployment
metadata:
  name: deployment-name
spec:
  replicas: 3
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;one can change the number of replicas to 5
by adding the following to your kustomization:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;replicas:
- name: deployment-name
  count: 5
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This field accepts a list, so many resources can
be modified at the same time.&lt;/p&gt;
&lt;p&gt;As this declaration does not take in a &lt;code&gt;kind:&lt;/code&gt; nor a &lt;code&gt;group:&lt;/code&gt;
it will match any &lt;code&gt;group&lt;/code&gt; and &lt;code&gt;kind&lt;/code&gt; that has a matching name and
that is one of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Deployment&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ReplicationController&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ReplicaSet&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;StatefulSet&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For more complex use cases, revert to using a patch.&lt;/p&gt;
&lt;h3 id=&#34;usage-via-plugin-9&#34;&gt;Usage via plugin&lt;/h3&gt;
&lt;h4 id=&#34;arguments-9&#34;&gt;Arguments&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Replica &lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/replica.go&#34;&gt;types.Replica&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;FieldSpecs []&lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/fieldspec.go&#34;&gt;config.FieldSpec&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&#34;example-9&#34;&gt;Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: builtin
kind: ReplicaCountTransformer
metadata:
  name: not-important-to-example
replica:
  name: myapp
  count: 23
fieldSpecs:
- path: spec/replicas
  create: true
  kind: Deployment
- path: spec/replicas
  create: true
  kind: ReplicationController
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;_secretgenerator_&#34;&gt;&lt;em&gt;SecretGenerator&lt;/em&gt;&lt;/h2&gt;
&lt;h3 id=&#34;usage-via-kustomizationyaml-10&#34;&gt;Usage via &lt;code&gt;kustomization.yaml&lt;/code&gt;&lt;/h3&gt;
&lt;h4 id=&#34;field-name-secretgenerator&#34;&gt;field name: &lt;code&gt;secretGenerator&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Each entry in the argument list
results in the creation of
one Secret resource
(it&amp;rsquo;s a generator of n secrets).&lt;/p&gt;
&lt;p&gt;This works like the &lt;code&gt;configMapGenerator&lt;/code&gt; field
described above.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;secretGenerator:
- name: app-tls
  files:
  - secret/tls.cert
  - secret/tls.key
  type: &amp;quot;kubernetes.io/tls&amp;quot;
- name: app-tls-namespaced
  # you can define a namespace to generate
  # a secret in, defaults to: &amp;quot;default&amp;quot;
  namespace: apps
  files:
  - tls.crt=catsecret/tls.cert
  - tls.key=secret/tls.key
  type: &amp;quot;kubernetes.io/tls&amp;quot;
- name: env_file_secret
  envs:
  - env.txt
  type: Opaque
- name: secret-with-annotation
  files:
  - app-config.yaml
  type: Opaque
  options:
    annotations:
      app_config: &amp;quot;true&amp;quot;
    labels:
      app.kubernetes.io/name: &amp;quot;app2&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;usage-via-plugin-10&#34;&gt;Usage via plugin&lt;/h3&gt;
&lt;h4 id=&#34;arguments-10&#34;&gt;Arguments&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/objectmeta.go&#34;&gt;types.ObjectMeta&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kubernetes-sigs/kustomize/tree/master/api/types/secretargs.go&#34;&gt;types.SecretArgs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&#34;example-10&#34;&gt;Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: builtin
kind: SecretGenerator
metadata:
  name: my-secret
  namespace: whatever
behavior: merge
envs:
- a.env
- b.env
files:
- obscure=longsecret.txt
literals:
- FRUIT=apple
- VEGETABLE=carrot
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;

      </description>
    </item>
    
    <item>
      <title>Guides: Exec plugin on linux</title>
      <link>https://kubernetes-sigs.github.io/kustomize/guides/plugins/execpluginguidedexample/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://kubernetes-sigs.github.io/kustomize/guides/plugins/execpluginguidedexample/</guid>
      <description>
        
        
        &lt;p&gt;This is a (no reading allowed!) 60 second copy/paste guided
example.  Full plugin docs &lt;a href=&#34;..&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This demo writes and uses a somewhat ridiculous
&lt;em&gt;exec&lt;/em&gt; plugin (written in bash) that generates a
&lt;code&gt;ConfigMap&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is a guide to try it without damaging your
current setup.&lt;/p&gt;
&lt;h4 id=&#34;requirements&#34;&gt;requirements&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;linux, git, curl, Go 1.13&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;make-a-place-to-work&#34;&gt;Make a place to work&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;DEMO=$(mktemp -d)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;create-a-kustomization&#34;&gt;Create a kustomization&lt;/h2&gt;
&lt;p&gt;Make a kustomization directory to
hold all your config:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MYAPP=$DEMO/myapp
mkdir -p $MYAPP
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Make a deployment config:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt;$MYAPP/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: the-deployment
spec:
  replicas: 3
  template:
    spec:
      containers:
      - name: the-container
        image: monopole/hello:1
        command: [&amp;quot;/hello&amp;quot;,
                  &amp;quot;--port=8080&amp;quot;,
                  &amp;quot;--date=$(THE_DATE)&amp;quot;,
                  &amp;quot;--enableRiskyFeature=$(ENABLE_RISKY)&amp;quot;]
        ports:
        - containerPort: 8080
        env:
        - name: THE_DATE
          valueFrom:
            configMapKeyRef:
              name: the-map
              key: today
        - name: ALT_GREETING
          valueFrom:
            configMapKeyRef:
              name: the-map
              key: altGreeting
        - name: ENABLE_RISKY
          valueFrom:
            configMapKeyRef:
              name: the-map
              key: enableRisky
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Make a service config:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;EOF &amp;gt;$MYAPP/service.yaml
kind: Service
apiVersion: v1
metadata:
  name: the-service
spec:
  type: LoadBalancer
  ports:
  - protocol: TCP
    port: 8666
    targetPort: 8080
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now make a config file for the plugin
you&amp;rsquo;re about to write.&lt;/p&gt;
&lt;p&gt;This config file is just another k8s resource
object.  The values of its &lt;code&gt;apiVersion&lt;/code&gt; and &lt;code&gt;kind&lt;/code&gt;
fields are used to &lt;em&gt;find&lt;/em&gt; the plugin code on your
filesystem (more on this later).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt;$MYAPP/cmGenerator.yaml
apiVersion: myDevOpsTeam
kind: SillyConfigMapGenerator
metadata:
  name: whatever
argsOneLiner: Bienvenue true
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, make a kustomization file
referencing all of the above:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;EOF &amp;gt;$MYAPP/kustomization.yaml
commonLabels:
  app: hello
resources:
- deployment.yaml
- service.yaml
generators:
- cmGenerator.yaml
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Review the files&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ls -C1 $MYAPP
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;make-a-home-for-plugins&#34;&gt;Make a home for plugins&lt;/h2&gt;
&lt;p&gt;Plugins must live in a particular place for
kustomize to find them.&lt;/p&gt;
&lt;p&gt;This demo will use the ephemeral directory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PLUGIN_ROOT=$DEMO/kustomize/plugin
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The plugin config defined above in
&lt;code&gt;$MYAPP/cmGenerator.yaml&lt;/code&gt; specifies:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: myDevOpsTeam
kind: SillyConfigMapGenerator
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;This means the plugin must live in a directory
named:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MY_PLUGIN_DIR=$PLUGIN_ROOT/myDevOpsTeam/sillyconfigmapgenerator

mkdir -p $MY_PLUGIN_DIR
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The directory name is the plugin config&amp;rsquo;s
&lt;em&gt;apiVersion&lt;/em&gt; followed by its lower-cased &lt;em&gt;kind&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;A plugin gets its own directory to hold itself,
its tests and any supplemental data files it
might need.&lt;/p&gt;
&lt;h2 id=&#34;create-the-plugin&#34;&gt;Create the plugin&lt;/h2&gt;
&lt;p&gt;There are two kinds of plugins, &lt;em&gt;exec&lt;/em&gt; and &lt;em&gt;Go&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Make an &lt;em&gt;exec&lt;/em&gt; plugin, installing it to the
correct directory and file name.  The file name
must match the plugin&amp;rsquo;s &lt;em&gt;kind&lt;/em&gt; (in this case,
&lt;code&gt;SillyConfigMapGenerator&lt;/code&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;lt;&amp;lt;&#39;EOF&#39; &amp;gt;$MY_PLUGIN_DIR/SillyConfigMapGenerator
#!/bin/bash
# Skip the config file name argument.
shift
today=`date +%F`
echo &amp;quot;
kind: ConfigMap
apiVersion: v1
metadata:
  name: the-map
data:
  today: $today
  altGreeting: &amp;quot;$1&amp;quot;
  enableRisky: &amp;quot;$2&amp;quot;
&amp;quot;
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;By definition, an &lt;em&gt;exec&lt;/em&gt; plugin must be executable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;chmod a+x $MY_PLUGIN_DIR/SillyConfigMapGenerator
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;install-kustomize&#34;&gt;Install kustomize&lt;/h2&gt;
&lt;p&gt;Per the &lt;a href=&#34;https://kubernetes-sigs.github.io/kustomize/kustomize/installation&#34;&gt;instructions&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -s &amp;quot;https://raw.githubusercontent.com/\
kubernetes-sigs/kustomize/master/hack/install_kustomize.sh&amp;quot;  | bash
mkdir -p $DEMO/bin
mv kustomize $DEMO/bin
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;review-the-layout&#34;&gt;Review the layout&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;tree $DEMO
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;build-your-app-using-the-plugin&#34;&gt;Build your app, using the plugin:&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;XDG_CONFIG_HOME=$DEMO $DEMO/bin/kustomize build --enable_alpha_plugins $MYAPP
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Above, if you had set&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;&lt;code&gt;PLUGIN_ROOT=$HOME/.config/kustomize/plugin
&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;there would be no need to use &lt;code&gt;XDG_CONFIG_HOME&lt;/code&gt; in the
&lt;em&gt;kustomize&lt;/em&gt; command above.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Guides: Go plugin Caveats</title>
      <link>https://kubernetes-sigs.github.io/kustomize/guides/plugins/goplugincaveats/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://kubernetes-sigs.github.io/kustomize/guides/plugins/goplugincaveats/</guid>
      <description>
        
        
        &lt;p&gt;A &lt;em&gt;Go plugin&lt;/em&gt; is a compilation artifact described
by the Go &lt;a href=&#34;https://golang.org/pkg/plugin&#34;&gt;plugin package&lt;/a&gt;.  It is built with
special flags and cannot run on its own.
It must be loaded into a running Go program.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A normal program written in Go might be usable
as &lt;em&gt;exec plugin&lt;/em&gt;, but is not a &lt;em&gt;Go plugin&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Go plugins allow kustomize extensions that run
without the cost marshalling/unmarshalling all
resource data to/from a subprocess for each plugin
run.  The Go plugin API assures a certain level of
consistency to avoid confusing downstream
transformers.&lt;/p&gt;
&lt;p&gt;Go plugins work as described in the &lt;a href=&#34;https://golang.org/pkg/plugin&#34;&gt;plugin
package&lt;/a&gt;, but fall short of common notions
associated with the word &lt;em&gt;plugin&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id=&#34;the-skew-problem&#34;&gt;The skew problem&lt;/h2&gt;
&lt;p&gt;Go plugin compilation creates an &lt;a href=&#34;https://en.wikipedia.org/wiki/Executable_and_Linkable_Format&#34;&gt;ELF&lt;/a&gt; formatted
&lt;code&gt;.so&lt;/code&gt; file, which by definition has no information
about the provenance of the object code.&lt;/p&gt;
&lt;p&gt;Skew between the compilation conditions (versions
of package dependencies, &lt;code&gt;GOOS&lt;/code&gt;, &lt;code&gt;GOARCH&lt;/code&gt;) of the
main program ELF and the plugin ELF will cause
plugin load failure, with non-helpful error
messages.&lt;/p&gt;
&lt;p&gt;Exec plugins also lack provenance, but won&amp;rsquo;t fail
due to compilation skew.&lt;/p&gt;
&lt;p&gt;In either case, the only sensible way to share a
plugin is as some kind of &lt;em&gt;bundle&lt;/em&gt; (a git repo
URL, a git archive file, a tar file, etc.)
containing source code, tests and associated data,
unpackable under
&lt;code&gt;$XDG_CONFIG_HOME/kustomize/plugin&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In the case of a Go plugin, an &lt;em&gt;end user&lt;/em&gt;
accepting a shared plugin &lt;em&gt;must compile both
kustomize and the plugin&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;This means a one-time run of&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Or whatever is appropriate at time of reading
GOPATH=${whatever} GO111MODULE=on go get sigs.k8s.io/kustomize/api
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and then a normal development cycle using&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;go build -buildmode plugin \
    -o ${wherever}/${kind}.so ${wherever}/${kind}.go
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;with paths and the release version tag (e.g. &lt;code&gt;v3.0.0&lt;/code&gt;)
adjusted as needed.&lt;/p&gt;
&lt;p&gt;For comparison, consider what one
must do to write a &lt;a href=&#34;https://www.tensorflow.org/guide/extend/op&#34;&gt;tensorflow plugin&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;why-support-go-plugins&#34;&gt;Why support Go plugins?&lt;/h2&gt;
&lt;h3 id=&#34;safety&#34;&gt;Safety&lt;/h3&gt;
&lt;p&gt;The Go plugin developer sees the same API offered
to native kustomize operations, assuring certain
semantics, invariants, checks, etc. An exec
plugin sub-process dealing with this via
stdin/stdout will have an easier time screwing
things up for downstream transformers and
consumers.&lt;/p&gt;
&lt;p&gt;Minor point: if the plugin reads files via
the kustomize-provided file &lt;code&gt;Loader&lt;/code&gt; interface, it
will be constrained by kustomize file loading
restrictions.  Of course, nothing but a code audit
prevents a Go plugin from importing the &lt;code&gt;io&lt;/code&gt; package
and doing whatever it wants.&lt;/p&gt;
&lt;h3 id=&#34;debugging&#34;&gt;Debugging&lt;/h3&gt;
&lt;p&gt;A Go plugin developer can debug the plugin &lt;em&gt;in
situ&lt;/em&gt;, setting breakpoints inside the plugin and
elsewhere while running a plugin in feature tests.&lt;/p&gt;
&lt;p&gt;To get the best of both worlds (shareability and safety),
a developer can write an &lt;code&gt;.go&lt;/code&gt; program that functions
as an &lt;em&gt;exec plugin&lt;/em&gt;, but can be processed by &lt;code&gt;go generate&lt;/code&gt;
to emit a &lt;em&gt;Go plugin&lt;/em&gt; (or vice versa).&lt;/p&gt;
&lt;h3 id=&#34;unit-of-contribution&#34;&gt;Unit of contribution&lt;/h3&gt;
&lt;p&gt;All the builtin generators and transformers
are themselves Go plugins.  This means that
the kustomize maintainers can promote a contributed
plugin to a builtin without needing code changes
(beyond those mandated by normal code review).&lt;/p&gt;
&lt;h3 id=&#34;ecosystems-grow-through-use&#34;&gt;Ecosystems grow through use&lt;/h3&gt;
&lt;p&gt;Tooling could ease Go plugin &lt;em&gt;sharing&lt;/em&gt;, but this
requires some critical mass of Go plugin
&lt;em&gt;authoring&lt;/em&gt;, which in turn is hampered by
confusion around sharing.  &lt;a href=&#34;https://github.com/golang/go/wiki/Modules&#34;&gt;Go modules&lt;/a&gt;, once they
are more widely adopted, will solve the
biggest plugin sharing difficulty: ambiguous
plugin vs host dependencies.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Guides: Go plugin example</title>
      <link>https://kubernetes-sigs.github.io/kustomize/guides/plugins/gopluginguidedexample/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://kubernetes-sigs.github.io/kustomize/guides/plugins/gopluginguidedexample/</guid>
      <description>
        
        
        &lt;h1 id=&#34;go-plugin-guided-example-for-linux&#34;&gt;Go Plugin Guided Example for Linux&lt;/h1&gt;
&lt;p&gt;This is a (no reading allowed!) 60 second copy/paste guided
example.&lt;/p&gt;
&lt;p&gt;Full plugin docs &lt;a href=&#34;README.md&#34;&gt;here&lt;/a&gt;.
Be sure to read the &lt;a href=&#34;goPluginCaveats.md&#34;&gt;Go plugin caveats&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This demo uses a Go plugin, &lt;code&gt;SopsEncodedSecrets&lt;/code&gt;,
that lives in the &lt;a href=&#34;https://github.com/monopole/sopsencodedsecrets&#34;&gt;sopsencodedsecrets repository&lt;/a&gt;.
This is an inprocess &lt;a href=&#34;https://golang.org/pkg/plugin&#34;&gt;Go plugin&lt;/a&gt;, not an
sub-process exec plugin that happens to be written
in Go (which is another option for Go authors).&lt;/p&gt;
&lt;p&gt;This is a guide to try it without damaging your
current setup.&lt;/p&gt;
&lt;h4 id=&#34;requirements&#34;&gt;requirements&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;linux, git, curl, Go 1.13&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For encryption&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;gpg&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Or&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Google cloud (gcloud) install&lt;/li&gt;
&lt;li&gt;a Google account with KMS permission&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;make-a-place-to-work&#34;&gt;Make a place to work&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;# Keeping these separate to avoid cluttering the DEMO dir.&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;DEMO&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;mktemp -d&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;tmpGoPath&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;mktemp -d&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;install-kustomize&#34;&gt;Install kustomize&lt;/h2&gt;
&lt;p&gt;Need v3.0.0 for what follows, and you must &lt;em&gt;compile&lt;/em&gt;
it (not download the binary from the release page):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;GOPATH&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;$tmpGoPath&lt;/span&gt; go install sigs.k8s.io/kustomize/kustomize
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;make-a-home-for-plugins&#34;&gt;Make a home for plugins&lt;/h2&gt;
&lt;p&gt;A kustomize plugin is fully determined by
its configuration file and source code.&lt;/p&gt;
&lt;p&gt;Kustomize plugin configuration files are formatted
as kubernetes resource objects, meaning
&lt;code&gt;apiVersion&lt;/code&gt;, &lt;code&gt;kind&lt;/code&gt; and &lt;code&gt;metadata&lt;/code&gt; are &lt;a href=&#34;https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields&#34;&gt;required
fields&lt;/a&gt; in these config files.&lt;/p&gt;
&lt;p&gt;The kustomize program reads the config file
(because the config file name appears in the
&lt;code&gt;generators&lt;/code&gt; or &lt;code&gt;transformers&lt;/code&gt; field in the
kustomization file), then locates the Go plugin&amp;rsquo;s
object code at the following location:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;$XDG_CONFIG_HOME&lt;/span&gt;/kustomize/plugin/&lt;span style=&#34;color:#000&#34;&gt;$apiVersion&lt;/span&gt;/&lt;span style=&#34;color:#000&#34;&gt;$lKind&lt;/span&gt;/&lt;span style=&#34;color:#000&#34;&gt;$kind&lt;/span&gt;.so
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;where &lt;code&gt;lKind&lt;/code&gt; holds the lowercased kind.  The
plugin is then loaded and fed its config, and the
plugin&amp;rsquo;s output becomes part of the overall
&lt;code&gt;kustomize build&lt;/code&gt; process.&lt;/p&gt;
&lt;p&gt;The same plugin might be used multiple times in
one kustomize build, but with different config
files.  Also, kustomize might customize config
data before sending it to the plugin, for whatever
reason.  For these reasons, kustomize owns the
mapping between plugins and config data; it&amp;rsquo;s not
left to plugins to find their own config.&lt;/p&gt;
&lt;p&gt;This demo will house the plugin it uses at the
ephemeral directory&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;PLUGIN_ROOT&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;$DEMO&lt;/span&gt;/kustomize/plugin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and ephemerally set &lt;code&gt;XDG_CONFIG_HOME&lt;/code&gt; on a command
line below.&lt;/p&gt;
&lt;h3 id=&#34;what-apiversion-and-kind&#34;&gt;What apiVersion and kind?&lt;/h3&gt;
&lt;p&gt;At this stage in the development of kustomize
plugins, plugin code doesn&amp;rsquo;t know or care what
&lt;code&gt;apiVersion&lt;/code&gt; or &lt;code&gt;kind&lt;/code&gt; appears in the config file
sent to it.&lt;/p&gt;
&lt;p&gt;The plugin could check these fields, but it&amp;rsquo;s the
remaining fields that provide actual configuration
data, and at this point the successful parsing of
these other fields are the only thing that matters
to a plugin.&lt;/p&gt;
&lt;p&gt;This demo uses a plugin called &lt;em&gt;SopsEncodedSecrets&lt;/em&gt;,
and it lives in the &lt;a href=&#34;https://github.com/monopole/sopsencodedsecrets&#34;&gt;SopsEncodedSecrets repository&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Somewhat arbitrarily, we&amp;rsquo;ll chose to install
this plugin with&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;mygenerators
&lt;span style=&#34;color:#000&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;SopsEncodedSecrets
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;define-the-plugins-home-dir&#34;&gt;Define the plugin&amp;rsquo;s home dir&lt;/h3&gt;
&lt;p&gt;By convention, the ultimate home of the plugin
code and supplemental data, tests, documentation,
etc. is the lowercase form of its kind.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;lKind&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#204a87&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;$kind&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&lt;/span&gt; awk &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#39;{print tolower($0)}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;download-the-sopsencodedsecrets-plugin&#34;&gt;Download the SopsEncodedSecrets plugin&lt;/h3&gt;
&lt;p&gt;In this case, the repo name matches the lowercase
kind already, so we just clone the repo and get
the proper directory name automatically:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;mkdir -p &lt;span style=&#34;color:#000&#34;&gt;$PLUGIN_ROOT&lt;/span&gt;/&lt;span style=&#34;color:#4e9a06&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;}&lt;/span&gt;
&lt;span style=&#34;color:#204a87&#34;&gt;cd&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;$PLUGIN_ROOT&lt;/span&gt;/&lt;span style=&#34;color:#4e9a06&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;}&lt;/span&gt;
git clone git@github.com:monopole/sopsencodedsecrets.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Remember this directory:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;MY_PLUGIN_DIR&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;$PLUGIN_ROOT&lt;/span&gt;/&lt;span style=&#34;color:#4e9a06&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;apiVersion&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;}&lt;/span&gt;/&lt;span style=&#34;color:#4e9a06&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;lKind&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;try-the-plugins-own-test&#34;&gt;Try the plugin&amp;rsquo;s own test&lt;/h3&gt;
&lt;p&gt;Plugins may come with their own tests.
This one does, and it hopefully passes:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;color:#204a87&#34;&gt;cd&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;$MY_PLUGIN_DIR&lt;/span&gt;
go &lt;span style=&#34;color:#204a87&#34;&gt;test&lt;/span&gt; SopsEncodedSecrets_test.go
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Build the object code for use by kustomize:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;color:#204a87&#34;&gt;cd&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;$MY_PLUGIN_DIR&lt;/span&gt;
&lt;span style=&#34;color:#000&#34;&gt;GOPATH&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;$tmpGoPath&lt;/span&gt; go build -buildmode plugin -o &lt;span style=&#34;color:#4e9a06&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;}&lt;/span&gt;.so &lt;span style=&#34;color:#4e9a06&#34;&gt;${&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;kind&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;}&lt;/span&gt;.go
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This step may succeed, but kustomize might
ultimately fail to load the plugin because of
dependency &lt;a href=&#34;https://kubernetes-sigs.github.io/kustomize/docs/plugins/README.md#caveats&#34;&gt;skew&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;On load failure&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;be sure to build the plugin with the same
version of Go (&lt;em&gt;go1.13&lt;/em&gt;) on the same &lt;code&gt;$GOOS&lt;/code&gt;
(&lt;em&gt;linux&lt;/em&gt;) and &lt;code&gt;$GOARCH&lt;/code&gt; (&lt;em&gt;amd64&lt;/em&gt;) used to build
the kustomize being &lt;a href=&#34;#install-kustomize&#34;&gt;used in this demo&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;change the plugin&amp;rsquo;s dependencies in its &lt;code&gt;go.mod&lt;/code&gt;
to match the versions used by kustomize (check
kustomize&amp;rsquo;s &lt;code&gt;go.mod&lt;/code&gt; used in its tagged commit).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lacking tools and metadata to allow this to be
automated, there won&amp;rsquo;t be a Go plugin ecosystem.&lt;/p&gt;
&lt;p&gt;Kustomize has adopted a Go plugin architecture as
to ease accept new generators and transformers
(just write a plugin), and to be sure that native
operations (also constructed and tested as
plugins) are compartmentalized, orderable and
reusable instead of bizarrely woven throughout the
code as a individual special cases.&lt;/p&gt;
&lt;h2 id=&#34;create-a-kustomization&#34;&gt;Create a kustomization&lt;/h2&gt;
&lt;p&gt;Make a kustomization directory to
hold all your config:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;MYAPP&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;$DEMO&lt;/span&gt;/myapp
mkdir -p &lt;span style=&#34;color:#000&#34;&gt;$MYAPP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Make a config file for the SopsEncodedSecrets plugin.&lt;/p&gt;
&lt;p&gt;Its &lt;code&gt;apiVersion&lt;/code&gt; and &lt;code&gt;kind&lt;/code&gt; allow the plugin to be
found:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;cat &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;lt;&amp;lt;EOF &amp;gt;$MYAPP/secGenerator.yaml
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;apiVersion: ${apiVersion}
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;kind: ${kind}
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;metadata:
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;  name: mySecretGenerator
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;name: forbiddenValues
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;namespace: production
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;file: myEncryptedData.yaml
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;keys:
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;- ROCKET
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;- CAR
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;EOF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This plugin expects to find more data in
&lt;code&gt;myEncryptedData.yaml&lt;/code&gt;; we&amp;rsquo;ll get to that shortly.&lt;/p&gt;
&lt;p&gt;Make a kustomization file referencing the plugin
config:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;cat &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;lt;&amp;lt;EOF &amp;gt;$MYAPP/kustomization.yaml
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;commonLabels:
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;  app: hello
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;generators:
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;- secGenerator.yaml
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;EOF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now generate the real encrypted data.&lt;/p&gt;
&lt;h3 id=&#34;assure-you-have-an-encryption-tool-installed&#34;&gt;Assure you have an encryption tool installed&lt;/h3&gt;
&lt;p&gt;We&amp;rsquo;re going to use &lt;a href=&#34;https://github.com/mozilla/sops&#34;&gt;sops&lt;/a&gt; to encode a file. Choose either GPG or Google Cloud KMS as the secret provider to continue.&lt;/p&gt;
&lt;h4 id=&#34;gpg&#34;&gt;GPG&lt;/h4&gt;
&lt;p&gt;Try this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;gpg --list-keys
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If it returns a list, presumably you&amp;rsquo;ve already created keys. If not, try import test keys from sops for dev.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;curl https://raw.githubusercontent.com/mozilla/sops/master/pgp/sops_functional_tests_key.asc &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&lt;/span&gt; gpg --import
&lt;span style=&#34;color:#000&#34;&gt;SOPS_PGP_FP&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;1022470DE3F0BC54BC6AB62DE05550BC07FB1A0A&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;google-cloude-kms&#34;&gt;Google Cloude KMS&lt;/h4&gt;
&lt;p&gt;Try this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;gcloud kms keys list --location global --keyring sops
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If it succeeds, presumably you&amp;rsquo;ve already created keys and placed them in a keyring called sops. If not, do this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;gcloud kms keyrings create sops --location global
gcloud kms keys create sops-key --location global &lt;span style=&#34;color:#4e9a06&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&lt;/span&gt;    --keyring sops --purpose encryption
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Extract your keyLocation for use below:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;keyLocation&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;$(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&lt;/span&gt;    gcloud kms keys list --location global --keyring sops &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&lt;/span&gt;    grep GOOGLE &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&lt;/span&gt; cut -d &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34; &amp;#34;&lt;/span&gt; -f1&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;)&lt;/span&gt;
&lt;span style=&#34;color:#204a87&#34;&gt;echo&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;$keyLocation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;install-sops&#34;&gt;Install &lt;code&gt;sops&lt;/code&gt;&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;GOPATH&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;$tmpGoPath&lt;/span&gt; go install go.mozilla.org/sops/cmd/sops
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;create-data-encrypted-with-your-private-key&#34;&gt;Create data encrypted with your private key&lt;/h3&gt;
&lt;p&gt;Create raw data to encrypt:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;cat &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;lt;&amp;lt;EOF &amp;gt;$MYAPP/myClearData.yaml
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;VEGETABLE: carrot
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;ROCKET: saturn-v
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;FRUIT: apple
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;CAR: dymaxion
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;EOF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Encrypt the data into file the plugin wants to read:&lt;/p&gt;
&lt;p&gt;With PGP&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;$tmpGoPath&lt;/span&gt;/bin/sops --encrypt &lt;span style=&#34;color:#4e9a06&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&lt;/span&gt;  --pgp &lt;span style=&#34;color:#000&#34;&gt;$SOPS_PGP_FP&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#000&#34;&gt;$MYAPP&lt;/span&gt;/myClearData.yaml &amp;gt;&lt;span style=&#34;color:#000&#34;&gt;$MYAPP&lt;/span&gt;/myEncryptedData.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or GCP KMS&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;$tmpGoPath&lt;/span&gt;/bin/sops --encrypt &lt;span style=&#34;color:#4e9a06&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&lt;/span&gt;  --gcp-kms &lt;span style=&#34;color:#000&#34;&gt;$keyLocation&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;\
&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#000&#34;&gt;$MYAPP&lt;/span&gt;/myClearData.yaml &amp;gt;&lt;span style=&#34;color:#000&#34;&gt;$MYAPP&lt;/span&gt;/myEncryptedData.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Review the files&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;tree &lt;span style=&#34;color:#000&#34;&gt;$DEMO&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This should look something like:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;/tmp/tmp.0kIE9VclPt
├── kustomize
│   └── plugin
│       └── mygenerators
│           └── sopsencodedsecrets
│               ├── go.mod
│               ├── go.sum
│               ├── LICENSE
│               ├── README.md
│               ├── SopsEncodedSecrets.go
│               ├── SopsEncodedSecrets.so
│               └── SopsEncodedSecrets_test.go
└── myapp
    ├── kustomization.yaml
    ├── myClearData.yaml
    ├── myEncryptedData.yaml
    └── secGenerator.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;h2 id=&#34;build-your-app-using-the-plugin&#34;&gt;Build your app, using the plugin:&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;XDG_CONFIG_HOME&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;$DEMO&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;$tmpGoPath&lt;/span&gt;/bin/kustomize build --enable_alpha_plugins &lt;span style=&#34;color:#000&#34;&gt;$MYAPP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This should emit a kubernetes secret, with
encrypted data for the names &lt;code&gt;ROCKET&lt;/code&gt; and &lt;code&gt;CAR&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Above, if you had set&lt;/p&gt;
&lt;blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;color:#000&#34;&gt;PLUGIN_ROOT&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;$HOME&lt;/span&gt;/.config/kustomize/plugin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;there would be no need to use &lt;code&gt;XDG_CONFIG_HOME&lt;/code&gt; in the
&lt;em&gt;kustomize&lt;/em&gt; command above.&lt;/p&gt;

      </description>
    </item>
    
  </channel>
</rss>
