<p>I have an environment made of pods that address their target environment based on an environment variable called <code>CONF_ENV</code> that could be <code>test</code>, <code>stage</code> or <code>prod</code>.</p>
<p>The application running inside the Pod has the same source code across environments, the configuration file is picked according to the <code>CONF_ENV</code> environment variable.</p>
<p>I'v encapsulated this <code>CONF_ENV</code> in <code>*.properties</code> files just because I may have to add more environment variables later, but I make sure that each property file contains the expected <code>CONF_ENV</code> e.g.:</p>
<ul>
<li><code>test.properites</code> has <code>CONF_ENV=test</code>,</li>
<li><code>prod.properties</code> has <code>CONF_ENV=prod</code>, and so on...</li>
</ul>
<p>I struggle to make this work with Kustomize overlays, because I want to define a <code>ConfigMap</code> as a shared resource across all the pods within the same overlay e.g. <code>test</code> (each pod in their own directory, along other stuff when needed).</p>
<p>So the idea is:</p>
<ul>
<li><code>base/</code> (shared) with the definition of the <code>Namespace</code>, the <code>ConfigMap</code> (and potentially other shared resources</li>
<li><code>base/pod1/</code> with the definition of pod1 picking from the shared <code>ConfigMap</code> (this defaults to <code>test</code>, but in principle it could be different)</li>
</ul>
<p>Then the overlays:</p>
<ul>
<li><code>overlay/test</code> that patches the base with <code>CONF_ENV=test</code> (e.g. for <code>overlay/test/pod1/</code> and so on)</li>
<li><code>overlay/prod/</code> that patches the base with <code>CONF_ENV=prod</code> (e.g. for <code>overlay/prod/pod1/</code> and so on)</li>
</ul>
<p>Each directory with their own <code>kustomize.yaml</code>.</p>
<p>The above doesn't work because when going into e.g. <code>overlay/test/pod1/</code> and I invoke the command <code>kubectl kustomize .</code> to check the output YAML, then I get all sorts of errors depending on how I defined the lists for the YAML keys <code>bases:</code> or <code>resources:</code>.</p>
<p>I am trying to share the <code>ConfigMap</code> across the entire <code>CONF_ENV</code> environment in an attempt to <strong>minimize the boilerplate YAML</strong> by leveraging the patching-pattern with Kustomize.</p>
<p>The Kubernetes / Kustomize YAML directory structure works like this:</p>
<pre class="lang-sh prettyprint-override"><code>├── base
│   ├── configuration.yaml # I am trying to share this!
│   ├── kustomization.yaml
│   ├── my_namespace.yaml # I am trying to share this!
│   ├── my-scheduleset-etl-misc
│   │   ├── kustomization.yaml
│   │   └── my_scheduleset_etl_misc.yaml
│   ├── my-scheduleset-etl-reporting
│   │   ├── kustomization.yaml
│   │   └── my_scheduleset_etl_reporting.yaml
│   └── test.properties # I am trying to share this!
└── overlay
    └── test
        ├── kustomization.yaml # here I want tell &quot;go and pick up the shared resources in the base dir&quot;
        ├── my-scheduleset-etl-misc
        │   ├── kustomization.yaml
        │   └── test.properties # I've tried to share this one level above, but also to add this inside the &quot;leaf&quot; level for a given pod
        └── my-scheduleset-etl-reporting
            └── kustomization.yaml
</code></pre>
<p>The command <code>kubectl</code> with Kustomize:</p>
<ul>
<li>sometimes complains that the shared namespace does not exist:</li>
</ul>
<pre><code>error: merging from generator &amp;{0xc001d99530 {  map[] map[]} {{ my-schedule-set-props merge {[CONF_ENV=test] [] [] } &lt;nil&gt;}}}: 
id resid.ResId{Gvk:resid.Gvk{Group:&quot;&quot;, Version:&quot;v1&quot;, Kind:&quot;ConfigMap&quot;, isClusterScoped:false}, Name:&quot;my-schedule-set-props&quot;, Namespace:&quot;&quot;} 
does not exist; cannot merge or replace
</code></pre>
<ul>
<li>sometimes doesn't allow to have shared resources inside an overlay:</li>
</ul>
<pre><code>error: loading KV pairs: env source files: [../test.properties]: 
security; file '/my/path/to/yaml/overlay/test/test.properties' 
is not in or below '/my/path/to/yaml/overlay/test/my-scheduleset-etl-misc'
</code></pre>
<ul>
<li>sometimes doesn't allow cycles when I am trying to have multiple bases - the shared resources and the original pod definition:</li>
</ul>
<pre><code>error: accumulating resources: accumulation err='accumulating resources from '../': 
'/my/path/to/yaml/overlay/test' must resolve to a file': 
cycle detected: candidate root '/my/path/to/yaml/overlay/test' 
contains visited root '/my/path/to/yaml/overlay/test/my-scheduleset-etl-misc'
</code></pre>
<p>The overlay <code>kustomization.yaml</code> files inside the pod dirs have:</p>
<pre class="lang-yaml prettyprint-override"><code>bases:
  - ../ # tried with/without this to share the ConfigMap
  - ../../../base/my-scheduleset-etl-misc/
</code></pre>
<p>The <code>kustomization.yaml</code> at the root of the overlay has:</p>
<pre class="lang-yaml prettyprint-override"><code>bases:
  - ../../base
</code></pre>
<p>The <code>kustomization.yaml</code> at the base dir contains this configuration for the ConfigMap:</p>
<pre class="lang-yaml prettyprint-override"><code># https://gist.github.com/hermanbanken/3d0f232ffd86236c9f1f198c9452aad9
configMapGenerator:
  - name: my-schedule-set-props
    namespace: my-ss-schedules
    envs:
      - test.properties

vars:
  - name: CONF_ENV
    objref:
      kind: ConfigMap
      name: my-schedule-set-props
      apiVersion: v1
    fieldref:
      fieldpath: data.CONF_ENV

configurations:
  - configuration.yaml
</code></pre>
<p>With <code>configuration.yaml</code> containing:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

varReference:
- path: spec/confEnv/value
  kind: Pod
</code></pre>
<p>How do I do this?</p>
<p>How do I make sure that I minimise the amount of YAML by sharing all the <code>ConfigMap</code> stuff and the Pods definitions as much as I can?</p>

<p>If I understand your goal correctly, I think you may be grossly over-complicating things. I <em>think</em> you want a common properties file defined in your base, but you want to override specific properties in your overlays. Here's one way of doing that.</p>
<p>In base, I have:</p>
<pre><code>$ cd base
$ tree
.
├── example.properties
├── kustomization.yaml
└── pod1
    ├── kustomization.yaml
    └── pod.yaml
</code></pre>
<p>Where <code>example.properties</code> contains:</p>
<pre><code>SOME_OTHER_VAR=somevalue
CONF_ENV=test
</code></pre>
<p>And <code>kustomization.yaml</code> contains:</p>
<pre><code>resources:
  - pod1

configMapGenerator:
  - name: example-props
    envs:
      - example.properties
</code></pre>
<p>I have two overlays defined, <code>test</code> and <code>prod</code>:</p>
<pre><code>$ cd ../overlays
$ tree
.
├── prod
│   ├── example.properties
│   └── kustomization.yaml
└── test
    └── kustomization.yaml
</code></pre>
<p><code>test/kustomization.yaml</code> looks like this:</p>
<pre><code>resources:
- ../../base
</code></pre>
<p>It's just importing the <code>base</code> without any changes, since the value of <code>CONF_ENV</code> from the <code>base</code> directory is <code>test</code>.</p>
<p><code>prod/kustomization.yaml</code> looks like this:</p>
<pre><code>apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base

configMapGenerator:
  - name: example-props
    behavior: merge
    envs:
      - example.properties
</code></pre>
<p>And <code>prod/example.properties</code> looks like:</p>
<pre><code>CONF_ENV=prod
</code></pre>
<p>If I run <code>kustomize build overlays/test</code>, I get as output:</p>
<pre><code>apiVersion: v1
data:
  CONF_ENV: test
  SOME_OTHER_VAR: somevalue
kind: ConfigMap
metadata:
  name: example-props-7245222b9b
---
apiVersion: v1
kind: Pod
metadata:
  name: example
spec:
  containers:
  - command:
    - sleep
    - 1800
    envFrom:
    - configMapRef:
        name: example-props-7245222b9b
    image: docker.io/alpine
    name: alpine
</code></pre>
<p>If I run <code>kustomize build overlays/prod</code>, I get:</p>
<pre><code>apiVersion: v1
data:
  CONF_ENV: prod
  SOME_OTHER_VAR: somevalue
kind: ConfigMap
metadata:
  name: example-props-h4b5tc869g
---
apiVersion: v1
kind: Pod
metadata:
  name: example
spec:
  containers:
  - command:
    - sleep
    - 1800
    envFrom:
    - configMapRef:
        name: example-props-h4b5tc869g
    image: docker.io/alpine
    name: alpine
</code></pre>
<p>That is, everything looks as you would expect given the configuration in <code>base</code>, but we have provided a new value for <code>CONF_ENV</code>.</p>
<p>You can find all these files <a href="https://github.com/larsks/so-example-71008589" rel="noreferrer">here</a>.</p>
