Update Your Kubernetes App Configuration Dynamically using ConfigMap
Published: 2023-06-23 05:47:18

[ConfigMap](https://kubernetes.io/docs/concepts/configuration/configmap/) is a Kubernetes resource that allows you to store configuration data separately from your application code. It provides a way to decouple configuration settings from the application itself, making it easier to manage and update configurations without modifying the application's code or container images.

A ConfigMap is typically used to store key-value pairs or configuration files. It can be created either through a declarative approach using YAML files or via the Kubernetes API. Once created, the ConfigMap can be mounted as a volume or exposed as environment variables within a containerized application.

## When to do use ConfigMaps?

ConfigMaps are particularly useful when you have multiple instances of the same application running in a Kubernetes cluster but with different configuration requirements. By using ConfigMaps, you can centralize the configuration data and dynamically update it without redeploying the application.

With ConfigMaps, you can easily modify the configuration settings of your application, such as database connection strings, API endpoints, feature toggles, or any other configuration parameter, without the need to rebuild or redeploy the application. This flexibility simplifies the management of application configurations in a dynamic and scalable environment like Kubernetes.

## Configuring Nginx App with a Dynamic value in Kubernetes

To configure Nginx with a dynamic value in a Kubernetes environment using ConfigMap, you can follow these steps:

## Step 1: Create a ConfigMap

Create a ConfigMap to store your Nginx configuration. You can do this by creating a YAML file, let's call it nginx-config.yaml, with the following content:

```
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  nginx.conf: |
    server {
      listen 80;
      server_name example.com;
      root /usr/share/nginx/html;
      index index.html;

      # Add your dynamic configuration here using the $variable_name syntax
      # Example: access_log /var/log/nginx/access.log $log_format;
    }
```

In this example, we are creating a ConfigMap named nginx-config and defining the Nginx configuration within the nginx.conf key.

## Step 2: Deploy Nginx with the ConfigMap

Create a deployment YAML file, let's call it nginx-deployment.yaml, to deploy Nginx and mount the ConfigMap as a volume. Modify the file with your desired specifications:

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80
          volumeMounts:
            - name: nginx-config
              mountPath: /etc/nginx/conf.d/default.conf
              subPath: nginx.conf
      volumes:
        - name: nginx-config
          configMap:
            name: nginx-config
```

In this example, we are creating a Deployment named nginx-deployment with one replica. The Nginx container is configured to mount the ConfigMap as a volume at the path /etc/nginx/conf.d/default.conf.

## Step 3: Apply the ConfigMap and Deployment

Apply the ConfigMap and Deployment using the kubectl apply command:

```
kubectl apply -f nginx-config.yaml
kubectl apply -f nginx-deployment.yaml
```

This will create the ConfigMap and deploy Nginx with the specified configuration.

## Step 4: Dynamic Value Usage

To use a dynamic value within the Nginx configuration, you can define the value as an environment variable in the Deployment specification. Modify the nginx-deployment.yaml file as follows:

```
spec:
  containers:
    - name: nginx
      image: nginx:latest
      ports:
        - containerPort: 80
      env:
        - name: LOG_FORMAT
          valueFrom:
            configMapKeyRef:
              name: nginx-config
              key: log-format
      volumeMounts:
        - name: nginx-config
          mountPath: /etc/nginx/conf.d/default.conf
          subPath: nginx.conf
...
```

In this example, we added an environment variable named LOG_FORMAT and referenced it from the nginx-config ConfigMap with the log-format key. You can then use this variable within your Nginx configuration file by using the $LOG_FORMAT syntax.

## Step 5: Update the ConfigMap

To change the dynamic value, you can update the ConfigMap using the kubectl edit command:

```
kubectl edit configmap nginx-config
```

This will open the ConfigMap in an editor where you can modify the dynamic value.

By following these steps, you can configure Nginx with a dynamic value using a ConfigMap in Kubernetes. This allows you to easily manage and update your Nginx configuration without modifying the deployment itself.

## Making the server_name parameter dynamic

To make the server_name parameter in the Nginx configuration dynamic and set it to the hostname of the pods, you can use the metadata.name field of the pod as an environment variable in the Nginx deployment. Here's how you can achieve that:

## Step 1: Modify the ConfigMap

Update your existing ConfigMap YAML (nginx-config.yaml) to include a placeholder for the server_name parameter. Modify the nginx.conf section as follows:

```
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  nginx.conf: |
    server {
      listen 80;
      server_name ${SERVER_NAME};
      root /usr/share/nginx/html;
      index index.html;

      # Add your dynamic configuration here using the $variable_name syntax
      # Example: access_log /var/log/nginx/access.log $log_format;
    }
```

In this example, we added ${SERVER_NAME} as a placeholder for the dynamic value of server_name.

## Step 2: Update the Deployment

In your Nginx deployment YAML (nginx-deployment.yaml), modify the container spec to include an environment variable that references the pod's hostname. Update the file as follows:

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80
          env:
            - name: SERVER_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
          volumeMounts:
            - name: nginx-config
              mountPath: /etc/nginx/conf.d/default.conf
              subPath: nginx.conf
      volumes:
        - name: nginx-config
          configMap:
            name: nginx-config
```

In this example, we added an environment variable named SERVER_NAME and set its value from the pod's metadata.name field using the fieldRef syntax.

## Step 3: Apply the Changes

Apply the updated ConfigMap and Deployment using the kubectl apply command:

```
kubectl apply -f nginx-config.yaml
kubectl apply -f nginx-deployment.yaml
```

This will apply the changes and update the Nginx deployment with the dynamic value for the server_name parameter.

Now, each pod's hostname will be automatically set as the value for server_name in the Nginx configuration, making it dynamic and specific to each pod.

Please note that the metadata.name field refers to the pod's assigned name, which by default is unique.