[← Config import](05-config-import.md) · [Index](../README.md) # 6. Config trees and Kubernetes ConfigMaps Transcript: [`03-config-tree.txt`](output/03-config-tree.txt). ## What Kubernetes actually mounts A ConfigMap mounted as a volume is not a properties file. Kubernetes writes **one file per key**, named after the key, containing only the value with no trailing newline: ``` /demo.datasource-url /demo.greeting /demo.pool-size /demo/nested/value /demo.api-key ``` ``` $ cat /demo.greeting from-configmap-volume ``` There is no syntax to parse. The filename is the key. ## Reading it ``` --spring.config.import=configtree:/etc/config/,configtree:/etc/secrets/ ``` A trailing `/` is required — the location is a directory. Values arrive as properties: ``` demo.pool-size = 25 demo.nested.value = from-nested-directory demo.api-key = sk_live_not_a_real_key ``` A directory under the mount becomes a nested property, so `demo/nested/value` is `demo.nested.value`. That is how a ConfigMap whose keys contain slashes arrives. Secrets mount identically. The only difference is file permissions, which is why the same mechanism reads both and why nothing in your application needs to know which it got. ## Why this beats mounting a properties file - **Per-key updates.** Changing one key rewrites one file. Kubernetes propagates it to the volume without a restart, and `spring.config.import` supports `configtree` reloading through Spring Cloud Kubernetes if you want to act on it. - **No parse step**, so no chance of one malformed line taking out the whole file. - **Secrets and config read the same way.** - **Values can contain anything.** No escaping, no quoting, no YAML surprises — a value of `yes` stays the string `yes`. ## Wildcards ``` --spring.config.import=optional:configtree:/etc/config/*/ ``` Reads every immediate subdirectory, which is the shape you get when several ConfigMaps are mounted under one parent. Useful for "one ConfigMap per component" layouts. ## It is still config data An imported config tree outranks `application.yaml` — and still loses to an environment variable: ``` effective value : from-environment-variable 1. from-environment-variable <- systemEnvironment 2. from-configmap-volume <- ConfigTreePropertySource 3. from-application-yaml <- application.yaml ``` If you mount a ConfigMap *and* set `envFrom` on the same Deployment — which is a common way to migrate from one to the other — the environment variables win and the ConfigMap looks broken. ## There is no profile-specific config tree No `-prod` convention exists. Per-environment configuration is a different ConfigMap chosen by the Deployment, not by `spring.profiles.active`. This is a feature: the environment is decided by what you deploy, not by a string inside the image.