Table of Contents
Understanding ConfigMaps in OpenShift
ConfigMaps in OpenShift provide a way to inject non-sensitive configuration data into your applications without baking that configuration into container images. They are Kubernetes-native objects, but OpenShift adds some conveniences in how you work with them.
This chapter focuses on how ConfigMaps work specifically in OpenShift, how to create and use them, and common patterns and pitfalls.
What a ConfigMap Is (in Practice)
Conceptually, a ConfigMap is a key–value store for configuration data where:
- Keys are strings (e.g.
APP_MODE,config.yaml) - Values are either:
- Simple strings, or
- Multi-line data (e.g. whole config files, scripts, templates)
ConfigMaps are not for secrets or credentials (those belong in Secret objects). They are for non-sensitive configuration that you might want to change without rebuilding images.
Common use cases in OpenShift:
- Application settings (mode, feature flags, URLs)
- External service endpoints (logging server, API URLs)
- Full configuration files (e.g.
application.properties,nginx.conf) - Script snippets or templates
Types of ConfigMaps and Key Styles
ConfigMaps are flexible in how they structure data. The main practical distinction is:
- “Environment-style”: Many simple
key: valuepairs, ideal for environment variables. - “File-style”: Keys that look like filenames (e.g.
config.yaml,nginx.conf), ideal for mounting as files.
Example of an “environment-style” ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_MODE: "production"
LOG_LEVEL: "info"
API_BASE_URL: "https://api.example.com"Example of a “file-style” ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-files
data:
application.properties: |
app.mode=production
logging.level=INFO
logging.conf: |
handlers = java.util.logging.ConsoleHandler
.level = INFOHow you intend to consume the ConfigMap (env vars vs mounted files) often drives how you structure it.
Creating ConfigMaps in OpenShift
You can create ConfigMaps via the web console or the oc CLI.
Using the Web Console
Within a project/namespace:
- Navigate to Workloads → ConfigMaps.
- Click Create ConfigMap.
- Choose:
- Form view (simple key–value editing, multiple entries).
- YAML view (define full YAML).
- Add your keys and values.
- Save.
The console shows where a ConfigMap is referenced from (e.g. which Deployments), which is useful for understanding impact.
Using the `oc` CLI
From Literal Values
Use --from-literal for quick, simple key–value pairs:
oc create configmap app-config \
--from-literal=APP_MODE=production \
--from-literal=LOG_LEVEL=infoFrom a File
Use --from-file to load file content as values:
oc create configmap app-config-files \
--from-file=application.properties=./application.properties \
--from-file=logging.conf=./logging.conf
This creates keys application.properties and logging.conf with file contents as values.
You can also import a whole directory:
oc create configmap app-config-dir --from-file=./config-dir
Each file inside ./config-dir becomes a key with its file content as the value.
From a YAML/JSON Manifest
You can define ConfigMaps declaratively and apply them:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_MODE: "development"
FEATURE_X_ENABLED: "true"Apply with:
oc apply -f app-config.yamlUsing ConfigMaps in Pods
There are two primary ways to use ConfigMaps:
- As environment variables.
- As configuration files mounted into the container filesystem.
You can mix both approaches in a single pod.
Injecting ConfigMaps as Environment Variables
You can expose each key in a ConfigMap as an environment variable in a pod.
Using `envFrom`
This is the most common pattern:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: app
image: quay.io/example/my-app:latest
envFrom:
- configMapRef:
name: app-config
All keys in app-config become environment variables in the container, e.g. APP_MODE, LOG_LEVEL, etc.
Using `env` with `valueFrom`
If you only need specific keys, or want to rename them:
containers:
- name: app
image: ...
env:
- name: APP_MODE
valueFrom:
configMapKeyRef:
name: app-config
key: APP_MODE
- name: VERBOSE_LOGGING
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVEL
The key name in the ConfigMap (LOG_LEVEL) does not need to match the env var name (VERBOSE_LOGGING).
Mounting ConfigMaps as Files
For applications that read configuration from files, mount a ConfigMap as a volume.
Mounting Entire ConfigMap
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: app
image: ...
volumeMounts:
- name: config-volume
mountPath: /opt/app/config
volumes:
- name: config-volume
configMap:
name: app-config-filesInside the container:
/opt/app/config/application.propertiesis created from the corresponding ConfigMap key./opt/app/config/logging.confis created similarly.
The mounted files are not writable by the application; they are managed by Kubernetes/OpenShift.
Mounting a Single Key to a Specific Path
If the ConfigMap has many entries and you only need one:
volumes:
- name: config-volume
configMap:
name: app-config-files
items:
- key: application.properties
path: app.propertiesThen mount as usual:
volumeMounts:
- name: config-volume
mountPath: /opt/app/config
Result: /opt/app/config/app.properties exists and is backed by the application.properties key.
Controlling File Permissions
You can control default file mode when mounting:
volumes:
- name: config-volume
configMap:
name: app-config-files
defaultMode: 0440This affects permissions inside the container; it doesn’t alter the UID/GID ownership logic of the container runtime.
Updating ConfigMaps and Application Behavior
Changing configuration without a full redeploy is a major benefit of ConfigMaps, but behavior depends on how the ConfigMap is used.
Updating a ConfigMap
Use oc edit or oc apply:
# Edit in-place
oc edit configmap app-config
# Or apply updated YAML
oc apply -f app-config.yamlWhen Do Changes Reach Running Pods?
- Used as environment variables:
- Pod environment is set when the pod starts.
- Updating the ConfigMap does not change env vars in existing pods.
- You must restart pods (e.g. trigger a new Deployment rollout) to pick up new values.
- Mounted as files:
- Underlying volumes are updated when the ConfigMap changes.
- Containers may see changes without a restart, but:
- There can be a small delay.
- Your application must be written to detect and reload changed files.
- Some apps only read config at startup, so a restart is still needed.
In OpenShift, a common practice is to trigger a Deployment rollout after a ConfigMap change:
oc rollout restart deployment/my-appThis ensures that pods see the updated configuration even if they use env vars.
ConfigMaps and OpenShift Workflows
ConfigMaps integrate with common OpenShift workflows and features.
ConfigMaps with BuildConfigs and S2I
For Source-to-Image (S2I) builds or regular BuildConfigs, ConfigMaps can be used to:
- Inject build-time configuration (e.g., Maven settings, NPM registries).
- Provide build scripts or templates.
Example (simplified):
apiVersion: build.openshift.io/v1
kind: BuildConfig
metadata:
name: my-app
spec:
source:
type: Git
git:
uri: https://github.com/example/my-app.git
strategy:
type: Source
sourceStrategy:
from:
kind: ImageStreamTag
name: "java:11"
envFrom:
- configMapRef:
name: build-configThis uses a ConfigMap to parameterize the build environment.
ConfigMaps in Templates and Helm Charts
ConfigMaps are frequently used in OpenShift templates (or Helm charts) to:
- Provide default configurations.
- Allow users to override config via parameters.
A template snippet:
parameters:
- name: APP_MODE
value: "production"
objects:
- apiVersion: v1
kind: ConfigMap
metadata:
name: ${NAME}-config
data:
APP_MODE: ${APP_MODE}
Users can supply APP_MODE at template instantiation time, and all workloads referencing ${NAME}-config automatically receive the right value.
Common Patterns
Application Configuration Bundled as a Single File
Some applications expect a single config file. Pattern:
- Store the entire config file as one key in a ConfigMap.
- Mount that key to the correct file path.
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
nginx.conf: |
worker_processes 1;
events { worker_connections 1024; }
http {
server {
listen 8080;
location / {
proxy_pass http://backend;
}
}
}Deployment:
volumes:
- name: nginx-config-volume
configMap:
name: nginx-config
volumeMounts:
- name: nginx-config-volume
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
Using subPath mounts only that key as a single file at the given path.
Using Multiple ConfigMaps
For larger applications, split configuration:
app-config: general app configuration.logging-config: logging-specific config.feature-flags: feature toggles.
Then mount or inject them separately. This allows independent updates and clearer ownership.
Combining ConfigMaps and Secrets
In many real applications, some settings are public and some are sensitive. Pattern:
- Use a ConfigMap for non-sensitive config (URLs, feature toggles, etc.).
- Use a Secret for credentials (passwords, tokens, keys).
- Merge them via
envFromin the pod:
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secretsThis keeps security boundaries clear while giving the application a unified env space.
Best Practices for ConfigMaps
1. Do Not Store Sensitive Data
Even if a value “seems harmless,” if it can be used to escalate access or reveal behavior, it should live in a Secret. In particular:
- API tokens
- Database passwords
- Private keys
- OAuth client secrets
Use ConfigMaps for configuration that could reasonably be checked into a public repository.
2. Keep ConfigMaps Focused and Small
Avoid “god ConfigMaps” with dozens of unrelated keys. Prefer:
- One ConfigMap per application or per concern (e.g. logging, features).
- Logical grouping to minimize blast radius of changes.
3. Version and Document Configuration
In GitOps or declarative workflows:
- Store ConfigMap YAML in version control.
- Add comments (via annotations) describing purpose and ownership.
Example:
metadata:
name: app-config
annotations:
owner: "team-a"
description: "Runtime configuration for frontend service"4. Plan for Config Changes and Rollouts
Especially in production:
- Be explicit about how configuration changes trigger pod restarts.
- Use
oc rollout restartor change a hash annotation to force rollouts when config changes. - Test config changes in non-production projects first.
A common technique is to compute a hash of ConfigMap data and annotate the pod template with it. Any change to the ConfigMap changes the hash, causing a new rollout. (Tools like Helm and Argo CD support this pattern out of the box.)
5. Use Default Values and Overlays
For multi-environment setups (dev/test/prod):
- Define base ConfigMaps with sensible defaults.
- Overlay environment-specific values via separate ConfigMaps or Kustomize overlays.
This avoids duplication and supports consistent configuration management across OpenShift projects.
Inspecting and Troubleshooting ConfigMaps
Inspecting ConfigMaps
Use oc:
# List ConfigMaps in the current project
oc get configmaps
# Show details and data
oc describe configmap app-config
# Show raw YAML
oc get configmap app-config -o yamlIn the web console, use Workloads → ConfigMaps to inspect values visually (not recommended for extremely large data).
Verifying Mounts Inside Pods
If an application isn’t picking up configuration:
- Exec into the pod (if allowed):
oc rsh deploy/my-app- Inspect env vars (if using env):
env | grep APP_- Inspect mounted files:
ls -R /opt/app/config
cat /opt/app/config/application.propertiesIf files or env vars are missing, verify:
- The pod’s
env/envFrom/volumeMounts/volumesdefinitions. - That the ConfigMap exists in the same project and has the right name.
Common Problems
- Name mismatches: Pod references
app-configbut actual ConfigMap isapp-config-v1. - Missing keys: Using
configMapKeyRefwith a non-existent key leads to pod startup failures ifoptional: false(default). - Using ConfigMap for secrets: Correct by moving data to a Secret and updating pod references.
- Expecting env updates without restarts: Remember env vars are fixed for a running container.
Summary
ConfigMaps in OpenShift are a core building block for externalizing non-sensitive configuration:
- Create them via the web console or
ocusing literals, files, or declarative manifests. - Consume them as environment variables, mounted files, or both.
- Combine them with Secrets to separate public configuration from sensitive data.
- Use them in BuildConfigs, templates, Helm charts, and GitOps workflows to keep configuration consistent and portable.
- Plan for how configuration changes propagate to running applications and use rollouts where appropriate.
Understanding these patterns enables flexible, maintainable configuration management across your OpenShift applications.