What is the best way to create a module which requ...
# general
m
What is the best way to create a module which requires a
k8s.Provider
as an input? Taking a
pulumi.Input<k8s.Provider>
runs into issues with then being able to pass it along to resources provisioned in the module. The provider is originally a
pulumi.Output<k8s.Provider>
from a different module.
w
What is causing you to get a
Pulumi.Output<k8s.Provider>
? In general, you will want to get a
k8s.Provider
directly, and it should (almost always) be possible to do so. The best way to inherit the provider is actually generally to use Components, and set all resources as
parent: this
inside the component. That will the pick up the provider from the parent, allowing the component to be used with any provider (or even with the default provider) depending on how the component is created by the owner.
m
I'm running into an issue where I would like to have the
k8s.Provider
have a dependency on a sibling resource, before it may be used.
Maybe that's just sort of an antipattern
My module creates a cluster, extracts the provider from that, then creates single k8s resource with that provider. I don't want anything else that uses the outputted k8s provider to be able to until that extra resource is created.
so I end up with a line like this
this.k8sProvider = adminClusterRoleBinding.id.apply(() => k8sProvider)
w
In general, you can pass
Input<T>
to the inputs of the Provider, so you can create the provider using the inputs from whatever it depends on, without using
apply
on those dependencies.
m
That's slightly different from what I'm trying to describe. I'm sort of wanting to artificially add a dependency to the provider after it has already been created
w
Ahh - I see, you are just looking to add additional dependency information into the returned Provider. Cc @lemon-spoon-91807 who is working on patterns to make this more natural (and will have suggestions on what you can do today).
👍 1
m
It has only become an issue for this very specific case of wanting to add an admin role binding to the cluster before anything else attempts to use the provider.
Also to your point of using the parent for provider info, I have seen mention of that but been a bit confused by the best way to do it. Would it look like:
Copy code
const k8sProvider = getProvider()
const resource = new ResourceThatMakesK8sThings("name", this, {
  providers: { kubernetes: k8sProvider }
})
Assuming the 3rd parameter is
opts?: pulumi.ComponentResourceOption
, used in the
super
call
w
Yes - that’s right. After doing that, any resources parented to that component will pick up the provider you specified. There’s some docs updates on this that are just getting rolled out now. Should be live shorty but here’s the PR. https://github.com/pulumi/docs/pull/893/files#diff-9f81eb55f153ab8ff815c4ceb0a90065R117
m
Got it, thanks a ton! There are definitely a few tricky patterns to this at first. Is there any way to set the providers of "this" after the
super
call?
Just figured out a trick to accomplish what I needed... obvious in hindsight. In my module I create two identical `k8s-provider`s now. One internal one to create the k8s resource I want the REAL provider to depend on, and a second one that is exported, built on dependency info of the k8s resource.