late-airplane-27955
11/23/2024, 10:01 AMComponentResource
, which takes a number of args. Let's say one of them is a containerImage
string. Should I define that as Input<string>
or just string
in my component resource args class/interface?
I'd like to do some logic on it, like add a version
if the image seems untagged. Am I okay to do this:
export interface CustomComponentResourceArgs {
containerImage: pulumi.Input<string>;
}
...and then cast it to string to perform logic on it?
let image = args.containerImage.toString()
image = image.includes(":") ? image : `${image}:${args.version}`;
...or is there a more pulumi-esque way of doing this? I'd like to allow whoever's using my component resource to be able to pass in both regular "hard-coded" args as well as outputs from other resources they might definelate-airplane-27955
11/23/2024, 11:54 AMechoing-dinner-19531
11/23/2024, 4:28 PMquick-house-41860
11/24/2024, 2:10 PMconst image = pulumi.all([args.containerImage, args.version]).apply(([containerImage, version]) => {
return containerImage.includes(":") ? containerImage : `${containerImage}:${version}`;
});
Casting the input to a string would fail if users pass an output or promise for this arg.late-airplane-27955
11/24/2024, 2:13 PMlate-airplane-27955
11/24/2024, 8:55 PMbrave-planet-10645
11/25/2024, 10:14 AMInput<T>
matches what provider resources do. For example, even though in our docs it looks like the cidrBlock
parameter of a VPC is a string
(see screenshot below) it's actually Input<string>
.
This will also mean that if you convert your components into multi-language ones, the types will remain the same rather than being converted to an input.
At the end of the day, I don't think it really matters which one as long as you're consistent on what you do.
Personally, I use Input<T>
when building component resources.late-airplane-27955
11/25/2024, 10:41 AMechoing-dinner-19531
11/25/2024, 10:43 AMlate-airplane-27955
11/25/2024, 12:59 PMlate-airplane-27955
11/25/2024, 1:01 PMlate-airplane-27955
11/25/2024, 1:05 PMechoing-dinner-19531
11/25/2024, 1:13 PMI don't know which design descision in pulumi that made this input/output apply a requirementcdk and cdktf use tokens instead, so you often have to use a limited set of built-in functions to operate on those values. Pulumi reifies the values fully, but to handle that the values are returned async, and sometimes not returned at all (e.g. during preview a resources might not have an output value) we have to wrap them in Inputs/Outputs and use apply. We're definitely interested in trying to make sure that all the most basic uses cases are handled by simple builtin functions, similar to cdk/cdktf.
I feel like there's no explanation about when apply has to be used and when not.I think we've historically assumed it was clear that you use apply when you have to because of the shape of your inputs/outputs. But that gets tricker when your the one defining the inputs/outputs for components. I've raised this thread to a docs team, we'll give it a think.
late-airplane-27955
11/25/2024, 1:17 PMit was clear that you use apply when you have to because of the shape of your inputs/outputsSpeaking for myself this was definetely not the case when starting out with Pulumi, it was incredibly confusing and not clear at all (esp fueled by the fact that it doesn't throw even when you're clearly doing something wrong). Now a couple of months in, it's still not completely clear to me whats going on, I'm still not able to fully "predict" if I have to use apply or not, but it's something I now know I have to look out for.
late-airplane-27955
11/25/2024, 1:20 PMechoing-dinner-19531
11/25/2024, 1:22 PMlate-airplane-27955
11/25/2024, 1:24 PMmode: strict
somewhereechoing-dinner-19531
11/25/2024, 1:25 PMlate-airplane-27955
11/25/2024, 1:28 PM