# 13: Kubernetes Secrets and ConfigMaps: A Complete Guide with Examples

In this blog, we'll explore **Kubernetes Secrets** and **ConfigMaps**, their purpose, differences, and how to use them effectively with examples. We'll also clarify any misconceptions and highlight best practices.

---

## What Are Kubernetes Secrets?

**Secrets** in Kubernetes are used to store sensitive and confidential information such as passwords, API keys, and SSH keys. They prevent sensitive data from being hardcoded into your application or configuration files.

### Key Characteristics:

* **Encoded, not encrypted**: Secrets are base64-encoded, not encrypted by default. While encoding helps obfuscate data, it doesn't protect it from being exposed.
    
* **Data in etcd**: By default, secrets are stored in etcd as plaintext, meaning data at rest isn't encrypted unless you enable encryption at the etcd layer.
    

### Examples of Sensitive Data for Secrets:

* SSH keys
    
* Database usernames and passwords
    
* API tokens
    

#### Difference Between Encoding and Encryption:

* **Encoding**: Transforms data into a different format (e.g., base64) for transmission or storage but is reversible without a key.
    
* **Encryption**: Secures data using algorithms and requires a key to decrypt.
    

---

### Creating and Using Secrets

Secrets can be created using **imperative** or **declarative** methods.

#### 1\. **Imperative Method**

```plaintext
kubectl create secret generic my-secret \
  --from-literal=username=admin \
  --from-literal=password=secret123
```

#### 2\. **Declarative Method (YAML)**

Define a `Secret` in a YAML file:

```plaintext
apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
data:
  username: YWRtaW4= # Base64-encoded value of 'admin'
  password: c2VjcmV0MTIz # Base64-encoded value of 'secret123'
```

Apply the configuration:

```plaintext
kubectl apply -f secret.yaml
```

#### Using Secrets in a Deployment

```plaintext
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: nginx
        env:
        - name: DB_USERNAME
          valueFrom:
            secretKeyRef:
              name: my-secret
              key: username
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: my-secret
              key: password
```

---

## What Are ConfigMaps?

**ConfigMaps** store non-sensitive data in key-value pairs or configuration files. They allow you to decouple configuration details from your application code.

### Key Use Cases:

* Application configuration files (e.g., `httpd.conf` for Apache).
    
* Environment-specific variables to control application behavior.
    

### Creating and Using ConfigMaps

#### 1\. **Imperative Method**

```plaintext
kubectl create configmap devapache --from-file=httpd.conf
```

#### 2\. **Declarative Method (YAML)**

Define a `ConfigMap` in a YAML file:

```plaintext
apiVersion: v1
kind: ConfigMap
metadata:
  name: devapache
data:
  httpd.conf: |
    ServerName localhost
    Listen 8080
```

#### Using ConfigMaps in a Deployment

```plaintext
apiVersion: apps/v1
kind: Deployment
metadata:
  name: apache-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: apache-app
  template:
    metadata:
      labels:
        app: apache-app
    spec:
      containers:
      - name: apache-container
        image: httpd
        volumeMounts:
        - name: config-volume
          mountPath: /usr/local/apache2/conf
          subPath: httpd.conf
      volumes:
      - name: config-volume
        configMap:
          name: devapache
```

**Important Note**: In the `volumeMounts` section:

* Use the **directory name** (not the filename) in the `mountPath` where the ConfigMap data should be placed inside the container.
    

---

## Comparison: Secrets vs. ConfigMaps

| Feature | Secrets | ConfigMaps |
| --- | --- | --- |
| **Purpose** | Store sensitive data | Store non-sensitive configuration |
| **Data Encoding** | Base64-encoded | Plaintext |
| **Use Case** | API keys, passwords, credentials | Configuration files, environment variables |
| **Storage** | etcd (plaintext by default) | etcd (plaintext) |

---

## Conclusion

Secrets and ConfigMaps are essential tools for managing configuration and sensitive data in Kubernetes. While Secrets provide an additional layer of security through obfuscation, ConfigMaps allow seamless application configuration. Remember to:

1. Enable encryption at rest for etcd to secure Secrets.
    
2. Avoid embedding sensitive data directly into YAML files.
    
3. Use declarative approaches for better version control.
    

By combining these resources effectively, you can build a secure and configurable Kubernetes-based application.
