If I define vpc property within a Function, is thi...
# sst
r
If I define vpc property within a Function, is this meant to reference existing VPC/subnets etc or is this going to create them?
t
Reference existing
r
Great, thanks
Do you have any examples?
t
I have some old code that was using it, moved to a vpc-less architecture now. Nothing too crazy, just defined a vpc like this:
Copy code
const vpc = new ec2.Vpc(this, "vpc")
This creates the classic public/private subnets and I passed that to the vpc param
f
Or to import an existing VPC:
Copy code
const vpc = ec2.Vpc.fromLookup(this, "iVpc", {
  vpcId: "...",
})
r
Cool, thanks - working on importing an existing one in that way, thank you
Is it possible to set the vpc via defaultFunctionProps? If I try to do this:
Copy code
export default function main(app: <http://sst.App|sst.App>): void {
  // Set default runtime for all functions
  app.setDefaultFunctionProps((stack) => ({
    runtime: 'nodejs14.x',
    vpc: Vpc.fromLookup(stack, 'default-vpc', {
      isDefault: true,
    }),
    securityGroups: [SecurityGroup.fromSecurityGroupId(stack, 'default-sg', 'sg-0083d5584b79deac3')],
  }));

  new OmwOfscBeStack(app, `OmwOfscBeStack-${stage}`);
}
The build fails with
Copy code
Error: There is already a Construct with name 'default-vpc' in OmwOfscBeStack [ttgb-prod-omw-ofsc-be-OmwOfscBeStack-ttgb-prod]
Actually, it doesn't seem to work if I don't use defaults and specify it on more than one function in the stack
f
Hmm.. yeah, the
setDefaultFunctionProps
gets invoked for each Lambda in the stack… and only the first import works b/c you can only import something under the name once
Give this a try
Copy code
const vpcsByStackName = {};
const securityGroupsByStackName = {};

app.setDefaultFunctionProps((stack) => {
  // Get already imported VPC and SG
  let vpc = vpcsByStackName[stack];
  let securityGroup = securityGroupsByStackName[stack];

  // If VPC and SG have not been imported, then import now
  if (!vpc) {
    vpc = Vpc.fromLookup(stack, 'default-vpc', {
      isDefault: true,
    });
    securityGroup = SecurityGroup.fromSecurityGroupId(stack, 'default-sg', 'sg-0083d5584b79deac3');

    vpcsByStackName[stack] = vpc;
    securityGroupsByStackName[stack] = securityGroup;
  }

  // Return the function definition
  return {
    runtime: 'nodejs14.x',
    vpc,
    securityGroups: [securityGroup],
  };
});
This pretty much imports the VPC and the SG only once per stack.
r
Does that mean setDefaultFunctionProps is called once per function, rather than once per stack for all functions?
t
I didn't even know
setDefaultFunctionProps
took a function 😮
f
Yeah. When I first added it, I didn’t expect it to be used this way.
This is a totally valid use case.
Let me know if the above code works for u, I will put in a chance.
r
Thanks Frank, just some TypeScript errors to sort out Type 'Stack' cannot be used as an index type
f
Oh I see.
stack.name
should work
t
Why does this need to be defined like a callback vs just specifying it as an object?
f
@thdxr I’m trying to remember lol
t
Ah I see it's being defined in
main
and not inside a stack. Which means it doesn't have access to
stack
and gets access via a callback. So it's used when you want to define common behavior across stacks that reference stack information
f
Yeah, I don’t recall the exact use case I did this for. But it was for configuring stack specific functions props.
r
I need the VPC and SG to be defined for all functions in the stack, some are part of an API, some are consumers of queues etc. So is this the right place to do that?
f
do you have a “core” stack that creates resources used by others?
r
Not in this case, these are existing legacy resources that need to be used
f
If you were creating the VPC in SST, it’d make sense to create a
CoreStack
and create them there.
r
Yeah, it already exists
f
Since you are importing, it makes sense to import them like this. This is the most convenient way.
This way, it’s guaranteed that ALL `sst.Function`s inherit this setting.
r
Any idea why TypeScript doesn't like the imported values on line 21 and 24 Type 'IVpc' is missing the following properties from type 'Vpc': vpcDefaultNetworkAcl, vpcCidrBlockAssociations, vpcDefaultSecurityGroup, vpcIpv6CidrBlocks, and 32 more Type 'ISecurityGroup' is missing the following properties from type 'SecurityGroup': securityGroupName, securityGroupVpcId, securityGroup, directIngressRules, and 22 more.
Need to reference the interface rather than the class
Copy code
type VpcsByStackName = {
  [key: string]: IVpc;
};
type SecGroupsByStackName = {
  [key: string]: ISecurityGroup;
};
f
Yeah,
Ixxxx
is the imported version of
xxxx
constructs in CDK
r
Getting there! Thanks for all your help