Join experts to dive deep into IaC security and governance on August 27

➡️ Register for IaCConf

Kubernetes

Kubernetes ConfigMap – What It Is, How to Use & Examples

kubernetes configmap

🚀 Level Up Your Infrastructure Skills

You focus on building. We’ll keep you updated. Get curated infrastructure insights that help you make smarter decisions.

ConfigMaps store config data that can be used by your Pods. A ConfigMap is a Kubernetes API object that contains one or more key-value pairs.

In this article, we’ll provide a complete guide to Kubernetes ConfigMaps. You’ll learn what they are, how to create them, and the ways in which they can be used with Pods.

We will cover:

  1. What are Kubernetes ConfigMaps?
  2. Where are ConfigMaps stored in Kubernetes?
  3. How to use Kubernetes ConfigMaps – Examples
  4. Understanding ConfigMap updates
  5. How to set Sensitive Config values?
  6. ConfigMap limitations

What are Kubernetes ConfigMaps?

Kubernetes ConfigMaps are built-in Kubernetes API objects that store your application’s non-sensitive key-value config data. ConfigMaps allow you to keep config values separate from your code and container images. Values can be strings or Base64-encoded binary data.

Once you’ve created a ConfigMap, its content will be saved to your Kubernetes cluster. Pods can then consume the ConfigMap’s values as environment variables, command line arguments, or filesystem volumes.

ConfigMaps are intended to store relatively small amounts of simple data. The total size of a ConfigMap object must be less than 1 MiB. If you need to store more data, you should split your configuration into multiple ConfigMaps or consider using a separate database or key-value store.

It’s good practice to use a ConfigMap to supply any configurable values that your app needs at runtime. The key-value pairs within the ConfigMap can be injected directly into your Pods in several different formats. Because ConfigMaps are part of the Kubernetes API, it’s possible to alter their values without re-deploying your app’s Pods.

What is a Kubernetes ConfigMap used for?

A Kubernetes ConfigMap is used to provide configuration values to applications in a way that is decoupled from the application code. It allows you to externalize environment-specific settings, such as a database hostname or IP address, without modifying the container image.

ConfigMaps are ideal when application deployments require settings that may change independently of code updates. For example, a system that connects to a database can retrieve the database server address from a ConfigMap instead of hardcoding it. 

ConfigMaps also support pre-configuration: users can create them before deploying an app, customizing behavior without altering the deployment process.

Applications should be designed to read configuration from the environment or filesystem so they can seamlessly use ConfigMap values in Kubernetes or environment variables in local development. This approach improves portability and simplifies multi-environment deployments.

Read more: How to Set up and Manage Kubernetes Environment Variables

Where are ConfigMaps stored in Kubernetes?

Kubernetes stores ConfigMaps in its etcd datastore. You shouldn’t directly edit etcd data; instead, use the Kubernetes API server and Kubectl to create and manage your ConfigMaps.

To back up ConfigMap values, follow the guidance to set up backups for etcd. These backups will contain a complete copy of your cluster’s data.

Check out other best practices for Kubernetes security.

How to use Kubernetes ConfigMaps - Examples

Because ConfigMaps are regular Kubernetes API objects, you can create them using YAML Kubernetes manifests files.

They require a top-level data field that defines the key-value config pairs to store. Keys can only contain alphanumeric characters and the ., -, and _ symbols.

The following ConfigMap stores three properties: database_host, debug_mode, and log_level:

apiVersion: v1
kind: ConfigMap
metadata:
  name: demo-config
data:
  database_host: "192.168.0.1"
  debug_mode: "1"
  log_level: "verbose"

Save the manifest to demo-config.yaml, then use Kubectl to apply it to your cluster and create the ConfigMap object:

$ kubectl apply -f demo-config.yaml
configmap/demo-config created

Example 1: Using data and binaryData fields

When you use the data field, your ConfigMap values must be strings. ConfigMaps also support binary data within separate binaryData field.

Binary values need to be Base64-encoded:

apiVersion: v1
kind: ConfigMap
metadata:
  name: demo-config
binaryData:
  file_template: RGVtbwo=

You can use both data and binaryData in a single ConfigMap, but each key can only appear once—either in data or in binaryData.

Example 2: Listing and inspecting ConfigMaps

You can list the ConfigMaps you’ve created by running the kubectl get command:

$ kubectl get configmaps
NAME               DATA   AGE
demo-config        3      83m

To inspect the key-value pairs within a ConfigMap, use kubectl describe:

$ kubectl describe configmap demo-config
Name:         demo-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
database_host:
----
192.168.0.1
debug_mode:
----
1
log_level:
----
verbose

BinaryData
====

Events:  <none>

The ConfigMap’s content is visible under the Data and BinaryData headings.

Getting a ConfigMap’s Content as JSON

The following command will produce a JSON object that contains the ConfigMap’s key-value pairs:

$ kubectl get configmap demo-config -o jsonpath='{.data}' | jq
{
  "database_host": "192.168.0.1",
  "debug_mode": "1",
  "log_level": "verbose"
}

This can be a more convenient way to inspect ConfigMaps and export their content into files.

Example 3: Mounting ConfigMaps into Pods as environment variables

Once you’ve created a ConfigMap, you can consume it within your Pods. You can access all or part of a ConfigMap as environment variables, command line arguments, or mounted files.

Environment variables are familiar, easy to consume in code, and open to easy inspection. They’re a good way to supply a small number of simple values to your application.

The following Pod (demo-pod.yaml) makes the content of the demo-config ConfigMap available as environment variables:

apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
spec:
  containers:
    - name: app
      command: ["/bin/sh", "-c", "printenv"]
      image: busybox:latest
      envFrom:
        - configMapRef:
            name: demo-config

The envFrom field instructs Kubernetes to create environment variables from the sources nested within it. The configMapRef refers to a ConfigMap by its name and selects all its key-value pairs.

Add the Pod to your cluster, then retrieve its logs to see the output from the printenv command. This should confirm that the three key-value pairs from the ConfigMap have been set as environment variables:

$ kubectl apply -f demo-pod.yaml
pod/demo-pod created

$ kubectl logs pod/demo-pod
...
database_host=192.168.0.1
debug_mode=1
log_level=verbose
...

Sometimes a Pod won’t require access to all the values contained in a ConfigMap. For example, you could have another Pod which only utilizes the log_level value from our demo ConfigMap.

The env.valueFrom syntax can be used instead of envFrom for this use case. It lets you select individual keys in a ConfigMap. Keys can also be renamed to different environment variables:

apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
spec:
  containers:
    - name: app
      command: ["/bin/sh", "-c", "printenv"]
      image: busybox:latest
      env:
        - name: logging_mode
          valueFrom:
            configMapKeyRef:
              name: demo-config
              key: log_level

If you add this Pod to your cluster, you’ll see that only logging_mode is set as an environment variable. It has the value of the log_level key from the ConfigMap.

$ kubectl logs pod/demo-pod
...
logging_mode=verbose
...

Example 4: Mounting ConfigMaps into Pods as command line arguments

ConfigMap values can be interpolated into a container’s command line arguments by first referencing the relevant ConfigMap key as an environment variable:

apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
spec:
  containers:
    - name: app
      command: ["demo-app", "--database-host", "$(DATABASE_HOST)"]
      image: demo-app:latest
      env:
        - name: DATABASE_HOST
          valueFrom:
            configMapKeyRef:
              name: demo-config
              key: database_host

This technique allows you to change the command that’s run when your containers start, based on the current content of your ConfigMap. It supports scenarios where your app expects configuration to be supplied directly to its process upon startup.

Example 5: Mounting ConfigMaps into Pods as volumes

Environment variables and command line arguments can become unwieldy when you have many different values, or values containing a large amount of data. ConfigMaps can be mounted as volumes instead, allowing your app to read its config values from files within the container’s filesystem.

To set up a volume mount, add an entry to your Pod manifest’s spec.volumes field that uses a configMap entry to reference your ConfigMap by name. Then, use the volumeMounts field to mount the volume to a read-only path in the container. The following manifest mounts the content of the demo-config ConfigMap to /etc/app-config:

apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
spec:
  containers:
    - name: app
      command: ["ls", "/etc/app-config"]
      image: demo-app:latest
      volumeMounts:
        - name: config
          mountPath: "/etc/app-config"
          readOnly: true
  volumes:
    - name: config
      configMap:
        name: demo-config

Apply this Pod to your cluster, then check its log output:

$ kubectl apply -f demo-pod.yaml
pod/demo-pod created

$ kubectl logs pod/demo-pod
database_host
debug_mode
log_level

The logs show the output from the ls /etc/app-config command that the container is configured to run. The command confirms there are three files within the directory, corresponding to the keys in the ConfigMap. You should configure your app to read these files when it needs to access a config value.

Example 6: Using Immutable ConfigMaps

The ConfigMaps we’ve created so far have been mutable — you can modify them at any time by adding, changing, and removing keys. In practice, many apps are configured once, then expected to stay in the same configuration throughout their lifetime.

ConfigMaps can be marked as immutable to facilitate this use case. An immutable ConfigMap cannot be edited and you’ll see an error if you try to apply changes. This enhances safety by preventing accidental modification or deletion of ConfigMap keys that your app depends on.

To create an immutable ConfigMap, set its immutable manifest property to true:

apiVersion: v1
kind: ConfigMap
metadata:
  name: demo-config-immutable
data:
  foo: bar
immutable: true

Save the example manifest to demo-config-immutable.yaml, then add it to your cluster:

$ kubectl apply -f demo-config-immutable.yaml
configmap/demo-config-immutable created

Now try changing the ConfigMap, such as by changing foo from bar to baz:

data:
  foo: baz

When you reapply the manifest, you’ll see a Forbidden error because the immutable ConfigMap doesn’t permit modifications:

$ kubectl apply -f demo-config-immutable.yaml
The ConfigMap "demo-config-immutable" is invalid: data: Forbidden: field is immutable when `immutable` is set

Understanding ConfigMap updates

The most common pitfall when updating ConfigMaps is assuming changes apply live to running pods without restarting them, which can lead to stale configurations or unexpected behavior.

Kubernetes does not automatically reload ConfigMap changes into running pods.

You can use Kubectl or the Kubernetes API to change mutable ConfigMaps. However, modifications won’t necessarily affect existing Pods, depending on how you’ve consumed the ConfigMap:

  • ConfigMaps consumed as environment variables or command line arguments will not update. Containers must restart to receive new environment variables and command line arguments. Consequently, containers consuming ConfigMaps using these methods won’t receive new values until they’re restarted.
  • ConfigMaps consumed as volumes will automatically apply updates. Pods that mount a ConfigMap as a volume will receive the new ConfigMap’s values, but the change won’t be instantaneous. The Kubelet worker process running on your cluster’s Nodes periodically checks for ConfigMap changes and updates the content of the files mounted into your Pods.

Immutable ConfigMaps are never updated — it’s impossible for them to change. As a result, they provide a performance advantage because worker Nodes can skip calling the API server to check for updates.

How to set sensitive config values

ConfigMaps are only suitable for values that aren’t sensitive or confidential. Data isn’t encrypted so it could be retrieved by anyone who gains access to your cluster’s etcd datastore.

What is the difference between ConfigMaps and secrets?

Kubernetes Secrets are an alternative to ConfigMaps that can be used to save confidential values with encryption support. Most real-world applications will therefore use a combination of ConfigMaps and Secrets when deploying to Kubernetes.

Values such as passwords, API keys, tokens, and certificates should be stored in a Kubernetes Secret instead. Secrets function similarly to ConfigMaps but are encrypted at rest, ensuring that your sensitive values are protected.

In summary, non-sensitive values such as DATABASE_HOST should be added to ConfigMaps; valuable ones like DATABASE_PASSWORD belong in a Secret.

ConfigMap limitations

A ConfigMap in Kubernetes has several key limitations, particularly around size, data types, mounting, and versioning.

  • Size limits: The total size of a ConfigMap, including all keys and values, is limited to 1 MiB. This limit is enforced because ConfigMaps are stored in etcd, which has performance and stability constraints. An excessive size or number of ConfigMaps can lead to etcd degradation.
  • Data type restrictions: ConfigMaps store only string data as key-value pairs. If you need to store structured or non-string data types (e.g., JSON, integers, booleans), they must be manually serialized to strings.
  • Mounting limits: When mounted as volumes, each key is presented as a separate file in the container’s filesystem. This approach is subject to filesystem limitations such as inode count, maximum filename length, and directory path length.
  • Versioning and updates: ConfigMaps do not support versioning or automatic change propagation. Changes do not automatically update environment variables or files inside running pods. For mounted volumes, changes might be reflected depending on runtime behavior, but applications must explicitly reload them. For environment variables, a pod restart is required.

Managing Kubernetes with Spacelift

If you need help managing your Kubernetes projects, consider Spacelift. It brings with it a GitOps flow, so your Kubernetes Deployments are synced with your Kubernetes Stacks, and pull requests show you a preview of what they’re planning to change. 

With Spacelift, you get:

  • Policies to control what kind of resources engineers can create, what parameters they can have, how many approvals you need for a run, what kind of task you execute, what happens when a pull request is open, and where to send your notifications
  • Stack dependencies to build multi-infrastructure automation workflows with dependencies, having the ability to build a workflow that can combine Terraform with Kubernetes, Ansible, and other infrastructure-as-code (IaC) tools such as OpenTofu, Pulumi, and CloudFormation.
  • Self-service infrastructure via Blueprints, enabling your developers to do what matters – developing application code while not sacrificing control
  • Creature comforts such as contexts (reusable containers for your environment variables, files, and hooks), and the ability to run arbitrary code
  • Drift detection and optional remediation

If you want to learn more about Spacelift, create a free account today or book a demo with one of our engineers.

Key points

Kubernetes ConfigMaps are Kubernetes resources that store arbitrary key-value data required by your application. Once you’ve created a ConfigMap, you can mount its values into your Pods as environment variables or volumes.

ConfigMaps are stored in plain text, so you should not use them for sensitive values, including passwords and API keys. Kubernetes Secrets are an alternative to ConfigMaps that can be used to save confidential values with encryption support. Most real-world applications will, therefore, use a combination of ConfigMaps and Secrets when deploying to Kubernetes.

Frequently asked questions

When to use ConfigMaps?

Use ConfigMaps when you need to inject non-sensitive configuration data into Kubernetes pods, such as environment variables, command-line arguments, or config files. They’re best for decoupling application code from environment-specific settings like log levels, feature flags, or service URLs.

Does Kubernetes still use etcd?

Kubernetes still uses etcd as its default backing store for all cluster data. etcd stores configuration details, state information, and metadata about the cluster, including node status, secrets, service definitions, and control plane settings. It is a core component of the Kubernetes control plane and is required for cluster operation.

What is the difference between etcd and ConfigMap?

The key difference is that etcd is a distributed key-value store, while a ConfigMap is a Kubernetes resource used to pass configuration data to pods. ConfigMaps are stored in etcd, but serve a distinct purpose in Kubernetes.

etcd is the backend data store for the Kubernetes control plane. It holds all cluster state, including API objects like ConfigMaps, Secrets, and node data. etcd is designed for consistency and high availability in distributed systems.

How big can a ConfigMap be?

A single Kubernetes ConfigMap is limited to 1 MiB (1,048,576 bytes) in size. This limit applies to the entire object, including metadata and all key-value pairs stored in it.

This constraint exists because ConfigMaps are stored in etcd, with a default request size limit of 1 MiB. Exceeding this limit will cause the ConfigMap creation or update to fail.

Manage Kubernetes easier and faster

Spacelift allows you to automate, audit, secure, and continuously deliver your infrastructure. It helps overcome common state management issues and adds several must-have features for infrastructure management.

Start free trial

Kubernetes Commands Cheat Sheet

Grab our ultimate cheat sheet PDF

for all the kubectl commands you need.

k8s book
Share your data and download the cheat sheet