Do you guys have templates for making a pulumi pro...
# general
r
Do you guys have templates for making a pulumi provider (i.e. something that is not a TF provider)?
w
There’s no boilerplate or docs - but it’s not too hard to do if you look at the kubernetes provider. Here’s a mail I sent recently on this with some details - planning on moving this into docs and/or boilerplate soon. We have plans to make this easier in two dimensions - a schema driven model for building providers, and a shared code generator so you don’t have to reimplement yourself. —————— Here's a quick summary of the pieces of building a native Pulumi provider. I'll use the Kubernetes provider as an example. First - there are two pieces to any provider: * A provider binary which serves the Resource Provider gRPC interface * An SDK per Pulumi language that projects the resources managed by the provider into NodeJS, Python, .NET, Go, etc. In the Kubernetes provider - there are two binaries corresponding to the above: The provider binary: https://github.com/pulumi/pulumi-kubernetes/blob/master/cmd/pulumi-resource-kubernetes/main.go To generate the language SDKS: https://github.com/pulumi/pulumi-kubernetes/blob/master/cmd/pulumi-gen-kubernetes/main.go Any resource provider will generally be driven off of some form of Schema. This can differ based on the resources being mapped. For Kubernetes, the schema is the published OpenAPI spec for the Kubernetes API Server. For Terraform-bridged providers it is the Terraform resource schema. And it can also be any sort of homegrown schematization if needed. This schema describes what resources exist, what properties exist on those resources and with what types, and some information about how to map those resources to API calls for CRUD operations. The gRPC interface that a Pulumi Provider must implement is documented here: https://github.com/pulumi/pulumi/blob/master/sdk/proto/provider.proto. It is implemented for the Kubernetes provider here: https://github.com/pulumi/pulumi-kubernetes/blob/master/pkg/provider/provider.go. To first approximation, this is an implementation of Create, Read, Update and Delete operations - but there are also critical Check and Diff functions. The contracts for the implementations of these interfaces are discussed in some detail in https://www.pulumi.com/docs/intro/concepts/programming-model/#resource-provider-interface in the context of "Dynamic Providers", but are generally the same as for the raw gRPC interface. For the Kubernetes provider, the code generators are built on top of Mustache templates - and are generatred from the same schema as is used to implement the gRPC interface. In general one class is generated per Resource, which just inherits from the core Pulumi package's CustomResource constructor that takes care of actually registering the resource with Pulumi.
r
Thank you. This helps. I believe I have managed to get the boilerplate done here: https://github.com/brandonkal/pulumi-command I’m not exactly sure how to go about testing this though. Is it just moving the result of
go build
into my
~/.pulumi
directory and
yarn link
the node sdk into a test project?
w
This looks great! Yes - if you make sure the
pulumi-resource-command
binary is on tour PATH then it should get loaded when you create a resource of type
command:x:y
. You should be able to yarn link the NodeJS package and then use that from examples. I’ll take a deeper look at the provider soon - but this looks like it’s exactly the right start - and a great example of a small native provider.
👍 1
r
I now have it functioning running commands and saving stdout/stderr to state. What is not working yet is accessing the result in TS. I added a
Copy code
readonly stdout: pulumi.Output<string>
to the Custom Resource class. Is there anything else required to get pulumi to include it so it can be exported in TS for instance? I’m excited that this is so close.
w
Yes - there is a very subtle requirement that you need to add any outputs as properties with value undefined on the props bag you pass to the`CustomResource` super call. For example like this: https://github.com/pulumi/pulumi-aws/blob/master/sdk/nodejs/acm/certificate.ts#L194. There’s a note on this requirement in the dynamic providers docs - but it is a little surprising.
r
Okay. Thank you! The other very minor thing is that it tries to download the go binary from <http://pulumi.com|pulumi.com> before using the binary in the PATH. Is that because the npm package has a “pulumi”: {“resource”true} in its package json? Looking through the code, I see it prefers when the executable has a version in its name.