skip to content

How do you create a Kubernetes ConfigMap from the command line using literal values, a file, a directory, and a dotenv-style file — and how do the resulting keys differ in each case?

level: juniorimportance: should knowfreq 48%

answer

  1. --from-literal=K=V → one key
  2. --from-file=path → key is basename, value is whole file
  3. --from-file=key=path renames
  4. --from-env-file → one key per LINE
  5. create --dry-run=client -o yaml | apply -f -

basics

~20 s

Use kubectl create configmap NAME with --from-literal=K=V (key is K), --from-file=path (key is the file's basename, value is its content), --from-file=key=path to rename, --from-file=dir/ (one key per file), or --from-env-file=.env (one key per line in the file).

solid answer

~50 s

`kubectl create configmap app-config` takes several source flags: - `--from-literal=LOG_LEVEL=debug` — key `LOG_LEVEL`, value `debug`. - `--from-file=./application.yaml` — key is the basename `application.yaml`, value is the whole file content. - `--from-file=config=./application.yaml` — same content under the key `config`. - `--from-file=./conf.d/` — every regular file in the directory becomes one key. - `--from-env-file=./.env` — each `KEY=value` line becomes a separate key, so this is the flag for producing many scalar keys rather than one file-shaped key. Flags can be repeated and combined. `kubectl create` fails if the object already exists, so in scripts the idiom is `kubectl create configmap app-config --from-file=... --dry-run=client -o yaml | kubectl apply -f -`, which is also how you generate a manifest to commit. Keys must contain only alphanumerics, `-`, `_` and `.`; binary content lands in `binaryData` rather than `data`.

code

bash · 12 lines
bash
kubectl create configmap app-config \
  --from-literal=LOG_LEVEL=debug \
  --from-file=application.yaml \
  --from-file=nginx=./conf/nginx.conf \
  --from-env-file=./.env

# idempotent version for CI / re-runs
kubectl create configmap app-config \
  --from-file=./conf/ \
  --dry-run=client -o yaml | kubectl apply -f -

kubectl get configmap app-config -o yaml

go deeper

for a junior

Recall the four flags and what key each produces; be able to type the create command from memory.

for a middle

Add the key-naming rules, the UTF-8/binaryData split, and why the imperative create is replaced by the dry-run-plus-apply pipeline.

for a senior

Talk about how the object gets into the cluster in a real pipeline — generated manifests, Kustomize configMapGenerator hashes, apply pruning semantics on removed keys.

for a principal

Position ConfigMap authoring inside the delivery model: who owns config, how it is reviewed and versioned, and how generated hashed names make config changes first-class, revertible releases.

## Why the flags matter The difference between `--from-file` and `--from-env-file` is the single most common confusion here, and it decides the *shape* of the resulting object — one key holding a whole file versus many small keys. That shape then decides how the Pod can consume it: many scalar keys work with `envFrom`, one file-shaped key works as a volume-mounted file. ## The source flags in detail **`--from-literal=KEY=VALUE`** creates exactly one entry. Repeat it for more. Quote carefully — the shell splits on spaces, and a value containing `=` is fine because only the first `=` separates key from value. **`--from-file=PATH`** with a file path creates one entry whose key is the file's *basename* and whose value is the file's entire contents, newlines included. `--from-file=/etc/nginx/nginx.conf` yields the key `nginx.conf`, not the full path. **`--from-file=KEY=PATH`** overrides the key. Use this when the on-disk name is not what the container expects, or when two source files share a basename. **`--from-file=DIR/`** with a directory adds one entry per regular file directly inside it — subdirectories are not recursed, and files whose names are not valid ConfigMap keys are rejected with an error. This is the natural way to ship a directory of drop-in config files. **`--from-env-file=PATH`** parses the file as a dotenv document: one `KEY=value` per line, `#` comments and blank lines ignored, no shell expansion, no `export` prefix and no multi-line values. Each line becomes its own ConfigMap key. Note the asymmetry: `--from-file=.env` would give you a *single* key called `.env` whose value is the whole file — almost never what you wanted. Flags combine freely: `kubectl create configmap app --from-env-file=.env --from-file=application.yaml --from-literal=BUILD=42`. ## Keys, values and limits Keys must consist of alphanumeric characters, `-`, `_` or `.`. That means `application.yaml` is a legal *key* but not a legal *environment variable name*, which is why `envFrom` silently skips it (recording an event) while a volume mount handles it fine. Values under `data` must be valid UTF-8. Non-UTF-8 content is placed under `binaryData` as base64 by `kubectl` automatically when you use `--from-file` with a binary file. The whole object is limited to roughly 1 MiB. ## Imperative creation versus a committed manifest `kubectl create` is imperative and fails with `AlreadyExists` on a second run, which makes it awkward in CI. Three ways forward: - **Generate and apply**: `kubectl create configmap app --from-file=./conf --dry-run=client -o yaml | kubectl apply -f -`. This is idempotent, works with `kubectl diff`, and is the standard scripted idiom. `--dry-run=client` means "render, do not contact the server" (the older bare `--dry-run` is removed; `--dry-run=server` validates against the API server without persisting). - **Generate and commit**: same command with `-o yaml > configmap.yaml`, then treat that file as source. Good when the config file is small and reviewable. - **Let a tool generate it**: Kustomize's `configMapGenerator` takes the same `literals`/`files`/`envs` inputs and appends a content hash to the object's name, rewriting references in the workloads that use it. Helm users template the ConfigMap and add a checksum annotation on the Pod template. Both turn a config edit into a Pod-template change, so a rollout happens automatically and can be rolled back. `kubectl create configmap ... --dry-run=client -o yaml` is also the fastest way to answer "what does the YAML for this look like?" in a live interview or exam. ## Updating an existing ConfigMap `kubectl edit configmap app` opens it in an editor. `kubectl apply -f` performs a three-way merge and is the safe scripted path. `kubectl replace -f` overwrites wholesale. A common trap: re-running `kubectl create ... --dry-run=client -o yaml | kubectl apply -f -` after *deleting* a key from disk does remove the key from the object (apply prunes fields it previously owned), while `kubectl patch` with a partial map only adds and overwrites. Immutable ConfigMaps reject all of these — they must be deleted and recreated, which is why they are normally paired with hashed names. ## Inspection `kubectl get configmap app -o yaml` shows everything. `kubectl describe configmap app` prints the values in a friendlier layout but truncates binary data. To see who consumes it there is no built-in reverse index — you grep the Pod specs (`kubectl get pods -o yaml | grep -A3 configMap`) or rely on your GitOps repository, which is one reason to keep references explicit rather than sprawling `envFrom` usage.

  • What is the difference between --from-file=.env and --from-env-file=.env?
    `--from-file=.env` creates a single key named `.env` whose value is the entire file, including newlines. `--from-env-file=.env` parses the file and creates one key per `KEY=value` line. Only the second form produces keys you can feed to a container with `envFrom`.
  • Why does kubectl create configmap fail on a second run, and what do you use instead in a pipeline?
    `create` is imperative and returns `AlreadyExists` when the object exists. The standard replacement is `kubectl create ... --dry-run=client -o yaml | kubectl apply -f -`, which renders the object locally and then performs a server-side three-way merge, making the command safely repeatable.

saying these in an interview costs you the question

  • Expecting --from-file to split the file into multiple keys
  • Thinking --from-file=/path/to/app.conf produces the full path as the key
  • Assuming kubectl create is idempotent
  • Believing any ConfigMap key is automatically a valid environment variable name
  • Using --dry-run without a value (that form was removed; use --dry-run=client)

context