Hello! Has anyone had success with using custom co...
# typescript
b
Hello! Has anyone had success with using custom component resources across multiple projects that are stored outside of those projects? Something like:
Copy code
my-pulumi-project
├── s3.ts
├── index.ts
├── ...
components
└── aws
    └── s3
        └── PrivateS3BucketV2.ts
The project dir includes the following
tsconfig.json
Copy code
...
    "baseUrl": ".",
    "paths": {
      "*": ["node_modules/*", "../components/*"]
    }
  },
  "include": ["index.ts", "../components/**/*.ts"]
}
And I am importing like this:
Copy code
import { PrivateS3BucketV2 } from '../components/aws/s3/PrivateS3BucketV2';
Ive not had much luck with this, seeing errors like
13 INTERNAL: Request message serialization failure: b.Va is not a function
. I am somewhat new to Typescript, am I missing something? Does Pulumi support this sort of pattern?
l
It does. And you can also package your components up and access them that way.
I'd guess that your tsconfig needs some work. Specifying anything in node_modules is not something I've seen before.
Start without a
paths
, that's a convenience thing. Get conveniences working after you've got the full thing right.
b
Thanks for the insight! I applied your suggestion and took another look at this. I don't think this is related to my ts setup, because I can import and use a generic class from that shared folder, the issue just arrises when I try and use a component resource class. For the sake of this discussion, I have a basic component resource that creates an S3 bucket. When importing that class and using it in the main pulumi program, all of the existing resources error out with this sort of message (sanitized). The new S3 bucket is shown in the preview just fine, this seems to only be an issue with existing resources.
Copy code
debug: RegisterResource RPC finished: resource:existing-resource[aws:sns/topic:Topic]; err: Error: 13 INTERNAL: Request message serialization failure: b.Va is not a function, resp: undefined
error: Running program '/Users/me/Repos/x/my-repo/pulumi/base-infra/index.ts' failed with an unhandled exception:
<ref *1> Error: failed to register new resource existing-resource [aws:sns/topic:Topic]: 13 INTERNAL: Request message serialization failure: b.Va is not a function
    at Object.registerResource (/Users/me/Repos/x/my-repo/pulumi/base-infra/node_modules/@pulumi/runtime/resource.ts:508:27)
    at new Resource (/Users/me/Repos/x/my-repo/pulumi/base-infra/node_modules/@pulumi/resource.ts:557:13)
    at new CustomResource (/Users/me/Repos/x/my-repo/pulumi/base-infra/node_modules/@pulumi/resource.ts:1080:9)
    at new Topic (/Users/me/Repos/x/my-repo/pulumi/base-infra/node_modules/@pulumi/sns/topic.ts:321:9)
    at Object.<anonymous> (/Users/me/Repos/x/my-repo/pulumi/base-infra/sns.ts:8:34)
    at Module._compile (node:internal/modules/cjs/loader:1369:14)
    at Module.m._compile (/Users/me/Repos/x/my-repo/pulumi/base-infra/node_modules/ts-node/src/index.ts:439:23)
    at Module._extensions..js (node:internal/modules/cjs/loader:1427:10)
    at Object.require.extensions.<computed> [as .ts] (/Users/me/Repos/x/my-repo/pulumi/base-infra/node_modules/ts-node/src/index.ts:442:12)
    at Module.load (node:internal/modules/cjs/loader:1206:32) {
  promise: Promise { <rejected> [Circular *1] }
}
l
I'm not sure why "existing resources" would be relevant: all resources in a component resource should be managed together, either they're all new or all existing (and created by this component resource). A common error is to have fixed names for resources within component resources, but that doesn't seem the be the case in this instance.
It also looks like you're creating a resource inside a Promise or Output. Would you be able to post the bit of your code that creates this SNS topic? Ideally using the Slack "Text Snippet" feature, as that allows it to be collapsed easily, and offers syntax highlighting.
b
I'm not sure why "existing resources" would be relevant
For more context, the pulumi project I am working in has a set of existing resources, created directly in that project (not component resources). Im noticing some repeated patterns (s3 buckets, etc) that I want to DRY up by writing component resources for. The error above seems to happen for all existing resources, not just the SNS topic or any other specific one, but I can share some more code below. Further troubleshooting, here are some observations; • This issue only happens when the
PrivateS3BucketV2.ts
file is sitting outside of the pulumi project dir. i.e.
/components/aws/s3/PrivateS3BucketV2.ts
. If I move this file into the pulumi project dir (
/pulumi/my-project/PrivateS3BucketV2.ts
) and import it, everything previews fine. • I tried to repro this in a separate project, first creating a few resources, then instantiating the
PrivateS3BucketV2
component resource, and had no issues. Package versions where the same, the only difference was the method in which I auth'd to AWS (profile instead of OIDC provider). Using a profile with the existing project doesn't seem to change anything. Ill include a few things below; •
PrivateS3BucketV2.ts
and its
package.json
• A set of S3 resources that currently throw the error. • Sanitized output of
pulumi preview -d
PrivateS3BucketV2.ts
package.json.js
existingResources.ts
Untitled.txt
l
Are you creating more than one instance of this component response class? Because there's a bug:
Copy code
this.bucket = new aws.s3.BucketV2(
      'bucket', // This will be the same for every bucket and will cause a conflict.
      {
        bucket: args.bucketName,
      },
      { parent: this }
    );
You need to use the name parameter of the component resource to make the name of the child resource unique. https://www.pulumi.com/docs/concepts/resources/components/#creating-child-resources
Also your component type name is invalid.
components:aws:s3:PrivateS3BucketV2
does not conform to the required
<package>:<module>:<type>
format. You want something more like
mycompany:aws:privatebucket
.
b
Appreciate it. I applied those suggestions but no dice. I will probably table this until sometime next week.
l
Ah. I see you're registering the entire object as an output. Try exporting only Outputs as outputs:
Copy code
this.registerOutputs({
      bucketName: this.bucket.bucket, // this.bucket.bucket is an Output<string>; this.bucket is a BucketV2 object.
    });
b
No luck, I tried this with a basic IAM role as well and same thing. Based on that other thread im thinking there is some sort of conflict somewhere in the rest of my program that is causing it, considering I cant repro locally with a small project.
l
Are you registering only outputs? In your original code, you were registering a resource, but it looks like you can register only
Output<string>
,
Output<number>
, etc.
b
Yeah, even if I dont register anything I still see the error.
l
Ah. Hmm. Given that it's been raised at least 3 times in Slack, I'm expecting to see something in GitHub issues about it, but I haven't found it so far...
b
Yeah! That was one of the first places I looked thinking "I can't be the only one with this issue"
c
I just ran into this error today. It's weird though. It happened when I installed a local version of a provider I was working on. The project where I wanted to test it already had its
node_modules
installed using
npm
. Then I ran
yarn link ...
to install a local version of the provider I was working on. Once I did that a
StackReference
I had in the project broke with a very similar error message, specifically it's the
b.Va is not a function
part that I recognized. Of course, in my case I know that under normal conditions (no locally-built provider installed) it works fine so I didn't spend any time debugging it.
b
Closing the loop on this for anyone that comes across it in the future. The issue for me ended up being a package (pulumi/pulumi and pulumi/aws, etc.) version mismatch between the versions used in the Pulumi project, and the versions used by the shared packages. Aligning those versions solved the issue.
116 Views