@friggframework/devtools 2.0.0--canary.393.f4a61c1.0 → 2.0.0--canary.393.5a4db58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -102,6 +102,309 @@ const modifyHandlerPaths = (functions) => {
102
102
  return modifiedFunctions;
103
103
  };
104
104
 
105
+ // Helper function to create VPC infrastructure resources
106
+ const createVPCInfrastructure = (AppDefinition) => {
107
+ const vpcResources = {
108
+ // VPC
109
+ FriggVPC: {
110
+ Type: 'AWS::EC2::VPC',
111
+ Properties: {
112
+ CidrBlock: AppDefinition.vpc.cidrBlock || '10.0.0.0/16',
113
+ EnableDnsHostnames: true,
114
+ EnableDnsSupport: true,
115
+ Tags: [
116
+ { Key: 'Name', Value: '${self:service}-${self:provider.stage}-vpc' }
117
+ ]
118
+ }
119
+ },
120
+
121
+ // Internet Gateway
122
+ FriggInternetGateway: {
123
+ Type: 'AWS::EC2::InternetGateway',
124
+ Properties: {
125
+ Tags: [
126
+ { Key: 'Name', Value: '${self:service}-${self:provider.stage}-igw' }
127
+ ]
128
+ }
129
+ },
130
+
131
+ // Attach Internet Gateway to VPC
132
+ FriggVPCGatewayAttachment: {
133
+ Type: 'AWS::EC2::VPCGatewayAttachment',
134
+ Properties: {
135
+ VpcId: { Ref: 'FriggVPC' },
136
+ InternetGatewayId: { Ref: 'FriggInternetGateway' }
137
+ }
138
+ },
139
+
140
+ // Public Subnet for NAT Gateway
141
+ FriggPublicSubnet: {
142
+ Type: 'AWS::EC2::Subnet',
143
+ Properties: {
144
+ VpcId: { Ref: 'FriggVPC' },
145
+ CidrBlock: '10.0.1.0/24',
146
+ AvailabilityZone: { 'Fn::Select': [0, { 'Fn::GetAZs': '' }] },
147
+ MapPublicIpOnLaunch: true,
148
+ Tags: [
149
+ { Key: 'Name', Value: '${self:service}-${self:provider.stage}-public-subnet' }
150
+ ]
151
+ }
152
+ },
153
+
154
+ // Private Subnet 1 for Lambda
155
+ FriggPrivateSubnet1: {
156
+ Type: 'AWS::EC2::Subnet',
157
+ Properties: {
158
+ VpcId: { Ref: 'FriggVPC' },
159
+ CidrBlock: '10.0.2.0/24',
160
+ AvailabilityZone: { 'Fn::Select': [0, { 'Fn::GetAZs': '' }] },
161
+ Tags: [
162
+ { Key: 'Name', Value: '${self:service}-${self:provider.stage}-private-subnet-1' }
163
+ ]
164
+ }
165
+ },
166
+
167
+ // Private Subnet 2 for Lambda (different AZ for redundancy)
168
+ FriggPrivateSubnet2: {
169
+ Type: 'AWS::EC2::Subnet',
170
+ Properties: {
171
+ VpcId: { Ref: 'FriggVPC' },
172
+ CidrBlock: '10.0.3.0/24',
173
+ AvailabilityZone: { 'Fn::Select': [1, { 'Fn::GetAZs': '' }] },
174
+ Tags: [
175
+ { Key: 'Name', Value: '${self:service}-${self:provider.stage}-private-subnet-2' }
176
+ ]
177
+ }
178
+ },
179
+
180
+ // Elastic IP for NAT Gateway
181
+ FriggNATGatewayEIP: {
182
+ Type: 'AWS::EC2::EIP',
183
+ Properties: {
184
+ Domain: 'vpc',
185
+ Tags: [
186
+ { Key: 'Name', Value: '${self:service}-${self:provider.stage}-nat-eip' }
187
+ ]
188
+ },
189
+ DependsOn: 'FriggVPCGatewayAttachment'
190
+ },
191
+
192
+ // NAT Gateway for private subnet internet access
193
+ FriggNATGateway: {
194
+ Type: 'AWS::EC2::NatGateway',
195
+ Properties: {
196
+ AllocationId: { 'Fn::GetAtt': ['FriggNATGatewayEIP', 'AllocationId'] },
197
+ SubnetId: { Ref: 'FriggPublicSubnet' },
198
+ Tags: [
199
+ { Key: 'Name', Value: '${self:service}-${self:provider.stage}-nat-gateway' }
200
+ ]
201
+ }
202
+ },
203
+
204
+ // Public Route Table
205
+ FriggPublicRouteTable: {
206
+ Type: 'AWS::EC2::RouteTable',
207
+ Properties: {
208
+ VpcId: { Ref: 'FriggVPC' },
209
+ Tags: [
210
+ { Key: 'Name', Value: '${self:service}-${self:provider.stage}-public-rt' }
211
+ ]
212
+ }
213
+ },
214
+
215
+ // Public Route to Internet Gateway
216
+ FriggPublicRoute: {
217
+ Type: 'AWS::EC2::Route',
218
+ Properties: {
219
+ RouteTableId: { Ref: 'FriggPublicRouteTable' },
220
+ DestinationCidrBlock: '0.0.0.0/0',
221
+ GatewayId: { Ref: 'FriggInternetGateway' }
222
+ },
223
+ DependsOn: 'FriggVPCGatewayAttachment'
224
+ },
225
+
226
+ // Associate Public Subnet with Public Route Table
227
+ FriggPublicSubnetRouteTableAssociation: {
228
+ Type: 'AWS::EC2::SubnetRouteTableAssociation',
229
+ Properties: {
230
+ SubnetId: { Ref: 'FriggPublicSubnet' },
231
+ RouteTableId: { Ref: 'FriggPublicRouteTable' }
232
+ }
233
+ },
234
+
235
+ // Private Route Table
236
+ FriggPrivateRouteTable: {
237
+ Type: 'AWS::EC2::RouteTable',
238
+ Properties: {
239
+ VpcId: { Ref: 'FriggVPC' },
240
+ Tags: [
241
+ { Key: 'Name', Value: '${self:service}-${self:provider.stage}-private-rt' }
242
+ ]
243
+ }
244
+ },
245
+
246
+ // Private Route to NAT Gateway
247
+ FriggPrivateRoute: {
248
+ Type: 'AWS::EC2::Route',
249
+ Properties: {
250
+ RouteTableId: { Ref: 'FriggPrivateRouteTable' },
251
+ DestinationCidrBlock: '0.0.0.0/0',
252
+ NatGatewayId: { Ref: 'FriggNATGateway' }
253
+ }
254
+ },
255
+
256
+ // Associate Private Subnet 1 with Private Route Table
257
+ FriggPrivateSubnet1RouteTableAssociation: {
258
+ Type: 'AWS::EC2::SubnetRouteTableAssociation',
259
+ Properties: {
260
+ SubnetId: { Ref: 'FriggPrivateSubnet1' },
261
+ RouteTableId: { Ref: 'FriggPrivateRouteTable' }
262
+ }
263
+ },
264
+
265
+ // Associate Private Subnet 2 with Private Route Table
266
+ FriggPrivateSubnet2RouteTableAssociation: {
267
+ Type: 'AWS::EC2::SubnetRouteTableAssociation',
268
+ Properties: {
269
+ SubnetId: { Ref: 'FriggPrivateSubnet2' },
270
+ RouteTableId: { Ref: 'FriggPrivateRouteTable' }
271
+ }
272
+ },
273
+
274
+ // Security Group for Lambda functions
275
+ FriggLambdaSecurityGroup: {
276
+ Type: 'AWS::EC2::SecurityGroup',
277
+ Properties: {
278
+ GroupDescription: 'Security group for Frigg Lambda functions',
279
+ VpcId: { Ref: 'FriggVPC' },
280
+ SecurityGroupEgress: [
281
+ {
282
+ IpProtocol: 'tcp',
283
+ FromPort: 443,
284
+ ToPort: 443,
285
+ CidrIp: '0.0.0.0/0',
286
+ Description: 'HTTPS outbound'
287
+ },
288
+ {
289
+ IpProtocol: 'tcp',
290
+ FromPort: 80,
291
+ ToPort: 80,
292
+ CidrIp: '0.0.0.0/0',
293
+ Description: 'HTTP outbound'
294
+ },
295
+ {
296
+ IpProtocol: 'tcp',
297
+ FromPort: 53,
298
+ ToPort: 53,
299
+ CidrIp: '0.0.0.0/0',
300
+ Description: 'DNS TCP'
301
+ },
302
+ {
303
+ IpProtocol: 'udp',
304
+ FromPort: 53,
305
+ ToPort: 53,
306
+ CidrIp: '0.0.0.0/0',
307
+ Description: 'DNS UDP'
308
+ }
309
+ ],
310
+ Tags: [
311
+ { Key: 'Name', Value: '${self:service}-${self:provider.stage}-lambda-sg' }
312
+ ]
313
+ }
314
+ }
315
+ };
316
+
317
+ // Add VPC Endpoints for cost optimization
318
+ if (AppDefinition.vpc.enableVPCEndpoints !== false) {
319
+ // S3 Gateway Endpoint (free)
320
+ vpcResources.FriggS3VPCEndpoint = {
321
+ Type: 'AWS::EC2::VPCEndpoint',
322
+ Properties: {
323
+ VpcId: { Ref: 'FriggVPC' },
324
+ ServiceName: 'com.amazonaws.${self:provider.region}.s3',
325
+ VpcEndpointType: 'Gateway',
326
+ RouteTableIds: [
327
+ { Ref: 'FriggPrivateRouteTable' }
328
+ ]
329
+ }
330
+ };
331
+
332
+ // DynamoDB Gateway Endpoint (free)
333
+ vpcResources.FriggDynamoDBVPCEndpoint = {
334
+ Type: 'AWS::EC2::VPCEndpoint',
335
+ Properties: {
336
+ VpcId: { Ref: 'FriggVPC' },
337
+ ServiceName: 'com.amazonaws.${self:provider.region}.dynamodb',
338
+ VpcEndpointType: 'Gateway',
339
+ RouteTableIds: [
340
+ { Ref: 'FriggPrivateRouteTable' }
341
+ ]
342
+ }
343
+ };
344
+
345
+ // KMS Interface Endpoint (paid, but useful if using KMS)
346
+ if (AppDefinition.encryption?.useDefaultKMSForFieldLevelEncryption === true) {
347
+ vpcResources.FriggKMSVPCEndpoint = {
348
+ Type: 'AWS::EC2::VPCEndpoint',
349
+ Properties: {
350
+ VpcId: { Ref: 'FriggVPC' },
351
+ ServiceName: 'com.amazonaws.${self:provider.region}.kms',
352
+ VpcEndpointType: 'Interface',
353
+ SubnetIds: [
354
+ { Ref: 'FriggPrivateSubnet1' },
355
+ { Ref: 'FriggPrivateSubnet2' }
356
+ ],
357
+ SecurityGroupIds: [
358
+ { Ref: 'FriggVPCEndpointSecurityGroup' }
359
+ ],
360
+ PrivateDnsEnabled: true
361
+ }
362
+ };
363
+ }
364
+
365
+ // Secrets Manager Interface Endpoint (paid, but useful for secrets)
366
+ vpcResources.FriggSecretsManagerVPCEndpoint = {
367
+ Type: 'AWS::EC2::VPCEndpoint',
368
+ Properties: {
369
+ VpcId: { Ref: 'FriggVPC' },
370
+ ServiceName: 'com.amazonaws.${self:provider.region}.secretsmanager',
371
+ VpcEndpointType: 'Interface',
372
+ SubnetIds: [
373
+ { Ref: 'FriggPrivateSubnet1' },
374
+ { Ref: 'FriggPrivateSubnet2' }
375
+ ],
376
+ SecurityGroupIds: [
377
+ { Ref: 'FriggVPCEndpointSecurityGroup' }
378
+ ],
379
+ PrivateDnsEnabled: true
380
+ }
381
+ };
382
+
383
+ // Security Group for VPC Endpoints
384
+ vpcResources.FriggVPCEndpointSecurityGroup = {
385
+ Type: 'AWS::EC2::SecurityGroup',
386
+ Properties: {
387
+ GroupDescription: 'Security group for Frigg VPC Endpoints',
388
+ VpcId: { Ref: 'FriggVPC' },
389
+ SecurityGroupIngress: [
390
+ {
391
+ IpProtocol: 'tcp',
392
+ FromPort: 443,
393
+ ToPort: 443,
394
+ SourceSecurityGroupId: { Ref: 'FriggLambdaSecurityGroup' },
395
+ Description: 'HTTPS from Lambda'
396
+ }
397
+ ],
398
+ Tags: [
399
+ { Key: 'Name', Value: '${self:service}-${self:provider.stage}-vpc-endpoint-sg' }
400
+ ]
401
+ }
402
+ };
403
+ }
404
+
405
+ return vpcResources;
406
+ };
407
+
105
408
  const composeServerlessDefinition = (AppDefinition) => {
106
409
  const definition = {
107
410
  frameworkVersion: '>=3.17.0',
@@ -355,16 +658,29 @@ const composeServerlessDefinition = (AppDefinition) => {
355
658
 
356
659
  // VPC Configuration based on App Definition
357
660
  if (AppDefinition.vpc?.enable === true) {
358
- // Create VPC config from App Definition
661
+ // Create VPC config from App Definition or use auto-created resources
359
662
  const vpcConfig = {};
663
+
360
664
  if (AppDefinition.vpc.securityGroupIds) {
665
+ // User provided custom security groups
361
666
  vpcConfig.securityGroupIds = AppDefinition.vpc.securityGroupIds;
667
+ } else {
668
+ // Use auto-created security group
669
+ vpcConfig.securityGroupIds = [{ Ref: 'FriggLambdaSecurityGroup' }];
362
670
  }
671
+
363
672
  if (AppDefinition.vpc.subnetIds) {
673
+ // User provided custom subnets
364
674
  vpcConfig.subnetIds = AppDefinition.vpc.subnetIds;
675
+ } else {
676
+ // Use auto-created private subnets
677
+ vpcConfig.subnetIds = [
678
+ { Ref: 'FriggPrivateSubnet1' },
679
+ { Ref: 'FriggPrivateSubnet2' }
680
+ ];
365
681
  }
366
682
 
367
- // Set VPC config directly (can be overridden by serverless.yml)
683
+ // Set VPC config for Lambda functions
368
684
  definition.provider.vpc = vpcConfig;
369
685
 
370
686
  // Add VPC-related IAM permissions
@@ -379,6 +695,10 @@ const composeServerlessDefinition = (AppDefinition) => {
379
695
  ],
380
696
  Resource: '*'
381
697
  });
698
+
699
+ // Add VPC infrastructure resources to CloudFormation
700
+ const vpcResources = createVPCInfrastructure(AppDefinition);
701
+ Object.assign(definition.resources.Resources, vpcResources);
382
702
  }
383
703
 
384
704
  // Add integration-specific functions and resources
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@friggframework/devtools",
3
3
  "prettier": "@friggframework/prettier-config",
4
- "version": "2.0.0--canary.393.f4a61c1.0",
4
+ "version": "2.0.0--canary.393.5a4db58.0",
5
5
  "dependencies": {
6
6
  "@babel/eslint-parser": "^7.18.9",
7
7
  "@babel/parser": "^7.25.3",
8
8
  "@babel/traverse": "^7.25.3",
9
- "@friggframework/test": "2.0.0--canary.393.f4a61c1.0",
9
+ "@friggframework/test": "2.0.0--canary.393.5a4db58.0",
10
10
  "@hapi/boom": "^10.0.1",
11
11
  "@inquirer/prompts": "^5.3.8",
12
12
  "axios": "^1.7.2",
@@ -27,8 +27,8 @@
27
27
  "serverless-http": "^2.7.0"
28
28
  },
29
29
  "devDependencies": {
30
- "@friggframework/eslint-config": "2.0.0--canary.393.f4a61c1.0",
31
- "@friggframework/prettier-config": "2.0.0--canary.393.f4a61c1.0",
30
+ "@friggframework/eslint-config": "2.0.0--canary.393.5a4db58.0",
31
+ "@friggframework/prettier-config": "2.0.0--canary.393.5a4db58.0",
32
32
  "prettier": "^2.7.1",
33
33
  "serverless": "3.39.0",
34
34
  "serverless-dotenv-plugin": "^6.0.0",
@@ -60,5 +60,5 @@
60
60
  "publishConfig": {
61
61
  "access": "public"
62
62
  },
63
- "gitHead": "f4a61c18c52e1a80a0b1e5bb4aa3eb6faefbf953"
63
+ "gitHead": "5a4db5802fd0ba3ae88a79981d1a9ba7fb2070d1"
64
64
  }