I'm working on a native provider and have a couple...
# package-authoring
g
I'm working on a native provider and have a couple questions about provider design. I was working on a TF provider and ended up feeling that the data model & requirements didn't fit well into TF. Hoping Pulumi is a different situation... • I want to validate as strongly as possible because the remote system is kind of delicate. From the
infer
module's
CustomCheck
interface, it looks like validation is only going to be local to a resource. Is there a clean way to validate a resource's inputs when that validation requires looking at other resources' state? • My remote system has APIs that end up creating multiple sub-resources. i.e. createParentResource API creates parentResource, childResource1, childResource2, childResource3. The creation API also fills in a lot of default configuration into those child resources. The child resources are managed individually from there on. Is there a clean way to handle this? It seems like I would need to create the parent and then import into Pulumi state, but that's not a great workflow. Any help is appreciated.
e
Is there a clean way to validate a resource's inputs when that validation requires looking at other resources' state?
We'd generally recommend using Check to just check local invariants and fill in defaults. But there's nothing that would technically stop you from doing a network request in Check to validate against other resources.
My remote system has APIs that end up creating multiple sub-resources
That is a tricky one. I don't know of any first class handling we have for this scenario, but maybe someone with more experience building providers knows some tricks for it.
a
Is there a clean way to validate a resource’s inputs when that validation requires looking at other resources’ state?
I’m not aware of a supported way to validate across resources. As Fraser said, you can make arbitrary requests within resource steps.
The creation API also fills in a lot of default configuration into those child resources. The child resources are managed individually from there on.
My best take would be: If your ok tying the lifecycle of
parentResource
to it’s children, then I would model by feeding `parentResource`’s ID to
childResource1
,
childResource2
,
childResource3
as a required input.
parentResource
would be responsible for creating and deleting itself and it’s children, where the children would be responsible for updating their resources. I’m not aware of a clean way to have
parentResource
handle creation but child resources handle deletion. The obvious problem there is what happens if no children are created in Pulumi. Fundamentally, pulumi thinks of resources as objects with a “Create” operation, and ideally Read, Update and Delete operations. I know how to handle missing Read, Update and Delete cleanly, but I’m not aware of a super clean mapping for missing Create (besides import, as you mentioned).
g
I think I'm clear on point 1. One last question on validation, is it possible to define custom types for different ID "domains"? for example resource A outputs an ID of type ResourceA_ID_String, and resource X would input a ResourceA_ID_String as an input. It seems like that might get me pretty far for validating config compared to the normal method which would just be validating a bunch of Unknown String inputs.... The reason this is the case is that my identifiers will be generated by the remote system. If all parent resource IDs referenced by the child resources were defined statically in the Pulumi config, it wouldn't be an issue... This issue seems related https://github.com/pulumi/pulumi-go-provider/issues/18. For the child resources, yes their lifecycles are intimately tied to the parent resource. Ian, your suggestion to make the children take parent object ID as input to child resources makes a lot of sense. My child resource Create method would call Read to fill its state in properly [there is an API to pull each child resource based upon the parent resource ID].