---
title: "Environment Variables, ConfigMaps & Secrets"
canonical: "https://kb.uconn.edu/space/IKB/28730490941/Environment%20Variables%2C%20ConfigMaps%20%26%20Secrets"
format: markdown
---
Externalizing configuration from your application code is a core Kubernetes principle. OpenShift provides three mechanisms for this: **environment variables**, **ConfigMaps**, and **Secrets**.

---

## Environment Variables

The simplest way to pass configuration to your application.

```shell
# Set environment variables on a deployment
oc set env deployment/my-app \
  DATABASE_HOST=postgres.my-project.svc \
  DATABASE_PORT=5432 \
  APP_ENV=production

# View current environment variables
oc set env deployment/my-app --list

# Remove an environment variable
oc set env deployment/my-app DATABASE_HOST-
```

> **Tip:** Setting env vars triggers a new rollout automatically — your pods will restart with the updated values.

---

## ConfigMaps

ConfigMaps store **non-sensitive** configuration data as key-value pairs. Use them for feature flags, config files, connection strings (without passwords), and application settings.

### Create a ConfigMap

```shell
# From literal key-value pairs
oc create configmap app-config \
  --from-literal=APP_MODE=production \
  --from-literal=LOG_LEVEL=info \
  --from-literal=MAX_CONNECTIONS=100

# From a file
oc create configmap nginx-config --from-file=nginx.conf

# From an env file
oc create configmap app-env --from-env-file=app.env

# View a ConfigMap
oc get configmap app-config -o yaml
```

### Use a ConfigMap as Environment Variables

```shell
# Inject all keys from a ConfigMap as env vars
oc set env deployment/my-app --from=configmap/app-config

# Inject a single key
oc set env deployment/my-app --from=configmap/app-config --keys=LOG_LEVEL
```

### Mount a ConfigMap as a File

```shell
oc set volume deployment/my-app \
  --add --name=config-volume \
  --type=configmap \
  --configmap-name=nginx-config \
  --mount-path=/etc/nginx/conf.d
```

---

## Secrets

Secrets store **sensitive** data such as passwords, API keys, tokens, and certificates. Secrets are base64-encoded (not encrypted by default) but can be configured with encryption at rest.

### Create a Secret

```shell
# From literal values
oc create secret generic db-credentials \
  --from-literal=DB_USER=admin \
  --from-literal=DB_PASSWORD=s3cur3P@ss!

# From a file (e.g., TLS certificate)
oc create secret generic tls-cert \
  --from-file=cert.pem --from-file=key.pem

# View a secret (values are base64-encoded)
oc get secret db-credentials -o yaml
```

### Use a Secret as Environment Variables

```shell
# Inject all keys from a Secret as env vars
oc set env deployment/my-app --from=secret/db-credentials

# Inject a single key with a custom env var name
oc set env deployment/my-app DB_PASSWORD=--from=secret/db-credentials
```

### Mount a Secret as a File

```shell
oc set volume deployment/my-app \
  --add --name=secret-volume \
  --type=secret \
  --secret-name=db-credentials \
  --mount-path=/app/secrets \
  --read-only
```

---

## ConfigMap vs. Secret: When to Use Which

| Data Type | Use | Example |
| --- | --- | --- |
| App settings, feature flags | **ConfigMap** | `LOG_LEVEL=info`, `FEATURE_X=enabled` |
| Connection strings (no passwords) | **ConfigMap** | `DB_HOST=postgres.svc` |
| Database passwords | **Secret** | `DB_PASSWORD=s3cur3P@ss` |
| API keys and tokens | **Secret** | `STRIPE_API_KEY=sk_live_...` |
| TLS certificates | **Secret** | `cert.pem`, `key.pem` |
| Config files (non-sensitive) | **ConfigMap** | `nginx.conf`, `app.yaml` |

---

## Editing Live Configuration

```shell
# Edit a ConfigMap directly
oc edit configmap app-config

# Edit a Secret directly
oc edit secret db-credentials

# After editing, restart pods to pick up changes
oc rollout restart deployment/my-app
```

> **Important:** Changes to mounted ConfigMaps and Secrets are eventually propagated to running pods, but environment variable changes require a rollout restart.

---

## Best Practices

1. **Never hardcode secrets** in your Dockerfile, source code, or Git repository
2. **Use Secrets for all sensitive data** — even if it seems harmless, treat credentials as sensitive
3. **Use descriptive key names** — `DATABASE_URL` is better than `DB`
4. **Separate config per environment** — create different ConfigMaps for dev, staging, and production
5. **Mount sensitive files as read-only** — always use `--read-only` when mounting Secrets as files

---

*UConn ITS Infrastructure Services — OpenShift Knowledge Base*