1. Introduction

At the present time, Kubernetes has become the industry standard for deploying applications. This is because it makes it easier to manage the deployments and provides high availability and scalability.

We use YAML or JSON files to manage deployments in Kubernetes. In a normal deployment, we’ll generally use several YAML files to specify the configurations we need to successfully deploy the application.

In order to be more organized, we can put the YAML files in directories that will help us quickly find the YAML files we are looking for. For example, we can have a directory for the YAML files responsible for the testing environment and another for the production environment.

In this tutorial, we’ll see how to apply all the configurations that are present in several YAML files that are located in one common directory with a single command. As a result, this will make it a lot easier to handle the deployments.

2. Files Located in a Single Directory

In this section, we will see how we can apply all the YAML files located in one directory.

Firstly, let’s create a directory and call it dir1:

$ mkdir dir1

Inside the directory, let’s create the following four files.

2.1. ConfigMap

Name the first file mongo-configmap.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: mongodb-configmap
data:
  database_url: mongodb-service

This file contains the configurations needed for the backend application to connect to the database.

2.2. File Containing the Secrets

Then, the second file will be mongo-secret.yaml:

apiVersion: v1
kind: Secret
metadata:
    name: mongodb-secret
type: Opaque
data:
    mongo-root-username: dXNlcm5hbWU=
    mongo-root-password: cGFzc3dvcmQ=

This file contains configurations similar to the ConfigMap but are secrets that should not be visible publicly, such as the username and password for the database.

2.3. Backend Application

The third file will be named mongo-express.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongo-express
  labels:
    app: mongo-express
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mongo-express
  template:
    metadata:
      labels:
        app: mongo-express
    spec:
      containers:
      - name: mongo-express
        image: mongo-express
        ports:
        - containerPort: 8081
        env:
        - name: ME_CONFIG_MONGODB_ADMINUSERNAME
          valueFrom:
            secretKeyRef:
              name: mongodb-secret
              key: mongo-root-username
        - name: ME_CONFIG_MONGODB_ADMINPASSWORD
          valueFrom:
            secretKeyRef:
              name: mongodb-secret
              key: mongo-root-password
        - name: ME_CONFIG_MONGODB_SERVER
          valueFrom:
            configMapKeyRef:
              name: mongodb-configmap
              key: database_url
---
apiVersion: v1
kind: Service
metadata:
  name: mongo-express-service
spec:
  selector:
    app: mongo-express
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 8081
      targetPort: 8081
      nodePort: 30000

This is the deployment file for the backend application. It contains two parts. The first is the Deployment which is responsible for the configurations of the pods that will be containing the backend application.

At the same time, the second part is the Service which is responsible for exposing the application so that we can access it.

2.4. Database

Finally, let’s create this file mongo.yaml and add the following text to it:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongodb-deployment
  labels:
    app: mongodb
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mongodb
  template:
    metadata:
      labels:
        app: mongodb
    spec:
      containers:
      - name: mongodb
        image: mongo
        ports:
        - containerPort: 27017
        env:
        - name: MONGO_INITDB_ROOT_USERNAME
          valueFrom:
            secretKeyRef:
              name: mongodb-secret
              key: mongo-root-username
        - name: MONGO_INITDB_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mongodb-secret
              key: mongo-root-password
---
apiVersion: v1
kind: Service
metadata:
  name: mongodb-service
spec:
  selector:
    app: mongodb
  ports:
    - protocol: TCP
      port: 27017
      targetPort: 27017

Similarly, like the previous file, this file contains a Deployment and a Service for the database that the backend will connect to.

2.5. Deploying All the Files at Once

After all the files were created, we now want to run a single command that will apply all the configurations in the four files.

We can do this by running the following:

$ kubectl apply -f <folder>

Now that everything is ready, let’s try it with our example. But in order for the command to run successfully, we need to make sure we are in the parent directory containing the directory we previously created. Then we can run kubectl:

$ kubectl apply -f dir1

When we do this, kubectl will recurse over each file in the directory, and if it is a YAML (or JSON) file, it will apply it.

To check the results, we can run the following:

$ kubectl get all
NAME                                     READY   STATUS    RESTARTS       AGE
pod/svclb-mongo-express-service-l8dxb    1/1     Running   0              6m45s
pod/mongodb-deployment-8f6675bc5-gxfl9   1/1     Running   0              6m45s
pod/mongo-express-78fcf796b8-nx94g       1/1     Running   1 (6m4s ago)   6m45s

NAME                            TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/kubernetes              ClusterIP      10.43.0.1       <none>        443/TCP          12d
service/mongodb-service         ClusterIP      10.43.238.212   <none>        27017/TCP        6m45s
service/mongo-express-service   LoadBalancer   10.43.108.110   172.19.0.3    8081:30000/TCP   6m45s

NAME                                         DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/svclb-mongo-express-service   1         1         1       1            1           <none>          6m45s

NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/mongodb-deployment   1/1     1            1           6m45s
deployment.apps/mongo-express        1/1     1            1           6m45s

NAME                                           DESIRED   CURRENT   READY   AGE
replicaset.apps/mongodb-deployment-8f6675bc5   1         1         1       6m45s
replicaset.apps/mongo-express-78fcf796b8       1         1         1       6m45s

So, we can see from the output of the command that all the Deployments and Services from our files were created successfully.

3. Files Located in Nested Directories

What we did in the previous section was useful, but how about if we want to organize our YAML files into several folders? Will we need to run the previous command on each one of these folders? The answer is no; there is an easier way.

Let’s first delete the Deployments and Services that we created in the previous section so that we can have a fresh start.

To delete the Deployments run this:

$ kubectl delete deploy mongodb-deployment mongo-express

To delete the Services, we can run the following:

$ kubectl delete service mongodb-service mongo-express-service

We can check they were deleted by running this command:

$ kubectl get all

Next, let’s move mongo-express.yaml and mongo.yaml to an apps folder*.* Also*,* let’s move the other two files to a folder called conf.

The folder tree should be similar to this:

dir1
    ├── apps
    │   ├── mongo-express.yaml
    │   └── mongo.yaml
    └── conf
        ├── mongo-configmap.yaml
        └── mongo-secret.yaml

Now if we try to run the kubectl apply -f command again from the parent directory of dir1, we will get an error:

$ kubectl apply -f dir1
error: error reading [dir1]: recognized file extensions are [.json .yaml .yml]

This is because the command is looking for the YAML files in the dir1 directory, and there are none.

We need to tell it to search recursively inside the directory to find all the files. We can do this by adding the -R or —**recursive options to our command.

Let’s try it again after adding -R:

$ kubectl apply -f dir1 -R

This time the command was successful, and the Deployments and Services were created.

4. Conclusion

In this article, we discussed many YAML files we use to manage our deployments. It is generally a good idea to organize them into multiple folders.