Search code examples
node.jskubernetesyamlkubectl

Can I deploy YAML code as file without YAML file in Kubernetes


One can easily deploy YAML file in Kubernetes either by using kubectl apply or using helm install to deploy all YAML file at once, but I am looking for a way through which I would be able to deploy YAML files without actually creating files and deploy it directly through nodeJS code

What I am doing right now:

I can able to deploy YAML files which are created by my nodeJS code, which first creates JSON object parse it to YAML, and then generates its YAML file, and the same code is able to deploy those files.

What I need:

I want to be able to deploy the YAML code directly without creating its YAML file.


Solution

  • To apply from command line use:

    node-js-generate-yaml-command | kubectl apply -f -

    or right from code use kubectl javascript client https://github.com/kubernetes-client/javascript

    The example of kubectl apply can be found here https://github.com/kubernetes-client/javascript/blob/master/examples/typescript/apply/apply-example.ts

    import * as k8s from '@kubernetes/client-node';
    import * as fs from 'fs';
    import * as yaml from 'js-yaml';
    import { promisify } from 'util';
    
    /**
     * Replicate the functionality of `kubectl apply`.  That is, create the resources defined in the `specFile` if they do
     * not exist, patch them if they do exist.
     *
     * @param specPath File system path to a YAML Kubernetes spec.
     * @return Array of resources created
     */
    export async function apply(specPath: string): Promise<k8s.KubernetesObject[]> {
        const kc = new k8s.KubeConfig();
        kc.loadFromDefault();
        const client = k8s.KubernetesObjectApi.makeApiClient(kc);
        const fsReadFileP = promisify(fs.readFile);
        const specString = await fsReadFileP(specPath, 'utf8');
        const specs: k8s.KubernetesObject[] = yaml.safeLoadAll(specString);
        const validSpecs = specs.filter((s) => s && s.kind && s.metadata);
        const created: k8s.KubernetesObject[] = [];
        for (const spec of validSpecs) {
            // this is to convince the old version of TypeScript that metadata exists even though we already filtered specs
            // without metadata out
            spec.metadata = spec.metadata || {};
            spec.metadata.annotations = spec.metadata.annotations || {};
            delete spec.metadata.annotations['kubectl.kubernetes.io/last-applied-configuration'];
            spec.metadata.annotations['kubectl.kubernetes.io/last-applied-configuration'] = JSON.stringify(spec);
            try {
                // try to get the resource, if it does not exist an error will be thrown and we will end up in the catch
                // block.
                await client.read(spec);
                // we got the resource, so it exists, so patch it
                const response = await client.patch(spec);
                created.push(response.body);
            } catch (e) {
                // we did not get the resource, so it does not exist, so create it
                const response = await client.create(spec);
                created.push(response.body);
            }
        }
        return created;
    }