Secrets and ConfigMaps
Twelve-Factor Apps are apps that follow modern cloud native principles. Kubernetes is designed for such modern cloud native app development, and as such, many of Kubernetes features are intended to enable adherence to these principles. One such principle is "strict separation of config from code," which is accomplished in Kubernetes through Secrets and ConfigMaps.
Secrets and ConfigMaps are almost identical in that they are key value pairs that are created in your Kubernetes Cluster, then attached to containers as environmental variables (or less commonly, as files on a data volume). However, unlike ConfigMaps, Secrets are encrypted, and so are suitable for sensitive information like API credentials. All configuration information should be stored as a Secret or ConfigMap, rather than being hardcoded into your code base.
Using Secrets and ConfigMaps
Secrets and ConfigMaps are both Kubernetes Objects (examples: Deployments and Services), and so may be created like other Kubernetes Objects, via kubectl CLI commands or applying Kubernetes YAML config files (called manifests). Here's an example of creating a ConfigMap via kubectl from the official K8s documentation:
kubectl create configmap special-config -from-literal=special.how=very -from-literal=special.type=charm
In this case, it is being created from string literals in the command itself, but you could also create them from text file that had a simple list of key value pairs, or as mentioned before from a K8s YAML manifests. Now this ConfigMap is in your K8s Cluster, has a name, and two key-value pairs. But it is not yet directly accessible to any of your containers.
Containers in Kubernetes always exist inside Pods, so you would add the ConfigMap to the Pod (and therefore its containers) in that Pod's manifest. Here's another example from the docs, this time as contents of the YAML file that you would apply to create a Pod that used the ConfigMap defined above:
- name: test-container
command: [ "/bin/sh", "-c", "env" ]
Now any of these Pods that get deployed to your cluster will have two new environmental variables in them, one with the key special.how and another special.type. You can access the values the same way you'd access any normal environmental variable. And the situation is almost identical with Secrets. Here's a diagram illustrating the relationship of the various Kubernetes Objects:
Learning to do anything in a new way takes effort, but with Kubernetes you can be sure it will pay off. Following twelve-factor app best practices can require some extra organization up front, but saves time and headache as your app grows.
By leveraging ConfigMaps and Secrets in Kubernetes, you separate your configuration information not only from the code base, but even from the container images you are building. This way you can build one image that's useable in many environments, and simply deploy it with Kubernetes into multiple environments (examples, dev and prod) with a different set of values for the same keys in your environmental variables. That way your payment gateway in dev hits a sandbox API, while in prod it actually charges real money. And you never had to change your code, or even your container image.