Kubernetes: ConfigMaps and Secrets (With Firebase)

After a certain amount of development with microservices you start to hit a moment where you want to eventually… oh, I don’t know… release your microservice.

At this point, you start to really worry about various hardcodings and variables that may need to be externalized from your application so that it can smoothly transition through various stages in your testing and release process. As you are planning on releasing your application in a Kubernetes Cluster this is the point you start to learn about ConfigMaps.

ConfigMaps are just the beginning. After some time with ConfigMaps it is natural that you might worry about how exposed your precious variables are, now you need to learn about Kubernetes Secrets.

“woman whispering on woman's ear while hands on lips” by Ben White on Unsplash

In this article, we are going to start by looking at moving variables into ConfigMaps before carving off a more secure plan for sensitive materials in Kubernetes Secrets.

ConfigMaps

ConfigMaps are a way to easily move your Pod configuration into separate files. This is helpful as you might have different configurations for different environments. One special feature of ConfigMaps is that you can even change out a configuration while the Pod is running without restarting the Pod. I personally don’t recommend this though as I prefer my Pods to be immutable.

ConfigMaps are really simple. In the following example, you see the entire anatomy of a ConfigMap.

With your ConfigMap YAML file created, you just need to apply it to your Kubernetes Cluster just like any other Kubernetes resource.

$ kubectl apply -f ../k8s/basic-config.yaml

With your ConfigMap applied to your Kubernetes Cluster, you can reference it in your Deployment YAML files in place of actual values. Below you can see this in action using the configMapKeyRef property.

As you can see from the above example, everywhere you reference a ConfigMap you have to request the ConfigMap by name. This means that you could reference multiple ConfigMaps in a single Pod Deployment file.

When you return to the Google Cloud Platform you can view your ConfigMap — and the values it contains — right from the UI.

The Viewable ConfigMap In A Cluster

While ConfigMaps are wonderful, you might already be thinking that having all of your data easily readable from any developer that has access to your Kubernetes Cluster is a bad thing. Now is the time to start increasing your security and introducing Kubernetes Secrets.

Secrets

Kubernetes Secrets take the idea of having easy to access key/value pairs and add an important layer of security to these values. Kubernetes achieves extra security by holding these values in memory rather than on disc. Making it that much harder for someone to get to those values.

Creating a Kubernetes Secret is easy and done through the command line. In the following case, I am taking a Firebase Service Account Key — provided in JSON format from the Firebase console — and putting it into a Kubernetes Secret names firebase-secret.

$ kubectl create secret generic \
firebase-secret \
--from-file=../k8s/files/serviceAccountKey.json

With the Kubernetes Secret created we can add the Secret into a Deployment file as a mounted volume. By mounting this secret as a volume you also will specify the path that your Pod will use to access the volume. You can see the example below for the code.

If you were to use the Google Cloud Platform UI and find your firebase-secret you’ll be excited to learn that the actual value is hidden from view. On top of that, if you use the command line you still don’t have access to the secret’s values.

NonViewable (Secret) Configuration File!

With a new working understanding of ConfigMaps and Kubernetes Secrets, it is time to actually see them working in action.

ConfigMaps and Secrets In Action

Just reading about a feature isn’t as important as actually doing it for yourself. In the next few steps, we will set up a Kubernetes Cluster in Google Cloud Platform, deploy a ConfigMap and a Secret, and then deploy a Pod that will consume these values. With this complete, we will hit some endpoints on the Pod to view the values from the ConfigMap and Secrets.

If you haven’t gone through or even read the first part of this series you might be lost, have questions where the code is, or what was done previously. Remember this assumes you’re using GCP and GKE. I will always provide the code and how to test the code is working as intended.

Setup Your Kubernetes Cluster

Getting started we need to have a Kubernetes Cluster up and running to apply our resources. As this isn’t the purpose of this article I’m just going to move forward quickly with a few scripts that you can use to start up a Kubernetes Cluster. Simply go into your Google Cloud Shell scripting section and run the following scripts.

$ git clone https://github.com/jonbcampos/kubernetes-series.git
$ cd ~/kubernetes-series/secrets/scripts
$ sh startup.sh

After a few moments, you’ll have a working Kubernetes Cluster running and ready to move forward with the new stuff.

Deploy The ConfigMap

The code to deploy the ConfigMap you saw earlier in the article. We just apply the resource to our Kubernetes Cluster and we’re ready to go.

$ cd ~/kubernetes-series/secrets/scripts
$ kubectl apply -f ../k8s/basic-config.yaml

Deploy The Secret To The Cluster

Before we deploy the Pod we need to have all the necessary values in the Kubernetes Cluster. Yes, you can mark some configuration values as optional, but in this case, they are all required to have a successful Pod start. The following code creates the secret with the provided serviceAccountKey.json. I need to state that I’ve already killed the Firebase project that belongs to the provided key, so if you want this to work you’ll need to create your own really quickly. It is super easy so that shouldn’t take more than 2 minutes.

$ cd ~/kubernetes-series/secrets/scripts
$ kubectl create secret generic firebase-secret \
--from-file=../k8s/files/serviceAccountKey.json

Now we just need to add in the config map.

Deploy The Pods And Services

With our Kubernetes Secret and ConfigMap in place, we are ready to deploy our Pod. You can verify that these resources exist in our Cluster by going to Kuberenetes Engine > Configuration and viewing these files within your Google Cloud Project.

Now we just need to deploy our Pod like a million other Pods we’ve deployed before.

$ cd ~/kubernetes-series/secrets/scripts
$ sh deploy.sh
$ sh
check-endpoint.sh endpoints

After a moment our Pod will be live and available for traffic. The check-endpoints.sh script will even provide the IP address we need to hit to view data from the Pod. You’ll use this IP Address shortly to validate everything is working as intended.

Confirm The ConfigMap-ping

The first validation to make is against the ConfigMap. If we use our browser and visit http://[Service IP Address]/api we will see that the value set in the ConfigMap is successfully passed and visible in the configVar.

configVar Provided By Our Deployed ConfigMap

Confirm We Have Access To The Secret

Now we need to validate our Kubernetes Secret. In this case, I wasn’t just going to output the value. So instead I used the Secret to access my Firebase and list out the user’s in the firebase account. Again, this account has already been deleted so you’ll need to create your own.

You can view this data by visiting http://[Service IP Address]/secret

Output Of Firebase User’s Utilizing A Kubernetes Secret

Closing

Kubernetes provides so many options that can easily blend into the background. Something as mundane as a configuration value morphs into a wonderfully orchestrated dance of values and security. As with everything, this is only the start of what you can do with these features. I recommend using them even for a simple Pod definition as the extra benefit will become clear in time.

Teardown

Before you leave, make sure to clean up your project so you aren’t charged for the VMs that you’re using to run your cluster. Return to the Cloud Shell and run the teardown script to clean up your project. This will delete your cluster and the containers that we’ve built.

$ cd ~/kubernetes-series/secrets/scripts
$ sh teardown.sh

Other Posts In This Series


Jonathan Campos is an avid developer and fan of learning new things. I believe that we should always keep learning and growing and failing. I am always a supporter of the development community and always willing to help. So if you have questions or comments on this story please ad them below. Connect with me on LinkedIn or Twitter and mention this story.

Like what you read? Give Jonathan Campos a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.