@friggframework/devtools 2.0.0--canary.428.ade056e.0 → 2.0.0--canary.428.b4a2c90.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.
@@ -976,7 +976,7 @@ const composeServerlessDefinition = async (AppDefinition) => {
976
976
 
977
977
  // Configure KMS grants to reference the created key
978
978
  definition.custom.kmsGrants = {
979
- kmsKeyId: { 'Fn::GetAtt': ['FriggKMSKey', 'Arn'] }
979
+ kmsKeyId: { 'Fn::GetAtt': ['FriggKMSKey', 'Arn'] },
980
980
  };
981
981
  } else {
982
982
  // No key found and createIfNoneFound is not enabled - error
@@ -1086,12 +1086,18 @@ const composeServerlessDefinition = async (AppDefinition) => {
1086
1086
  // ALWAYS manage NAT Gateway through CloudFormation for self-healing
1087
1087
  // This ensures NAT Gateway is always in the correct subnet with proper configuration
1088
1088
 
1089
- // Check if we found a valid NAT Gateway (will be null if in private subnet)
1090
- const needsNewNatGateway = !discoveredResources.existingNatGatewayId;
1089
+ const needsNewNatGateway =
1090
+ (natGatewayMethod ===
1091
+ AppDefinition.vpc.natGateway?.method) ===
1092
+ 'createAndManage';
1091
1093
 
1092
1094
  if (needsNewNatGateway) {
1093
- console.log('Creating CloudFormation-managed NAT Gateway resources...');
1094
- console.log('Note: Any existing misconfigured NAT Gateways will be replaced by CloudFormation');
1095
+ console.log(
1096
+ 'Creating CloudFormation-managed NAT Gateway resources...'
1097
+ );
1098
+ console.log(
1099
+ 'Note: Any existing misconfigured NAT Gateways will be replaced by CloudFormation'
1100
+ );
1095
1101
 
1096
1102
  // Only create EIP if we don't have an existing one available
1097
1103
  if (!discoveredResources.existingElasticIpAllocationId) {
@@ -1111,29 +1117,35 @@ const composeServerlessDefinition = async (AppDefinition) => {
1111
1117
 
1112
1118
  // If no public subnet exists, create one for NAT Gateway placement
1113
1119
  if (!discoveredResources.publicSubnetId) {
1114
- console.log('No public subnet found, creating one for NAT Gateway placement...');
1120
+ console.log(
1121
+ 'No public subnet found, creating one for NAT Gateway placement...'
1122
+ );
1115
1123
 
1116
1124
  // Check if Internet Gateway exists or create one
1117
1125
  if (!discoveredResources.internetGatewayId) {
1118
- definition.resources.Resources.FriggInternetGateway = {
1119
- Type: 'AWS::EC2::InternetGateway',
1120
- Properties: {
1121
- Tags: [
1122
- {
1123
- Key: 'Name',
1124
- Value: '${self:service}-${self:provider.stage}-igw',
1125
- },
1126
- ],
1127
- },
1128
- };
1126
+ definition.resources.Resources.FriggInternetGateway =
1127
+ {
1128
+ Type: 'AWS::EC2::InternetGateway',
1129
+ Properties: {
1130
+ Tags: [
1131
+ {
1132
+ Key: 'Name',
1133
+ Value: '${self:service}-${self:provider.stage}-igw',
1134
+ },
1135
+ ],
1136
+ },
1137
+ };
1129
1138
 
1130
- definition.resources.Resources.FriggIGWAttachment = {
1131
- Type: 'AWS::EC2::VPCGatewayAttachment',
1132
- Properties: {
1133
- VpcId: discoveredResources.defaultVpcId,
1134
- InternetGatewayId: { Ref: 'FriggInternetGateway' },
1135
- },
1136
- };
1139
+ definition.resources.Resources.FriggIGWAttachment =
1140
+ {
1141
+ Type: 'AWS::EC2::VPCGatewayAttachment',
1142
+ Properties: {
1143
+ VpcId: discoveredResources.defaultVpcId,
1144
+ InternetGatewayId: {
1145
+ Ref: 'FriggInternetGateway',
1146
+ },
1147
+ },
1148
+ };
1137
1149
  }
1138
1150
 
1139
1151
  // Create a small public subnet for NAT Gateway
@@ -1141,8 +1153,12 @@ const composeServerlessDefinition = async (AppDefinition) => {
1141
1153
  Type: 'AWS::EC2::Subnet',
1142
1154
  Properties: {
1143
1155
  VpcId: discoveredResources.defaultVpcId,
1144
- CidrBlock: '${self:custom.publicSubnetCidr, "172.31.250.0/24"}', // Small /24 subnet
1145
- AvailabilityZone: '${self:provider.region}a',
1156
+ CidrBlock:
1157
+ AppDefinition.vpc.natGateway
1158
+ ?.publicSubnetCidr || '172.31.250.0/24', // Small /24 subnet
1159
+ AvailabilityZone: {
1160
+ 'Fn::Select': [0, { 'Fn::GetAZs': '' }],
1161
+ },
1146
1162
  MapPublicIpOnLaunch: true,
1147
1163
  Tags: [
1148
1164
  {
@@ -1174,22 +1190,30 @@ const composeServerlessDefinition = async (AppDefinition) => {
1174
1190
  // Add route to Internet Gateway
1175
1191
  definition.resources.Resources.FriggPublicRoute = {
1176
1192
  Type: 'AWS::EC2::Route',
1177
- DependsOn: discoveredResources.internetGatewayId ? [] : 'FriggIGWAttachment',
1193
+ DependsOn: discoveredResources.internetGatewayId
1194
+ ? []
1195
+ : 'FriggIGWAttachment',
1178
1196
  Properties: {
1179
1197
  RouteTableId: { Ref: 'FriggPublicRouteTable' },
1180
1198
  DestinationCidrBlock: '0.0.0.0/0',
1181
- GatewayId: discoveredResources.internetGatewayId || { Ref: 'FriggInternetGateway' },
1199
+ GatewayId:
1200
+ discoveredResources.internetGatewayId || {
1201
+ Ref: 'FriggInternetGateway',
1202
+ },
1182
1203
  },
1183
1204
  };
1184
1205
 
1185
1206
  // Associate public subnet with public route table
1186
- definition.resources.Resources.FriggPublicSubnetRouteTableAssociation = {
1187
- Type: 'AWS::EC2::SubnetRouteTableAssociation',
1188
- Properties: {
1189
- SubnetId: { Ref: 'FriggPublicSubnet' },
1190
- RouteTableId: { Ref: 'FriggPublicRouteTable' },
1191
- },
1192
- };
1207
+ definition.resources.Resources.FriggPublicSubnetRouteTableAssociation =
1208
+ {
1209
+ Type: 'AWS::EC2::SubnetRouteTableAssociation',
1210
+ Properties: {
1211
+ SubnetId: { Ref: 'FriggPublicSubnet' },
1212
+ RouteTableId: {
1213
+ Ref: 'FriggPublicRouteTable',
1214
+ },
1215
+ },
1216
+ };
1193
1217
  }
1194
1218
 
1195
1219
  // ALWAYS create NAT Gateway in CloudFormation for management and self-healing
@@ -1203,7 +1227,9 @@ const composeServerlessDefinition = async (AppDefinition) => {
1203
1227
  'AllocationId',
1204
1228
  ],
1205
1229
  },
1206
- SubnetId: discoveredResources.publicSubnetId || { Ref: 'FriggPublicSubnet' },
1230
+ SubnetId: discoveredResources.publicSubnetId || {
1231
+ Ref: 'FriggPublicSubnet',
1232
+ },
1207
1233
  Tags: [
1208
1234
  {
1209
1235
  Key: 'Name',
@@ -1218,7 +1244,9 @@ const composeServerlessDefinition = async (AppDefinition) => {
1218
1244
  };
1219
1245
  } else {
1220
1246
  // We have an existing valid NAT Gateway - import it into CloudFormation management
1221
- console.log('Found existing NAT Gateway - importing into CloudFormation management for self-healing...');
1247
+ console.log(
1248
+ 'Found existing NAT Gateway - importing into CloudFormation management for self-healing...'
1249
+ );
1222
1250
 
1223
1251
  // Note: CloudFormation will detect if a NAT Gateway already exists with these properties
1224
1252
  // and will adopt it rather than creating a duplicate
@@ -1240,14 +1268,16 @@ const composeServerlessDefinition = async (AppDefinition) => {
1240
1268
  },
1241
1269
  };
1242
1270
 
1243
- definition.resources.Resources.FriggNATRoute = {
1244
- Type: 'AWS::EC2::Route',
1245
- Properties: {
1246
- RouteTableId: { Ref: 'FriggLambdaRouteTable' },
1247
- DestinationCidrBlock: '0.0.0.0/0',
1248
- NatGatewayId: { Ref: 'FriggNATGateway' }, // Always use CloudFormation-managed NAT Gateway
1249
- },
1250
- };
1271
+ if (needsNewNatGateway) {
1272
+ definition.resources.Resources.FriggNATRoute = {
1273
+ Type: 'AWS::EC2::Route',
1274
+ Properties: {
1275
+ RouteTableId: { Ref: 'FriggLambdaRouteTable' },
1276
+ DestinationCidrBlock: '0.0.0.0/0',
1277
+ NatGatewayId: { Ref: 'FriggNATGateway' }, // Always use CloudFormation-managed NAT Gateway
1278
+ },
1279
+ };
1280
+ }
1251
1281
 
1252
1282
  // Associate Lambda subnets with NAT Gateway route table
1253
1283
  // Note: This will only work if the subnets aren't already associated with another route table
@@ -1295,37 +1325,46 @@ const composeServerlessDefinition = async (AppDefinition) => {
1295
1325
  };
1296
1326
 
1297
1327
  // Add KMS VPC endpoint if using KMS encryption
1298
- if (AppDefinition.encryption?.fieldLevelEncryptionMethod === 'kms') {
1328
+ if (
1329
+ AppDefinition.encryption?.fieldLevelEncryptionMethod ===
1330
+ 'kms'
1331
+ ) {
1299
1332
  // Create security group for VPC endpoints if it doesn't exist
1300
- if (!definition.resources.Resources.VPCEndpointSecurityGroup) {
1301
- definition.resources.Resources.VPCEndpointSecurityGroup = {
1302
- Type: 'AWS::EC2::SecurityGroup',
1303
- Properties: {
1304
- GroupDescription: 'Security group for VPC endpoints',
1305
- VpcId: discoveredResources.defaultVpcId,
1306
- SecurityGroupIngress: [
1307
- {
1308
- IpProtocol: 'tcp',
1309
- FromPort: 443,
1310
- ToPort: 443,
1311
- CidrIp: '172.31.0.0/16', // VPC CIDR
1312
- },
1313
- ],
1314
- Tags: [
1315
- {
1316
- Key: 'Name',
1317
- Value: '${self:service}-${self:provider.stage}-vpc-endpoints-sg',
1318
- },
1319
- ],
1320
- },
1321
- };
1333
+ if (
1334
+ !definition.resources.Resources
1335
+ .VPCEndpointSecurityGroup
1336
+ ) {
1337
+ definition.resources.Resources.VPCEndpointSecurityGroup =
1338
+ {
1339
+ Type: 'AWS::EC2::SecurityGroup',
1340
+ Properties: {
1341
+ GroupDescription:
1342
+ 'Security group for VPC endpoints',
1343
+ VpcId: discoveredResources.defaultVpcId,
1344
+ SecurityGroupIngress: [
1345
+ {
1346
+ IpProtocol: 'tcp',
1347
+ FromPort: 443,
1348
+ ToPort: 443,
1349
+ CidrIp: '172.31.0.0/16', // VPC CIDR
1350
+ },
1351
+ ],
1352
+ Tags: [
1353
+ {
1354
+ Key: 'Name',
1355
+ Value: '${self:service}-${self:provider.stage}-vpc-endpoints-sg',
1356
+ },
1357
+ ],
1358
+ },
1359
+ };
1322
1360
  }
1323
1361
 
1324
1362
  definition.resources.Resources.VPCEndpointKMS = {
1325
1363
  Type: 'AWS::EC2::VPCEndpoint',
1326
1364
  Properties: {
1327
1365
  VpcId: discoveredResources.defaultVpcId,
1328
- ServiceName: 'com.amazonaws.${self:provider.region}.kms',
1366
+ ServiceName:
1367
+ 'com.amazonaws.${self:provider.region}.kms',
1329
1368
  VpcEndpointType: 'Interface',
1330
1369
  SubnetIds: vpcConfig.subnetIds,
1331
1370
  SecurityGroupIds: [
@@ -1337,19 +1376,21 @@ const composeServerlessDefinition = async (AppDefinition) => {
1337
1376
 
1338
1377
  // Also add Secrets Manager endpoint if using Secrets Manager
1339
1378
  if (AppDefinition.secretsManager?.enable === true) {
1340
- definition.resources.Resources.VPCEndpointSecretsManager = {
1341
- Type: 'AWS::EC2::VPCEndpoint',
1342
- Properties: {
1343
- VpcId: discoveredResources.defaultVpcId,
1344
- ServiceName: 'com.amazonaws.${self:provider.region}.secretsmanager',
1345
- VpcEndpointType: 'Interface',
1346
- SubnetIds: vpcConfig.subnetIds,
1347
- SecurityGroupIds: [
1348
- { Ref: 'VPCEndpointSecurityGroup' },
1349
- ],
1350
- PrivateDnsEnabled: true,
1351
- },
1352
- };
1379
+ definition.resources.Resources.VPCEndpointSecretsManager =
1380
+ {
1381
+ Type: 'AWS::EC2::VPCEndpoint',
1382
+ Properties: {
1383
+ VpcId: discoveredResources.defaultVpcId,
1384
+ ServiceName:
1385
+ 'com.amazonaws.${self:provider.region}.secretsmanager',
1386
+ VpcEndpointType: 'Interface',
1387
+ SubnetIds: vpcConfig.subnetIds,
1388
+ SecurityGroupIds: [
1389
+ { Ref: 'VPCEndpointSecurityGroup' },
1390
+ ],
1391
+ PrivateDnsEnabled: true,
1392
+ },
1393
+ };
1353
1394
  }
1354
1395
  }
1355
1396
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@friggframework/devtools",
3
3
  "prettier": "@friggframework/prettier-config",
4
- "version": "2.0.0--canary.428.ade056e.0",
4
+ "version": "2.0.0--canary.428.b4a2c90.0",
5
5
  "dependencies": {
6
6
  "@aws-sdk/client-ec2": "^3.835.0",
7
7
  "@aws-sdk/client-kms": "^3.835.0",
@@ -9,8 +9,8 @@
9
9
  "@babel/eslint-parser": "^7.18.9",
10
10
  "@babel/parser": "^7.25.3",
11
11
  "@babel/traverse": "^7.25.3",
12
- "@friggframework/schemas": "2.0.0--canary.428.ade056e.0",
13
- "@friggframework/test": "2.0.0--canary.428.ade056e.0",
12
+ "@friggframework/schemas": "2.0.0--canary.428.b4a2c90.0",
13
+ "@friggframework/test": "2.0.0--canary.428.b4a2c90.0",
14
14
  "@hapi/boom": "^10.0.1",
15
15
  "@inquirer/prompts": "^5.3.8",
16
16
  "axios": "^1.7.2",
@@ -32,8 +32,8 @@
32
32
  "serverless-http": "^2.7.0"
33
33
  },
34
34
  "devDependencies": {
35
- "@friggframework/eslint-config": "2.0.0--canary.428.ade056e.0",
36
- "@friggframework/prettier-config": "2.0.0--canary.428.ade056e.0",
35
+ "@friggframework/eslint-config": "2.0.0--canary.428.b4a2c90.0",
36
+ "@friggframework/prettier-config": "2.0.0--canary.428.b4a2c90.0",
37
37
  "jest": "^30.1.3",
38
38
  "prettier": "^2.7.1",
39
39
  "serverless": "3.39.0",
@@ -66,5 +66,5 @@
66
66
  "publishConfig": {
67
67
  "access": "public"
68
68
  },
69
- "gitHead": "ade056ef7772afeb2d7eae1b90e698feae9cb4c9"
69
+ "gitHead": "b4a2c9027b96e1009f95926205f39044560edc83"
70
70
  }