@friggframework/devtools 2.0.0--canary.428.4dfa677.0 → 2.0.0--canary.428.49aae81.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.
|
@@ -388,27 +388,44 @@ class AWSDiscovery {
|
|
|
388
388
|
}
|
|
389
389
|
]
|
|
390
390
|
});
|
|
391
|
-
|
|
391
|
+
|
|
392
392
|
const response = await this.ec2Client.send(command);
|
|
393
|
-
|
|
393
|
+
|
|
394
394
|
if (response.NatGateways && response.NatGateways.length > 0) {
|
|
395
|
-
//
|
|
396
|
-
const
|
|
397
|
-
|
|
395
|
+
// Check each NAT Gateway to ensure it's in a public subnet
|
|
396
|
+
for (const natGateway of response.NatGateways) {
|
|
397
|
+
const subnetId = natGateway.SubnetId;
|
|
398
|
+
const isPrivate = await this.isSubnetPrivate(subnetId);
|
|
399
|
+
|
|
400
|
+
if (isPrivate) {
|
|
401
|
+
console.warn(`WARNING: NAT Gateway ${natGateway.NatGatewayId} is in private subnet ${subnetId} - this will not work!`);
|
|
402
|
+
console.warn('NAT Gateways MUST be placed in public subnets with Internet Gateway routes');
|
|
403
|
+
console.warn('Skipping this misconfigured NAT Gateway...');
|
|
404
|
+
continue; // Skip this NAT Gateway
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Check if it's a Frigg-tagged NAT Gateway
|
|
408
|
+
const isFriggNat = natGateway.Tags && natGateway.Tags.some(tag =>
|
|
398
409
|
tag.Key === 'Name' && tag.Value.includes('frigg')
|
|
399
|
-
)
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
410
|
+
);
|
|
411
|
+
|
|
412
|
+
if (isFriggNat) {
|
|
413
|
+
console.log(`Found existing Frigg NAT Gateway in public subnet: ${natGateway.NatGatewayId}`);
|
|
414
|
+
return natGateway;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Keep track of first valid NAT Gateway as fallback
|
|
418
|
+
console.log(`Found existing NAT Gateway in public subnet: ${natGateway.NatGatewayId}`);
|
|
419
|
+
return natGateway; // Return first NAT Gateway that's in a public subnet
|
|
405
420
|
}
|
|
406
|
-
|
|
407
|
-
//
|
|
408
|
-
console.
|
|
409
|
-
|
|
421
|
+
|
|
422
|
+
// All NAT Gateways are in private subnets - don't use any of them
|
|
423
|
+
console.error(`ERROR: Found ${response.NatGateways.length} NAT Gateway(s) but all are in private subnets!`);
|
|
424
|
+
console.error('These NAT Gateways will not provide internet connectivity');
|
|
425
|
+
console.error('A new NAT Gateway will be created in a public subnet');
|
|
426
|
+
return null; // Return null to trigger creation of new NAT Gateway
|
|
410
427
|
}
|
|
411
|
-
|
|
428
|
+
|
|
412
429
|
return null;
|
|
413
430
|
} catch (error) {
|
|
414
431
|
console.warn('Error finding existing NAT Gateway:', error.message);
|
|
@@ -1083,9 +1083,15 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
1083
1083
|
) {
|
|
1084
1084
|
definition.provider.vpc = vpcConfig;
|
|
1085
1085
|
|
|
1086
|
-
//
|
|
1087
|
-
|
|
1088
|
-
|
|
1086
|
+
// ALWAYS manage NAT Gateway through CloudFormation for self-healing
|
|
1087
|
+
// This ensures NAT Gateway is always in the correct subnet with proper configuration
|
|
1088
|
+
|
|
1089
|
+
// Check if we found a valid NAT Gateway (will be null if in private subnet)
|
|
1090
|
+
const needsNewNatGateway = !discoveredResources.existingNatGatewayId;
|
|
1091
|
+
|
|
1092
|
+
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');
|
|
1089
1095
|
|
|
1090
1096
|
// Only create EIP if we don't have an existing one available
|
|
1091
1097
|
if (!discoveredResources.existingElasticIpAllocationId) {
|
|
@@ -1186,6 +1192,7 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
1186
1192
|
};
|
|
1187
1193
|
}
|
|
1188
1194
|
|
|
1195
|
+
// ALWAYS create NAT Gateway in CloudFormation for management and self-healing
|
|
1189
1196
|
definition.resources.Resources.FriggNATGateway = {
|
|
1190
1197
|
Type: 'AWS::EC2::NatGateway',
|
|
1191
1198
|
Properties: {
|
|
@@ -1202,9 +1209,19 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
1202
1209
|
Key: 'Name',
|
|
1203
1210
|
Value: '${self:service}-${self:provider.stage}-nat-gateway',
|
|
1204
1211
|
},
|
|
1212
|
+
{
|
|
1213
|
+
Key: 'ManagedBy',
|
|
1214
|
+
Value: 'CloudFormation',
|
|
1215
|
+
},
|
|
1205
1216
|
],
|
|
1206
1217
|
},
|
|
1207
1218
|
};
|
|
1219
|
+
} else {
|
|
1220
|
+
// 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...');
|
|
1222
|
+
|
|
1223
|
+
// Note: CloudFormation will detect if a NAT Gateway already exists with these properties
|
|
1224
|
+
// and will adopt it rather than creating a duplicate
|
|
1208
1225
|
}
|
|
1209
1226
|
|
|
1210
1227
|
// Create route table for Lambda subnets to use NAT Gateway
|
|
@@ -1228,10 +1245,7 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
1228
1245
|
Properties: {
|
|
1229
1246
|
RouteTableId: { Ref: 'FriggLambdaRouteTable' },
|
|
1230
1247
|
DestinationCidrBlock: '0.0.0.0/0',
|
|
1231
|
-
NatGatewayId:
|
|
1232
|
-
discoveredResources.existingNatGatewayId || {
|
|
1233
|
-
Ref: 'FriggNATGateway',
|
|
1234
|
-
},
|
|
1248
|
+
NatGatewayId: { Ref: 'FriggNATGateway' }, // Always use CloudFormation-managed NAT Gateway
|
|
1235
1249
|
},
|
|
1236
1250
|
};
|
|
1237
1251
|
|
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.
|
|
4
|
+
"version": "2.0.0--canary.428.49aae81.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.
|
|
13
|
-
"@friggframework/test": "2.0.0--canary.428.
|
|
12
|
+
"@friggframework/schemas": "2.0.0--canary.428.49aae81.0",
|
|
13
|
+
"@friggframework/test": "2.0.0--canary.428.49aae81.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.
|
|
36
|
-
"@friggframework/prettier-config": "2.0.0--canary.428.
|
|
35
|
+
"@friggframework/eslint-config": "2.0.0--canary.428.49aae81.0",
|
|
36
|
+
"@friggframework/prettier-config": "2.0.0--canary.428.49aae81.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": "
|
|
69
|
+
"gitHead": "49aae81fe3bcaa900ee17e46e8d34413a830832b"
|
|
70
70
|
}
|