I’ve got a strange problem. If I create a library ...
# typescript
w
I’ve got a strange problem. If I create a library with a function containing
return new aws.iam.Policy(…)
and call that function from my program then the policy is not created. If I copy that function into my program then it is created. How could that be? I have debugged it and I can’t see any difference.
Oh jesus. It looks like it is because they are loading
@pulumi/aws
from two different places. What a foot gun.
all because one of my workspaces had a different version from the others. geez that’s a bit nasty
l
It's appropriate to have those sorts of libraries require that their providers are passed into them. Having them create their own provider, or rely on a default provider, allows this sort of thing to happen.
Another problem with default providers 🙂 You can accidentally have multiple instances of the "default" provider and it's very hard to detect them.
w
Oh, how do you make them require a provider?
l
Just check for the presence of the
provider
or
providers
opt in all constructors 🙂
w
Ah good to know. I never noticed that. Thanks!
So I tried specifying
provider
in the
opts
but it fails with:
Copy code
error: unknown provider 'urn:pulumi:stack::project::pulumi:providers:aws::foo::04da6b54-80e4-46f7-96ec-b56ff0331ba9' for resource 'urn:pulumi:prod::bottech-infrastructure-bootstrap::aws:iam/group:Group::Administrators'
Any idea why it would do that?
l
Is it coming from another module? I seem to recall there's a weirdness about that. But I can't remember what it is. Try temporarily moving your provider's source into the same directory and see if that resolves it. If it does, then it's a Node issue.
w
I think in this particular case it is the same module. I’m calling
provider: new aws.Provider("foo")
and then pretty much immediately calling
new aws.iam.Group
. So you mean copy the aws provider code?
l
No, that looks all good. I'd made an incorrect assumption: I thought you'd created a dynamic provider and wanted to use that. You've got an instance of the normal AWS provider. In this case, it looks like the problem might be that your provider isn't instantiated correctly. Normally, a provider instance would have all the information needed to connect: a target (account, region) and credentials. If you're just instantiating a provider with none of those things, that's probably the problem.
I don't think it's ever useful to create a provider inline like that. Provider are pretty much always used for many resources, so you need to retain the provider in its own variable.
w
Ah. I thought it was going to use the same as the defaults if I didn’t specify them.
Oh I am assigning it to a shared
CustomResourceOptions
that I use for all resources
l
It will, but there's probably some that you need to specify anyway. I know that AWS really wants you to provide the region over and over again. 🙂
w
Well at least that is something to go on. Thanks!
l
Can you confirm that the provider object is created and is usable? Maybe pass it to one of the read methods like getCallerIdentity? https://www.pulumi.com/registry/packages/aws/api-docs/getcalleridentity/
w
That’s a great idea
Nope it doesn’t work.
Copy code
const id = await aws.getCallerIdentity({}, { provider: new aws.Provider("foo") })
fails with:
Copy code
/Users/jason/src/bottech/infrastructure/node_modules/@pulumi/pulumi/runtime/invoke.js:18
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
                                                         ^
TypeError: Cannot read properties of undefined (reading 'invoke')
    at /Users/jason/src/bottech/infrastructure/node_modules/@pulumi/runtime/invoke.ts:158:25
    at new Promise (<anonymous>)
    at /Users/jason/src/bottech/infrastructure/node_modules/@pulumi/runtime/invoke.ts:157:13
    at Generator.next (<anonymous>)
    at fulfilled (/Users/jason/src/bottech/infrastructure/node_modules/@pulumi/pulumi/runtime/invoke.js:18:58)
Which is not very helpful but at least that’s narrowed the problem
l
Yes, I think you should create the provider to its own variable, so that you can separate exceptions thrown from its constructor from exceptions thrown from other places like getCallerIdentity.
Do you know what is undefined? Is it generator? What is generator?