1. Defining custom resource definitions to extend Kubernetes via ProviderConfig

    TypeScript

    Custom Resource Definitions (CRDs) are a powerful feature of Kubernetes that allow you to extend its API and introduce new custom resources. These custom resources can be managed via kubectl or using Kubernetes client libraries, just like built-in resources like pods and services. Pulumi provides a way to manage these resources using infrastructure as code principles.

    Before we dive into the code, it's important to understand that a CRD defines a new kind of resource that your Kubernetes cluster will understand and manage. A CRD includes the definition of a new object (like a Database or Firewall), specifying things like allowed fields, validation rules, and the lifecycle of these objects.

    In Pulumi, you use the CustomResource class to create instances of your custom resources once they are defined. However, to define the CRD itself, you use a specific CustomResourceDefinition class from the Kubernetes package.

    Here's a step-by-step TypeScript program that demonstrates how to define a CRD using Pulumi:

    1. First, you need to import the necessary packages from Pulumi and Kubernetes SDK.
    2. Then, you define the CRD by creating a new instance of CustomResourceDefinition, passing in the necessary specifications, like the group, version, kind, and schema of the resources you're defining.
    3. After setting up the CRD, you can then create instances of your new custom resource using the CustomResource class, just as you would with any other Kubernetes resource.

    Let's look at a Pulumi TypeScript program that creates a simple CRD. This CRD will define a new resource type called MyResource:

    import * as k8s from "@pulumi/kubernetes"; const myResourceCrd = new k8s.apiextensions.v1.CustomResourceDefinition("myResourceCrd", { metadata: { // Name of the CRD name: "myresources.example.com" }, // Define the CRD Spec spec: { group: "example.com", versions: [{ name: "v1", served: true, storage: true, schema: { openAPIV3Schema: { type: "object", properties: { spec: { type: "object", properties: { name: { type: "string", }, // Here you can define all the fields your custom resource will have // ... }, required: ["name"] // Set required fields } } } }, }], scope: "Namespaced", names: { plural: "myresources", singular: "myresource", kind: "MyResource", shortNames: ["mr"] } } }); // To create an instance of MyResource after defining the CRD, you can define a CustomResource as shown below: /* const myResourceInstance = new k8s.apiextensions.CustomResource("myResourceInstance", { apiVersion: "example.com/v1", kind: "MyResource", metadata: { namespace: "default", name: "my-first-resource" }, spec: { name: "MyFirstResource" // ... other spec fields } }); */ // Export the CRD's name to be easily retrieved with `pulumi stack output` export const crdName = myResourceCrd.metadata.name;

    This Pulumi program creates a CRD named myresources.example.com, defining a new resource type MyResource with a spec that has a required name field. Once this CRD is applied to your cluster, you can create instances of MyResource that conform to the defined schema.

    Note that creation of the actual custom resources (MyResource in this case) should be done after the CRD is known to be ready and recognized by the Kubernetes API server. Pulumi handles these dependencies automatically with its promise-based approach when you run the commented part of the code.

    After running this Pulumi program using the Pulumi CLI, you will be able to manage MyResource instances using kubectl or the Kubernetes API.

    Remember, when deploying CRDs and resources based on them, it's important to manage dependencies and ensure that CRDs are fully ready before creating instances of them. Pulumi takes care of these ordering dependencies when the program is executed.

    This is just a basic example. CRDs can be complex and have many more options, such as validation, versioning, and more. For full details on all of the options available, you can refer to Kubernetes CRD documentation and the Pulumi Kubernetes API documentation for CustomResourceDefinition.