Generating CronTab CustomResources with crd2pulumi
This example lives in the pulumi/examples repository. Check out just this directory to use it:
git clone --filter=blob:none --sparse https://github.com/pulumi/examples pulumi-examplesgit -C pulumi-examples sparse-checkout set crd2pulumi-crontabscd pulumi-examples/crd2pulumi-crontabsThis example generates a strongly-typed CronTab CustomResource from the Kubernetes CRD specified in crontabs.yaml in TypeScript and Go. Afterwards, we’ll use this generated code with Pulumi to deploy the CRD and create an instance. For more documentation on crd2pulumi, check out the project’s GitHub page.
Setting up crd2pulumi#
We’ll set up crd2pulumi by downloading the latest binary. If you’re interested in building crd2pulumi itself, you can find instructions in the project README.
You can find the download links for the latest binaries on GitHub. For this example we’re using darwin-amd64, so if you’re using a different OS, make sure to use the correct download link.
wget https://github.com/pulumi/pulumi-kubernetes/releases/download/crd2pulumi%2Fv1.0.0/crd2pulumi-darwin-amd64.tar.gztar -xvf crd2pulumi-darwin-amd64.tar.gzmv ./releases/crd2pulumi-darwin-amd64/crd2pulumi ./crd2pulumiRunning the App (TypeScript)#
Follow the steps in Pulumi Installation and Setup and Configuring Pulumi Kubernetes to get setup with Pulumi and Kubernetes.
Install dependencies:
cd kubernetes-ts-crontabsnpm installCreate a new stack:
pulumi stack init devAt first, the provided index.ts program shouldn’t run, since we haven’t actually generated the ./crontabs code yet.
crontabs.yamlis a k8s CRD that specifies a CronTab CustomResource. It’s also used as an example in the Kubernetes Documentation.
Generate the strongly-typed CronTab resource in the current directory:
../crd2pulumi nodejs ../crontabs.yaml .This should generate a ./crontabs folder, where we can import the useful classes v1.CronTab and NewCronTabDefinition.
This saves us a lot of time, since we can create the CRD in a single line and get typed arguments in the CustomResource. If you’re curious, the comments contain the code that we would’ve written without
crd2pulumi.
Perform the deployment:
pulumi upPreviewing update (dev): Type Name Plan pulumi:pulumi:Stack examples-dev + ├─ kubernetes:stable.example.com:CronTab my-new-cron-object create + └─ kubernetes:apiextensions.k8s.io:CustomResourceDefinition my-crontab-definition createResources: + 2 to create 1 unchangedDo you want to perform this update? yesUpdating (dev): Type Name Status pulumi:pulumi:Stack examples-dev + ├─ kubernetes:stable.example.com:CronTab my-new-cron-object created + └─ kubernetes:apiextensions.k8s.io:CustomResourceDefinition my-crontab-definition createdOutputs: urn: "urn:pulumi:dev::examples::kubernetes:stable.example.com/v1:CronTab::my-new-cron-object"Resources: + 2 created 1 unchangedDuration: 17sIt looks like both the CronTab definition and instance were both created! Finally, let’s verify that they were created by manually viewing the raw YAML data:
kubectl get ct -o yaml- apiVersion: stable.example.com/v1 kind: CronTab metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"stable.example.com/v1","kind":"CronTab","metadata":{"labels":{"app.kubernetes.io/managed-by":"pulumi"},"name":"my-new-cron-object"},"spec":{"cronSpec":"* * * * */5","image":"my-awesome-cron-image"}} creationTimestamp: "2020-08-10T09:50:38Z" generation: 1 labels: app.kubernetes.io/managed-by: pulumi name: my-new-cron-object namespace: default resourceVersion: "1658962" selfLink: /apis/stable.example.com/v1/namespaces/default/crontabs/my-new-cron-object uid: 5e2c56a2-7332-49cf-b0fc-211a0892c3d5 spec: cronSpec: '* * * * */5' image: my-awesome-cron-imagekind: Listmetadata: resourceVersion: "" selfLink: ""Let’s destroy the CRD and CustomResource object so we can re-create them in Go.
pulumi destroyPreviewing destroy (dev): Type Name Plan - pulumi:pulumi:Stack kubernetes-go-crontabs-dev delete - ├─ kubernetes:stable.example.com:CronTab my-new-cron-object delete - └─ kubernetes:apiextensions.k8s.io:CustomResourceDefinition cronTabDef delete
Outputs: - urn: "urn:pulumi:dev::kubernetes-go-crontabs::kubernetes:stable.example.com/v1:CronTab::my-new-cron-object"
Resources: - 3 to delete
Do you want to perform this destroy? yesDestroying (dev): Type Name Status - pulumi:pulumi:Stack kubernetes-go-crontabs-dev deleted - ├─ kubernetes:stable.example.com:CronTab my-new-cron-object deleted - └─ kubernetes:apiextensions.k8s.io:CustomResourceDefinition cronTabDef deleted
Outputs: - urn: "urn:pulumi:dev::kubernetes-go-crontabs::kubernetes:stable.example.com/v1:CronTab::my-new-cron-object"
Resources: - 3 deleted
Duration: 5s
The resources in the stack have been deleted, but the history and configuration associated with the stack are still maintained.If you want to remove the stack completely, run 'pulumi stack rm dev'.Running the App (Go)#
First, if you haven’t already, install Go. Then create a new stack:
cd kubernetes-go-crontabspulumi stack init devLike before, main.go shouldn’t compile since we haven’t generated the crontabs module yet. Let’s do that:
../crd2pulumi go ../crontabs.yaml .This creates a crontabs/v1 module in the current directory, which contains the useful constructor NewCronTab().
If you’re curious, the commented code is what we would’ve had to write without
crd2pulumi. Previously we would have had to input theSpecarguments into a genericmap[string]interface{}with zero type-checking.
Perform the deployment:
pulumi up --yesPreviewing update (dev): Type Name Plan + pulumi:pulumi:Stack kubernetes-go-crontabs-dev create + ├─ kubernetes:stable.example.com:CronTab my-new-cron-object create + └─ kubernetes:apiextensions.k8s.io:CustomResourceDefinition cronTabDef create
Resources: + 3 to create
Updating (dev): Type Name Status + pulumi:pulumi:Stack kubernetes-go-crontabs-dev created + ├─ kubernetes:stable.example.com:CronTab my-new-cron-object created + └─ kubernetes:apiextensions.k8s.io:CustomResourceDefinition cronTabDef created
Outputs: urn: "urn:pulumi:dev::kubernetes-go-crontabs::kubernetes:stable.example.com/v1:CronTab::my-new-cron-object"
Resources: + 3 created
Duration: 10sLike before, you can run kubectl get ct -o yaml to verify that the CronTab object was actually created. Before we leave, let’s remove everything we have created:
pulumi destroy --yesPreviewing destroy (dev): Type Name Plan - pulumi:pulumi:Stack kubernetes-go-crontabs-dev delete - ├─ kubernetes:stable.example.com:CronTab my-new-cron-object delete - └─ kubernetes:apiextensions.k8s.io:CustomResourceDefinition cronTabDef delete
Outputs: - urn: "urn:pulumi:dev::kubernetes-go-crontabs::kubernetes:stable.example.com/v1:CronTab::my-new-cron-object"
Resources: - 3 to delete
Destroying (dev): Type Name Status - pulumi:pulumi:Stack kubernetes-go-crontabs-dev deleted - ├─ kubernetes:stable.example.com:CronTab my-new-cron-object deleted - └─ kubernetes:apiextensions.k8s.io:CustomResourceDefinition cronTabDef deleted
Outputs: - urn: "urn:pulumi:dev::kubernetes-go-crontabs::kubernetes:stable.example.com/v1:CronTab::my-new-cron-object"
Resources: - 3 deleted
Duration: 3s