https://pulumi.com logo
Title
g

great-sunset-355

12/14/2021, 9:52 AM
Hi, can anyone explain to me how does
pulumi.ResourceOptions(providers={mapping}
work? I looked at the type description but it's not helpful and nor is the docstring. Because when the resource is created like this:
opts = pulumi.ResourceOptions(
                parent=self,
                                   provider=classic_aws_provider,
            )
and later on
opts
is modified to use
providers
parameter
opts- pulumi.ResourceOptions(
                parent=self,
                                   providers={'aws':classic_aws_provider, 'aws-native':aws_native_provider},
            )
Pulumi results in creating
default
aws provider and completely ignore
providers
p

prehistoric-activity-61023

12/14/2021, 10:06 AM
let me check my projects, I think I’ve got one where I needed to use 2 providers
ok, I see that
providers
is of type:
Optional[Union[Mapping[str, 'ProviderResource'], List['ProviderResource']]]
and I actually used a list (every provider is a different type so you don’t need to name them)
but I think your approach should work as well
can you try to pass these providers as list and see if that helps?
...
   providers=[classic_aws_provider, aws_native_provider])
...
keep in mind that resources inherit their parent providers so in most cases, you don’t need to explicitly specify providers in child resources (or within ComponentResource classes where you usually assign
self
as a parent)
btw, there’s also a note saying:
Note: do not provide both provider and providers.
If the tip above doesn’t work, could you explain what you meant by:
and later on 
opts
 is modified to use 
providers
 parameter
I’m afraid you might somehow set both parameters and that’s the root cause of this.
g

great-sunset-355

12/14/2021, 10:25 AM
P.S.
you don’t need to explicitly specify providers
- this lead to many problems that created a silent default provider for whatever reason and that's what I want to avoid. I also tried the
list
and it did not go well. Because pulumi silently used a
default
provider. This is what I'm trying to achieve, but I may be misunderstanding something
self._opts = pulumi.ResourceOptions.merge(
            opts,
            pulumi.ResourceOptions(
                parent=self,
                providers=[aws_classic_provider, aws_native_provider],
            ),
        )

        classic_role = aws_classic.iam.Role(
            f"{self._config.name}-classic-role",
            args=aws_classic.iam.RoleArgs(assume_role_policy=json.dumps(assume_policy), tags=self._config.tags),
            opts=self._opts,    # here I expect Pulumi to pick my classic provider
        )

        native_role = aws_native.iam.Role(
            f"{self._config.name}-native-role",
            args=aws_native.iam.RoleArgs(
                assume_role_policy_document=assume_policy
            ),
            opts=self._opts  # here I expect my native provider
        )
but the code below ends with
pulumi:providers:aws-native       default_4_32_0                               1 error

pulumi:providers:aws-native (default_4_32_0):
    error: no resource plugin 'aws-native-v4.32.0' found in the workspace or on your $PATH, install the plugin using `pulumi plugin install resource aws-native v4.32.0`
It looks like something is confused by the mapping
p

prehistoric-activity-61023

12/14/2021, 10:58 AM
Regarding the default provider - in my project I stopped using default provider configuration completely. Everything except ResourceComponents (that rely on parent providers) receives explicit providers.
If I find some time, I’ll try to repro it locally on my side. My current guess is that you defined both
provider
and
providers
. Can you add a simple print debugging statement and check how this
self._opts
actually looks like? Plus, can you confirm that these resources are created within ComponentResource definition (this is what I assumed based on
parent=self
)? If so, how are you creating this resource? Do you specify any
opts
in the constructor?
g

great-sunset-355

12/14/2021, 11:19 AM
Regarding the default provider
Yes me too, that's why I inspect the state to make sure that the default provider is not created somehow.
that you defined both provider and providers.
No only
providers
heck how this self._opts actually looks like?, ... ComponentResource definition (this...
yes it is a ComponentResource and I do not pass
provider
to the constructor, nor
providers
. When my ComponentResources need provider I ask for that explicitly rather than assuming it from
opts
.
p

prehistoric-activity-61023

12/14/2021, 11:22 AM
🤔
the other difference I see is that you used
pulumi.ResourceOptions.merge
maybe it’s related to that
g

great-sunset-355

12/14/2021, 11:26 AM
I doubt that. Here is what I got with the
print
{'merge': <bound method ResourceOptions._merge_instance of <pulumi.resource.ResourceOptions object at 0x7f42bfb39910>>, 'parent': <tqs_infrastructure.components.native_fargate.FargateApp object at 0x7f42bfb39370>, 'protect': None, 'provider': None, 'providers': {'aws': <pulumi_aws.provider.Provider object at 0x7f42bfbd2d90>, 'aws-native': <pulumi_aws_native.provider.Provider object at 0x7f42bfb64370>}, 'delete_before_replace': None, 'ignore_changes': None, 'version': None, 'aliases': None, 'additional_secret_outputs': None, 'custom_timeouts': None, 'id': None, 'import_': None, 'transformations': None, 'urn': None, 'replace_on_changes': None, 'depends_on': []}
to me this looks as expected, though the result is unexpected