https://pulumi.com logo
#typescript
Title
# typescript
i

icy-controller-6092

08/24/2022, 10:24 PM
This is more of a typescript question, but I’m trying to create this resource creator bound to a specific region so I can use it with deploying region-specific stacks… but I am getting a typescript error (code in thread)
Copy code
import * as aws from '@pulumi/aws'
import * as pulumi from '@pulumi/pulumi'

export class Builder {
  constructor(private provider: aws.Provider, private nameSuffix: string) {}

  createResource<T extends typeof pulumi.Resource> (
    Resource: T,
    name: string,
    args: ConstructorParameters<T>[1]
  ) {
    const regionalName = `${name}_${this.nameSuffix}`
    return new Resource(name, args, {
      provider: this.provider,
    })
  }
}
l

little-cartoon-10569

08/24/2022, 10:33 PM
Why would you build a class which has the job of passing its parameters to "new"? Is there a case where your code is better when you use this code?
i

icy-controller-6092

08/24/2022, 10:42 PM
I’m doing a deployment of a regional stack of resources, this standardizes how the resources are built (add regional suffix to name, and pass provider into the pulumi
opts
parameter) If I didn’t do it this way, it’s too easy to forget to add a suffix to the resource name, or to forget to pass the provider into a resource constructor (and I want to keep a default provider, because only 20% of my resources are deployed into multiple regions)
l

little-cartoon-10569

08/24/2022, 10:43 PM
You won't be able to add a regional suffix to every name: some resources have very strict naming - lengths, characters allowed, etc. If you do this, then you will also have to codify all the exceptions to it.
i

icy-controller-6092

08/24/2022, 10:43 PM
that’s ok, the only exception right now is my S3 bucket
l

little-cartoon-10569

08/24/2022, 10:43 PM
There will be more. I recommend using a stack transformation or defaultTags to add tags to all resources that you want to add metadata to.
name is the wrong place to store metadata.
i

icy-controller-6092

08/24/2022, 10:44 PM
its only in the name because I need unique resource names, right?
l

little-cartoon-10569

08/24/2022, 10:44 PM
No. The name is used by some resources in additional ways.
And there isn't a list of resources that have special uses for name.
i

icy-controller-6092

08/24/2022, 10:44 PM
It also needs to be unique or I get an error when I go to deploy to the 2nd region, because the resource names are the same
l

little-cartoon-10569

08/24/2022, 10:45 PM
You find out when things don't work.
i

icy-controller-6092

08/24/2022, 10:45 PM
Copy code
const createRegionalBucket = (provider) => {
  return new Bucket('mybucket', {}, { provider })
}

createRegionalBucket(x)
createRegionalBucket(y)
this will fail, because 2 resources have identical resource name
same occurs with
awsx.apigateway.API
l

little-cartoon-10569

08/24/2022, 10:46 PM
They wouldn't be the same if you used Pulumi's naming feature.
You've overridden it.
Do it Pulumi's way: it's for a good reason.
i

icy-controller-6092

08/24/2022, 10:46 PM
There’s no need to be this abbrasive
I was doing it pulumis way to start with and I started seeing these problems
l

little-cartoon-10569

08/24/2022, 10:47 PM
Not trying to be, sorry.
i

icy-controller-6092

08/24/2022, 10:47 PM
that is why I am trying to find a workaround
Copy code
const createRegionalResources (region: aws.Region) => {
  const provider = new aws.Provider(region, { region })
  new Resource1('a', { ... }, { provider })
  new Resource2('b', { ... }, { provider })
  // etc
}
this is how I was doing it to start with, and I was seeing errors with name clashes, not just with the S3 bucket
the code above, is the pulumi way right? Allow pulumi to name the resources?
l

little-cartoon-10569

08/24/2022, 10:51 PM
Try this:
Copy code
onst createRegionalBucket = (name, provider) => {
  return new Bucket(name, {}, { provider })
}

createRegionalBucket("one", x)
createRegionalBucket("two", y)
name is not a suitable field for autogenerating. It should be chosen by the app writer with forethought and good reason. Having library / general code generate a name for you like this does not work with with either Pulumi or cloud providers. I'm not trying to be abrasive: this is advice given from years of experience in this area.
i

icy-controller-6092

08/24/2022, 10:52 PM
The name is not being auto-generated, it is still specified in the code that generates the regional resources. The only thing that is automatically done by the builder is appending the name suffix
l

little-cartoon-10569

08/24/2022, 10:53 PM
The caller of the API (createRegionalResources) has no input into the name of the regional resource. This is what I mean.
i

icy-controller-6092

08/24/2022, 10:53 PM
I only want one line of code per-region, doing it like
createRegionalBucket
for all resources in the regional stack would require a line of code for every resource inside the stack for every region
💯 1
l

little-cartoon-10569

08/24/2022, 10:53 PM
Would multiple stacks, one per region, help?
i

icy-controller-6092

08/24/2022, 10:57 PM
im putting together a repo to show the problem
https://github.com/mattfysh/pulumi-regional-stacks here’s the repo, notice that you cannot push
a
and the
b
folder is how I propose to solve it
l

little-cartoon-10569

08/24/2022, 11:15 PM
Looking now...
🙌 1
Your earlier description was good and accurate.
Is there a reason not to use Pulumi stacks? Do you need to create a collection of identical resources in two regions in the same stack?
i

icy-controller-6092

08/24/2022, 11:19 PM
So only 20% of my resources are deployed to multiple regions… and the other 80% are deployed to a single region the resources that are deployed into mulitple regions, also need to reference some of the other local resources
so it would be something like:
Copy code
const x = createLocalResources()
createRegionalStack('ap-southeast-2, x)
createRegionalStack('us-west-1', x)
l

little-cartoon-10569

08/24/2022, 11:20 PM
Referencing isn't a problem. Projects can reference resources in other projects. You need to group resources by purpose and deployment-cycle. If you have everyone in one chunk of code when they need to be deployed separately / repeatedly, you will have difficulties. You will end up re-implementing Pulumi's core functionality in your code.
It looks like you should have more than one project here. And at least one project should have more than one stack.
I'd be happy to help convert your requirements into a project/stack design.
i

icy-controller-6092

08/24/2022, 11:21 PM
• ok thats a good point, thanks. I’ll try creating a project for the local resources, and then another project for the regionalized API that has a stack for each region
l

little-cartoon-10569

08/24/2022, 11:22 PM
Don't forgot to consider environments, which may be in addition to region. You may want a dev environment, a Europe-prod, a US-prod, etc....
i

icy-controller-6092

08/24/2022, 11:23 PM
thats true -- I need to get around to that soon, everything is prod right now while I race to get the demo built (no users just yet)
l

little-cartoon-10569

08/24/2022, 11:23 PM
"demo prod" == dev!
🙂
And from experience: often when people say "I need a dev environment", what they should be saying is "I need an arbitrary number of dev environments, possibly based on the number of developers or teams that will be working on this code".