---
title: Creating and using config maps
---

# Creating and using config maps {#configmaps}

You can review the following sections to learn how to create and use config maps. By using a config map, you can decouple environment-specific configuration from your container images, so that your applications are easily portable.

## Understanding config maps {#nodes-pods-configmap-overview_configmaps}

You can review the following sections to learn how to use config maps to make configuration values available to your pods separately from application code.

Many applications require configuration by using some combination of configuration files, command-line arguments, and environment variables. In OpenShift Container Platform, these configuration artifacts are decoupled from image content to keep containerized applications portable.

The `ConfigMap` object provides mechanisms to inject containers with configuration data while keeping containers agnostic of OpenShift Container Platform. A config map can be used to store fine-grained information like individual properties or coarse-grained information like entire configuration files or JSON blobs.

The `ConfigMap` object holds key-value pairs of configuration data that can be consumed in pods or used to store configuration data for system components such as controllers. For example:

```yaml {title="ConfigMap Object Definition"}
kind: ConfigMap
apiVersion: v1
metadata:
  creationTimestamp: 2016-02-18T19:14:38Z
  name: example-config
  namespace: my-namespace
data:
  example.property.1: hello
  example.property.2: world
  example.property.file: |-
    property.1=value-1
    property.2=value-2
    property.3=value-3
binaryData:
  bar: L3Jvb3QvMTAw
```

where:

`data`
:   Specifies the configuration data.

`binaryData.bar`
:   Specifies a file that contains non-UTF8 data, for example, a binary Java keystore file. Enter the file data in Base 64.

> [!NOTE]
> You can use the `binaryData` field when you create a config map from a binary file, such as an image.

Configuration data can be consumed in pods in a variety of ways. A config map can be used to:

- Populate environment variable values in containers
- Set command-line arguments in a container
- Populate configuration files in a volume

Users and system components can store configuration data in a config map.

A config map is similar to a secret, but designed to more conveniently support working with strings that do not contain sensitive information.

### Config map restrictions {#nodes-pods-configmap-overview-restrictions}

**A config map must be created before its contents can be consumed in pods.**

Controllers can be written to tolerate missing configuration data. Consult individual components configured by using config maps on a case-by-case basis.

**`ConfigMap` objects reside in a project.**

They can only be referenced by pods in the same project.

**The Kubelet only supports the use of a config map for pods it gets from the API server.**

This includes any pods created by using the CLI, or indirectly from a replication controller. It does not include pods created by using the OpenShift Container Platform node’s `--manifest-url` flag, its `--config` flag, or its REST API because these are not common ways to create pods.

## Creating a config map in the OpenShift Container Platform web console {#nodes-pods-configmap-create-from-console_configmaps}

To provide configuration data to your pods, you can create a config map by using the OpenShift Container Platform web console. You can use config maps to define key-value pairs that contain information for your applications.

**Procedure**

- To create a config map as a cluster administrator:

  1. In the Administrator perspective, select `Workloads` → `Config Maps`.
  2. At the top right side of the page, select **Create Config Map**.
  3. Enter the contents of your config map.
  4. Select **Create**.
- To create a config map as a developer:

  1. In the Developer perspective, select `Config Maps`.
  2. At the top right side of the page, select **Create Config Map**.
  3. Enter the contents of your config map.
  4. Select **Create**.

## Creating a config map by using the CLI {#nodes-pods-configmap-create_configmaps}

To provide configuration data to your pods, you can use the OpenShift CLI (`oc`) to create a config map from directories, specific files, or literal values.

**Procedure**

- Create a config map:

  ```terminal
  $ oc create configmap <configmap_name> [options]
  ```

### Creating a config map from a directory {#nodes-pods-configmap-creating-from-directories_configmaps}

You can create a config map from a directory by using the `--from-file` flag. By creating the config map from a directory, you can include multiple files from that directory in the config map with one command.

Each file in the directory is used to populate a key in the config map, where the name of the key is the file name, and the value of the key is the content of the file.

For example, the following command creates a config map with the contents of the `example-files` directory:

```terminal
$ oc create configmap game-config --from-file=example-files/
```

View the keys in the config map:

```terminal
$ oc describe configmaps game-config
```

The output is similar to the following example:

```terminal
Name:           game-config
Namespace:      default
Labels:         <none>
Annotations:    <none>

Data

game.properties:        158 bytes
ui.properties:          83 bytes
```

You can see that the two keys in the map are created from the file names in the directory specified in the command. The content of those keys might be large, so the output of `oc describe` only shows the names of the keys and their sizes.

**Prerequisite**

- You must have a directory with files that contain the data you want to populate a config map with.

  The following procedure uses these example files: `game.properties` and `ui.properties`:

  ```terminal
  $ cat example-files/game.properties
  ```

  ```terminal {title="Example output"}
  enemies=aliens
  lives=3
  enemies.cheat=true
  enemies.cheat.level=noGoodRotten
  secret.code.passphrase=UUDDLRLRBABAS
  secret.code.allowed=true
  secret.code.lives=30
  ```

  ```terminal
  $ cat example-files/ui.properties
  ```

  ```terminal {title="Example output"}
  color.good=purple
  color.bad=yellow
  allow.textmode=true
  how.nice.to.look=fairlyNice
  ```

**Procedure**

- Create a config map holding the content of each file in this directory by entering the following command:

  ```terminal
  $ oc create configmap game-config \
      --from-file=example-files/
  ```

**Verification**

- Enter the `oc get` command for the object with the `-o` option to see the values of the keys:

  ```terminal
  $ oc get configmaps game-config -o yaml
  ```

  ```yaml {title="Example output"}
  apiVersion: v1
  data:
    game.properties: |-
      enemies=aliens
      lives=3
      enemies.cheat=true
      enemies.cheat.level=noGoodRotten
      secret.code.passphrase=UUDDLRLRBABAS
      secret.code.allowed=true
      secret.code.lives=30
    ui.properties: |
      color.good=purple
      color.bad=yellow
      allow.textmode=true
      how.nice.to.look=fairlyNice
  kind: ConfigMap
  metadata:
    creationTimestamp: 2016-02-18T18:34:05Z
    name: game-config
    namespace: default
    resourceVersion: "407"
    selflink: /api/v1/namespaces/default/configmaps/game-config
    uid: 30944725-d66e-11e5-8cd0-68f728db1985
  ```

### Creating a config map from a file {#nodes-pods-configmap-creating-from-files_configmaps}

You can create a config map from a file, which you can use to quickly add multiple `key=value` pairs for applications to read.

You can also specify the key to set in a config map for content imported from a file by passing a `key=value` expression to the `--from-file` option. For example:

```terminal
$ oc create configmap game-config-3 --from-file=game-special-key=example-files/game.properties
```

You can pass the `--from-file` option multiple times to the CLI.

> [!NOTE]
> If you create a config map from a file, you can include files containing non-UTF8 data that are placed in this field without corrupting the non-UTF8 data. OpenShift Container Platform detects binary files and transparently encodes the file as `MIME`. On the server, the `MIME` payload is decoded and stored without corrupting the data.

**Prerequisite**

- You must have a directory with files that contain the data you want to populate a config map with.

  The following procedure uses these example files: `game.properties` and `ui.properties`:

  ```terminal
  $ cat example-files/game.properties
  ```

  ```terminal {title="Example output"}
  enemies=aliens
  lives=3
  enemies.cheat=true
  enemies.cheat.level=noGoodRotten
  secret.code.passphrase=UUDDLRLRBABAS
  secret.code.allowed=true
  secret.code.lives=30
  ```

  ```terminal
  $ cat example-files/ui.properties
  ```

  ```terminal {title="Example output"}
  color.good=purple
  color.bad=yellow
  allow.textmode=true
  how.nice.to.look=fairlyNice
  ```

**Procedure**

- Create a config map by specifying a specific file:

  ```terminal
  $ oc create configmap game-config-2 \
      --from-file=example-files/game.properties \
      --from-file=example-files/ui.properties
  ```
- Create a config map by specifying a key-value pair:

  ```terminal
  $ oc create configmap game-config-3 \
      --from-file=game-special-key=example-files/game.properties
  ```

**Verification**

- Enter the `oc get` command for the object with the `-o` option to see the values of the keys from the file:

  ```terminal
  $ oc get configmaps game-config-2 -o yaml
  ```

  ```yaml {title="Example output"}
  apiVersion: v1
  data:
    game.properties: |-
      enemies=aliens
      lives=3
      enemies.cheat=true
      enemies.cheat.level=noGoodRotten
      secret.code.passphrase=UUDDLRLRBABAS
      secret.code.allowed=true
      secret.code.lives=30
    ui.properties: |
      color.good=purple
      color.bad=yellow
      allow.textmode=true
      how.nice.to.look=fairlyNice
  kind: ConfigMap
  metadata:
    creationTimestamp: 2016-02-18T18:52:05Z
    name: game-config-2
    namespace: default
    resourceVersion: "516"
    selflink: /api/v1/namespaces/default/configmaps/game-config-2
    uid: b4952dc3-d670-11e5-8cd0-68f728db1985
  ```
- Enter the `oc get` command for the object with the `-o` option to see the values of the keys from the key-value pair:

  ```terminal
  $ oc get configmaps game-config-3 -o yaml
  ```

  ```yaml {title="Example output"}
  apiVersion: v1
  data:
    game-special-key: |-
      enemies=aliens
      lives=3
      enemies.cheat=true
      enemies.cheat.level=noGoodRotten
      secret.code.passphrase=UUDDLRLRBABAS
      secret.code.allowed=true
      secret.code.lives=30
  kind: ConfigMap
  metadata:
    creationTimestamp: 2016-02-18T18:54:22Z
    name: game-config-3
    namespace: default
    resourceVersion: "530"
    selflink: /api/v1/namespaces/default/configmaps/game-config-3
    uid: 05f8da22-d671-11e5-8cd0-68f728db1985
  ```

  You set the `game-special-key` key in the preceding step.

### Creating a config map from literal values {#nodes-pods-configmap-creating-from-literal-values_configmaps}

You can create a config map by passing literal values in the `key=value` syntax, which allows literal values to be supplied directly on the command line.

**Procedure**

- Create a config map by specifying a literal value:

  ```terminal
  $ oc create configmap special-config \
      --from-literal=special.how=very \
      --from-literal=special.type=charm
  ```

**Verification**

- Enter the `oc get` command for the object with the `-o` option to see the values of the keys:

  ```terminal
  $ oc get configmaps special-config -o yaml
  ```

  ```yaml {title="Example output"}
  apiVersion: v1
  data:
    special.how: very
    special.type: charm
  kind: ConfigMap
  metadata:
    creationTimestamp: 2016-02-18T19:14:38Z
    name: special-config
    namespace: default
    resourceVersion: "651"
    selflink: /api/v1/namespaces/default/configmaps/special-config
    uid: dadce046-d673-11e5-8cd0-68f728db1985
  ```

### Populating environment variables in containers by using config maps {#nodes-pods-configmaps-use-case-consuming-in-env-vars_configmaps}

You can use config maps to populate individual environment variables in containers or to populate environment variables in containers from all keys that form valid environment variable names.

The following example `ConfigMap` custom resource (CR) contains two environment variables:

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  special.how: very
  special.type: charm
```

where:

`metadata.name`
:   Specifies the name of the config map.

`metadata.namespace`
:   Specifies the project in which the config map resides. Config maps can only be referenced by pods in the same project.

`data`
:   Specifies the environment variables to inject.

The following example `ConfigMap` (CR) contains one environment variable:

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: env-config
  namespace: default
data:
  log_level: INFO
```

where:

`metadata.name`
:   Specifies the name of the config map.

`metadata.namespace`
:   Specifies the project in which the config map resides. Config maps can only be referenced by pods in the same project.

`data`
:   Specifies the environment variables to inject.

**Procedure**

- You can consume the keys of this `ConfigMap` in a pod using `configMapKeyRef` sections.

  ```yaml {title="Sample Pod specification configured to inject specific environment variables"}
  apiVersion: v1
  kind: Pod
  metadata:
    name: dapi-test-pod
  spec:
    securityContext:
      runAsNonRoot: true
      seccompProfile:
        type: RuntimeDefault
    containers:
      - name: test-container
        image: gcr.io/google_containers/busybox
        command: [ "/bin/sh", "-c", "env" ]
        env:
          - name: SPECIAL_LEVEL_KEY
            valueFrom:
              configMapKeyRef:
                name: special-config
                key: special.how
          - name: SPECIAL_TYPE_KEY
            valueFrom:
              configMapKeyRef:
                name: special-config
                key: special.type
                optional: true
        envFrom:
          - configMapRef:
              name: env-config
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop: [ALL]
    restartPolicy: Never
  ```

  where:

  `spec.containers.env`
  :   Specifies the environment variables to pull from a config map.

  `spec.containers.env.name`
  :   Specifies the name of a pod environment variable that you are injecting a key’s value into.

  `spec.containers.env.valueFrom.configMapKeyRef.name`
  :   Specifies the name of the config map to pull specific environment variables from.

  `spec.containers.env.valueFrom.configMapKeyRef.key`
  :   Specifies the environment variable to pull from the config map.

  `spec.containers.env.valueFrom.configMapKeyRef.optional`
  :   Specifies that the environment variable is optional. As optional, the pod will be started even if the specified config map and keys do not exist.

  `spec.containers.envFrom.configMapRef`
  :   Specifies the name of the config map to pull all environment variables from.

  When this pod is run, the pod logs will include the following output:

  ```
  SPECIAL_LEVEL_KEY=very
  log_level=INFO
  ```

  > [!NOTE]
  > `SPECIAL_TYPE_KEY=charm` is not listed in the example output because `optional: true` is set.

### Setting command-line arguments for container commands with config maps {#nodes-pods-configmaps-use-case-setting-command-line-arguments_configmaps}

You can use config maps to set the value of the commands or arguments in a container by using the Kubernetes substitution syntax `$(VAR_NAME)`.

As an example, consider the following config map:

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  special.how: very
  special.type: charm
```

**Procedure**

- To inject values into a command in a container, you must consume the keys you want to use as environment variables. Then you can refer to them in a container’s command using the `$(VAR_NAME)` syntax.

  ```yaml {title="Sample pod specification configured to inject specific environment variables"}
  apiVersion: v1
  kind: Pod
  metadata:
    name: dapi-test-pod
  spec:
    securityContext:
      runAsNonRoot: true
      seccompProfile:
        type: RuntimeDefault
    containers:
      - name: test-container
        image: gcr.io/google_containers/busybox
        command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ]
        env:
          - name: SPECIAL_LEVEL_KEY
            valueFrom:
              configMapKeyRef:
                name: special-config
                key: special.how
          - name: SPECIAL_TYPE_KEY
            valueFrom:
              configMapKeyRef:
                name: special-config
                key: special.type
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop: [ALL]
    restartPolicy: Never
  ```

  where:

  `spec.containers.command`
  :   Specifies values to inject into a command in a container by using the keys you want to use as environment variables.

  When this pod is run, the output from the echo command run in the test-container container is as follows:

  ```
  very charm
  ```

### Injecting content into a volume by using config maps {#nodes-pods-configmaps-use-case-consuming-in-volumes_configmaps}

You can use config maps to inject content into a volume.

The following example `ConfigMap` custom resource (CR) contains two environment variables:

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  special.how: very
  special.type: charm
```

The following procedure describes options for injecting content into a volume by using config maps.

**Procedure**

- The most basic way to inject content into a volume by using a config map is to populate the volume with files where the key is the file name and the content of the file is the value of the key:

  ```yaml
  apiVersion: v1
  kind: Pod
  metadata:
    name: dapi-test-pod
  spec:
    securityContext:
      runAsNonRoot: true
      seccompProfile:
        type: RuntimeDefault
    containers:
      - name: test-container
        image: gcr.io/google_containers/busybox
        command: [ "/bin/sh", "-c", "cat", "/etc/config/special.how" ]
        volumeMounts:
        - name: config-volume
          mountPath: /etc/config
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop: [ALL]
    volumes:
      - name: config-volume
        configMap:
          name: special-config
    restartPolicy: Never
  ```

  where:

  `spec.volumes.configMap.name`
  :   Specifies a file containing key. When this pod is run, the output of the cat command will be:

  ```
  very
  ```
- You can also control the paths within the volume where config map keys are projected:

  ```yaml
  apiVersion: v1
  kind: Pod
  metadata:
    name: dapi-test-pod
  spec:
    securityContext:
      runAsNonRoot: true
      seccompProfile:
        type: RuntimeDefault
    containers:
      - name: test-container
        image: gcr.io/google_containers/busybox
        command: [ "/bin/sh", "-c", "cat", "/etc/config/path/to/special-key" ]
        volumeMounts:
        - name: config-volume
          mountPath: /etc/config
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop: [ALL]
    volumes:
      - name: config-volume
        configMap:
          name: special-config
          items:
          - key: special.how
            path: path/to/special-key
    restartPolicy: Never
  ```

  where:

  `spec.volumes.configMap.items.path`
  :   Specifies the path to config map key.

  When this pod is run, the output of the cat command is `very`.
