This is more of a typescript question, but I’m try...
# typescript
i
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
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
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
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
that’s ok, the only exception right now is my S3 bucket
l
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
its only in the name because I need unique resource names, right?
l
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
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
You find out when things don't work.
i
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
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
There’s no need to be this abbrasive
I was doing it pulumis way to start with and I started seeing these problems
l
Not trying to be, sorry.
i
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
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
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
The caller of the API (createRegionalResources) has no input into the name of the regional resource. This is what I mean.
i
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
Would multiple stacks, one per region, help?
i
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
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
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
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
• 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
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
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
"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".