Search code examples
kubernetesgoogle-cloud-platformpulumi

Controlling where Pulumi creates k8s namespaces


I need to write a new Pulumi program to do some k8s stuff. One task is creating new namespaces in different clusters.

What I want to do should look like this:

    const ns1 = new k8s.core.v1.Namespace("foo-ns", {cluster: "foo_cluster"});
    const ns2 = new k8s.core.v1.Namespace("bar-ns", {cluster: "bar_cluster"});

I've looked at the docs for Namespaces (https://www.pulumi.com/registry/packages/kubernetes/api-docs/core/v1/namespace/) and I'm not really sure how I can control where the namespaces will get created. I see that there is an option to pass in a cluster name (https://www.pulumi.com/registry/packages/kubernetes/api-docs/core/v1/namespace/#clustername_nodejs) but the documents says

The name of the cluster which the object belongs to. This is used to distinguish resources with same name and namespace in different clusters. This field is not set anywhere right now and apiserver is going to ignore it if set in create or update request.

(emphasis is mine)

So now I wonder: if I tell Pulumi to create a new namespace, in which cluster will the namespace be created?

(I was going to also ask about creating namespaces in similarly-named clusters in different GKE environments in different GCP projects - as that might be the next phase of this code, but I don't see a point if I can't specify different clusters in the same project)


Solution

  • You can achieve this using a resource provider, concretely, an explicit resource provider

    The Kubernetes resource provider supports a variety of ways to configure access to clusters, such as passing a kubeconfig or Kubernetes context:

    import * as k8s from "@pulumi/kubernetes";
    
    const cluster1 = new k8s.Provider("cluster1", {
      cluster: "cluster1" // use the cluster with name "cluster1" in your default kubeconfig
    });
    
    const cluster2 = new k8s.Provider("cluster2", {
      kubeconfig: fs.readFileSync(path.resolve(__dirname, "./kubeconfig.yaml") // use a different kubeconfig entirely
    });
    
     const ns1 = new k8s.core.v1.Namespace("foo-ns", {}, {provider: cluster1});
     const ns2 = new k8s.core.v1.Namespace("bar-ns", {}, {provider: cluster2});