# ConfigMap

A ConfigMap is an API object used to store non-confidential data in key-value pairs. Pods can consume ConfigMaps as environment variables, command-line arguments, or as configuration files in a volume.

A ConfigMap allows you to decouple environment-specific configuration from your container images, so that your applications are easily portable.

## App: Get Config From ENV

We already have and app that will return a JSON response `{"message":"Success"}`. Let's make it configurable so our apps will check the environment variable `DEFAULT_MESSAGE` and use the value as message in our response.

```go
package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    "os"
)

type Response struct {
    Message string `json:"message,omitempty"`
}

func main() {
    // get default message from env
    message := os.Getenv("DEFAULT_MESSAGE")
    if message == "" {
        // fallback message
        message = "Success"
    }

    srv := http.NewServeMux()
    srv.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        res := Response{
            Message: message,
        }

        err := json.NewEncoder(w).Encode(res)
        if err != nil {
            log.Fatal(err)
        }
    })

    fmt.Println("Server is running on port 8080...")
    err := http.ListenAndServe(":8080", srv)
    if err != nil {
        log.Fatal(err)
    }
}
```

Try to run it with additional environment variable like this `DEFAULT_MESSAGE="k8s" go run main.go` and it should return `k8s` as the message when we access it.

```bash
➜ curl http://127.0.0.1:8080
{"message":"k8s"}
```

Build our apps again using command `docker build --tag simple-go .` so the new image will available in kubernetes docker images.

## Define ConfigMap

Let's create a new file called `configmap.yaml` and define our ConfigMap object in there.

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: simple-go-config
data:
  DEFAULT_MESSAGE: "Everything is fine!"
```

This will create a ConfigMap object with name `simple-go-config`. The `data` section is key value pair for our config. In here we have config data with key `DEFAULT_MESSAGE` and value `"Everything is fine!"`.

Lets apply it using command `kubectl apply -f configmap.yaml`. And check it using `kubectl get configmaps`. We should see `simple-go-config` in the list there.

```bash
➜ kubectl get configmaps 
NAME               DATA   AGE
kube-root-ca.crt   1      20d
simple-go-config   1      3s
```

We can also get the details of it using command `kubectl describe configmaps simple-go-config`.

```bash
➜ kubectl describe configmaps simple-go-config 
Name:         simple-go-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
DEFAULT_MESSAGE:
----
Everything is fine!


BinaryData
====

Events:  <none>
```

## Bind ConfigMap in Deployment

Now that we already setup a ConfigMap we need to update our deployment config to set environment variable with name `DEFAULT_MESSAGE` and get the value from ConfigMap named `simple-go-config` and key `DEFAULT_MESSAGE`.

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: simple-go
  labels:
    app: simple-go
spec:
  replicas: 3
  selector:
    matchLabels:
      app: simple-go
  template:
    metadata:
      labels:
        app: simple-go
    spec:
      containers:
      - name: server
        image: simple-go:latest
        imagePullPolicy: Never
        ports:
        - containerPort: 8080
        env:
        - name: DEFAULT_MESSAGE
          valueFrom:
            configMapKeyRef:
              name: simple-go-config
              key: DEFAULT_MESSAGE
```

Apply the deployment and we should see a new sets of pods created replacing the old pods.

```bash
➜ kubectl apply -f deployment.yaml 
deployment.apps/simple-go configured
```

```bash
➜ kubectl get pods
NAME                         READY   STATUS    RESTARTS   AGE
simple-go-77b89f5cf8-6ldx9   1/1     Running   0          8s
simple-go-77b89f5cf8-bpsgq   1/1     Running   0          9s
simple-go-77b89f5cf8-jcfc7   1/1     Running   0          7s
```

Now let's do a port-forward to one of the pods and access our apps with curl.

```bash
➜ kubectl port-forward simple-go-77b89f5cf8-6ldx9 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
```

Our app now should return response message `"Everything is fine!"` like this.

```bash
➜ curl http://127.0.0.1:8080
{"message":"Everything is fine!"}
```

Whenever we update a ConfigMap we also need to restart our pods so it will get the latest config available.

## References

* <https://kubernetes.io/docs/concepts/configuration/configmap/>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bagus-cahyono.gitbook.io/programming-notes/cka/04_configmap.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
