@friggframework/devtools 2.0.0-next.24 → 2.0.0-next.26

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',
@@ -238,6 +541,25 @@ const composeServerlessDefinition = (AppDefinition) => {
238
541
  },
239
542
  ],
240
543
  },
544
+ health: {
545
+ handler: 'node_modules/@friggframework/core/handlers/routers/health.handler',
546
+ events: [
547
+ {
548
+ http: {
549
+ path: '/health',
550
+ method: 'GET',
551
+ cors: true,
552
+ },
553
+ },
554
+ {
555
+ http: {
556
+ path: '/health/{proxy+}',
557
+ method: 'GET',
558
+ cors: true,
559
+ },
560
+ },
561
+ ],
562
+ },
241
563
  },
242
564
  resources: {
243
565
  Resources: {
@@ -353,6 +675,51 @@ const composeServerlessDefinition = (AppDefinition) => {
353
675
  };
354
676
  }
355
677
 
678
+ // VPC Configuration based on App Definition
679
+ if (AppDefinition.vpc?.enable === true) {
680
+ // Create VPC config from App Definition or use auto-created resources
681
+ const vpcConfig = {};
682
+
683
+ if (AppDefinition.vpc.securityGroupIds) {
684
+ // User provided custom security groups
685
+ vpcConfig.securityGroupIds = AppDefinition.vpc.securityGroupIds;
686
+ } else {
687
+ // Use auto-created security group
688
+ vpcConfig.securityGroupIds = [{ Ref: 'FriggLambdaSecurityGroup' }];
689
+ }
690
+
691
+ if (AppDefinition.vpc.subnetIds) {
692
+ // User provided custom subnets
693
+ vpcConfig.subnetIds = AppDefinition.vpc.subnetIds;
694
+ } else {
695
+ // Use auto-created private subnets
696
+ vpcConfig.subnetIds = [
697
+ { Ref: 'FriggPrivateSubnet1' },
698
+ { Ref: 'FriggPrivateSubnet2' }
699
+ ];
700
+ }
701
+
702
+ // Set VPC config for Lambda functions
703
+ definition.provider.vpc = vpcConfig;
704
+
705
+ // Add VPC-related IAM permissions
706
+ definition.provider.iamRoleStatements.push({
707
+ Effect: 'Allow',
708
+ Action: [
709
+ 'ec2:CreateNetworkInterface',
710
+ 'ec2:DescribeNetworkInterfaces',
711
+ 'ec2:DeleteNetworkInterface',
712
+ 'ec2:AttachNetworkInterface',
713
+ 'ec2:DetachNetworkInterface'
714
+ ],
715
+ Resource: '*'
716
+ });
717
+
718
+ // Add VPC infrastructure resources to CloudFormation
719
+ const vpcResources = createVPCInfrastructure(AppDefinition);
720
+ Object.assign(definition.resources.Resources, vpcResources);
721
+ }
722
+
356
723
  // Add integration-specific functions and resources
357
724
  for (const integration of AppDefinition.integrations) {
358
725
  const integrationName = integration.Definition.name;
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-next.24",
4
+ "version": "2.0.0-next.26",
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-next.24",
9
+ "@friggframework/test": "2.0.0-next.26",
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-next.24",
31
- "@friggframework/prettier-config": "2.0.0-next.24",
30
+ "@friggframework/eslint-config": "2.0.0-next.26",
31
+ "@friggframework/prettier-config": "2.0.0-next.26",
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": "b1a00897238f7734a67342a3f72f1e9b6504800f"
63
+ "gitHead": "9b9a6cf25e458ec0033c7f4e4ee1f2128b81599e"
64
64
  }