Defining custom resource definitions to extend Kubernetes via ProviderConfig
TypeScriptCustom 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
orFirewall
), 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 specificCustomResourceDefinition
class from the Kubernetes package.Here's a step-by-step TypeScript program that demonstrates how to define a CRD using Pulumi:
- First, you need to import the necessary packages from Pulumi and Kubernetes SDK.
- 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. - 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 typeMyResource
with a spec that has a requiredname
field. Once this CRD is applied to your cluster, you can create instances ofMyResource
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 usingkubectl
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
.