Kustomize - Create multi and single deployment using same namespace

7/12/2021

Kustomize directory structure

├── base
│   ├── deployment.yaml
│   └── kustomization.yaml
└── overlays
    └── prod
        ├── kustomization.yaml
        ├── namespace-a
        │   ├── deployment-a1
        │   │   ├── kustomization.yaml
        │   │   └── patch.yaml
        │   ├── deployment-a2
        │   │   ├── kustomization.yaml
        │   │   └── patch.yaml
        │   ├── kustomization.yaml
        │   └── namespace.yaml
        ├── namespace-b
        │   ├── deployment-b1
        │   │   ├── kustomization.yaml
        │   │   └── patch.yaml
        │   ├── deployment-b2
        │   │   ├── kustomization.yaml
        │   │   └── patch.yaml
        │   ├── kustomization.yaml
        │   └── namespace.yaml
        └── namespace-c

As you can see above, I have prod environment with namesapce-a and namespace-b and few more. To create deployment for all, I can simply run the below command:

    > kustomize overlays/prod

Which works flawlessly, both namespaces are created along with other deployment files for all deployments.

To create a deployment for only namespace-a:

    > kustomize overlays/prod/namespace-a

That also works. :)

But that's not where the story ends for me at-least.

I would like to keep the current functionality and be able to deploy deployment-a1, deployment-a2 ...

    > kustomize overlays/prod/namespace-a/deployment-a1

If I put the namespace.yaml inside deployment-a1 folder and add it in kustomization.yaml then the above command works but previous 2 fails with error because now we have 2 namespace files with same name.

I have 2 queries.

  1. Can this directory structure be improved?
  2. How can I create namesapce with single deployment without breaking the other functionality?

Full code can be seen here

-- Arian
kubernetes
kustomize

1 Answer

7/15/2021

In your particular case, in the most ideal scenario, all the required namespaces should already be created before running the kustomize command. However, I know that you would like to create namespaces dynamically as needed.

Using a Bash script as some kind of wrapper can definitely help with this approach, but I'm not sure if you want to use this.

Below, I'll show you how this can work, and you can choose if it's right for you.


First, I created a kustomize-wrapper script that requires two arguments: 1. The name of the Namespace you want to use. 2. Path to the directory containing the kustomization.yaml file.

kustomize-wrapper.sh

$ cat kustomize-wrapper.sh
#!/bin/bash

if [ -z "$1" ] || [ -z "$2" ]; then
    echo "Pass required arguments !"
    echo "Usage: $0 NAMESPACE KUSTOMIZE_PATH"
    exit 1
else
    NAMESPACE=$1
    KUSTOMIZE_PATH=$2
fi

echo "Creating namespace"
sed -i "s/name:.*/name: ${NAMESPACE}/" namespace.yaml
kubectl apply -f namespace.yaml

echo "Setting namespace: ${NAMESPACE} in the kustomization.yaml file"
sed -i "s/namespace:.*/namespace: ${NAMESPACE}/" base/kustomization.yaml

echo "Deploying resources in the ${NAMESPACE}"
kustomize build ${KUSTOMIZE_PATH} | kubectl apply -f -

As you can see, this script creates a namespace using the namespace.yaml file as the template. It then sets the same namespace in the base/kustomization.yaml file and finally runs the kustomize command with the path you provided as the second argument.

namespace.yaml

$ cat namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name:

base/kustomization.yaml

$ cat base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace:

resources:
- deployment.yaml

Directory structure

$ tree
.
├── base
│   ├── deployment.yaml
│   └── kustomization.yaml
├── kustomize-wrapper.sh
├── namespace.yaml
└── overlays
    └── prod
        ├── deployment-a1
        │   ├── kustomization.yaml
        │   └── patch.yaml
        ├── deployment-a2
        │   ├── kustomization.yaml
        │   └── patch.yaml
        └── kustomization.yaml
    
    
    

We can check if it works as expected.

Creating the namespace-a Namespace along with app-deployment-a1 and app-deployment-a2 Deployments:

$ ./kustomize-wrapper.sh namespace-a overlays/prod
Creating namespace
namespace/namespace-a created
Setting namespace: namespace-a in the kustomization.yaml file
deployment.apps/app-deployment-a1 created
deployment.apps/app-deployment-a2 created

Creating only the namespace-a Namespace and app-deployment-a1 Deployment:

$ ./kustomize-wrapper.sh namespace-a overlays/prod/deployment-a1
Creating namespace
namespace/namespace-a created
Setting namespace: namespace-a in the kustomization.yaml file
deployment.apps/app-deployment-a1 created
-- matt_j
Source: StackOverflow