@friggframework/devtools 2.0.0--canary.490.a6abe40.0 → 2.0.0--canary.490.36b3031.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.
|
@@ -577,11 +577,10 @@ class VpcBuilder extends InfrastructureBuilder {
|
|
|
577
577
|
* Build VPC based on ownership decision
|
|
578
578
|
*
|
|
579
579
|
* For STACK ownership: ALWAYS add definitions to template.
|
|
580
|
-
* CloudFormation idempotency ensures existing resources aren't recreated.
|
|
581
580
|
*/
|
|
582
581
|
buildVpcFromDecision(decision, appDefinition, result) {
|
|
583
582
|
if (decision.ownership === ResourceOwnership.STACK) {
|
|
584
|
-
// For STACK ownership: ALWAYS create definitions
|
|
583
|
+
// For STACK ownership: ALWAYS create definitions
|
|
585
584
|
if (decision.physicalId) {
|
|
586
585
|
console.log(` → Adding VPC definition to template (existing: ${decision.physicalId})`);
|
|
587
586
|
} else {
|
|
@@ -1348,6 +1348,105 @@ describe('VpcBuilder', () => {
|
|
|
1348
1348
|
});
|
|
1349
1349
|
});
|
|
1350
1350
|
|
|
1351
|
+
describe('Full Frontify deployment pattern integration test', () => {
|
|
1352
|
+
it('should correctly handle Frontify production scenario: external VPC + stack routing', async () => {
|
|
1353
|
+
// This test replicates the EXACT Frontify production deployment scenario
|
|
1354
|
+
const appDefinition = {
|
|
1355
|
+
vpc: { enable: true },
|
|
1356
|
+
encryption: { fieldLevelEncryptionMethod: 'kms' },
|
|
1357
|
+
};
|
|
1358
|
+
|
|
1359
|
+
// Actual Frontify discovery results (from production logs)
|
|
1360
|
+
const discoveredResources = {
|
|
1361
|
+
fromCloudFormationStack: true,
|
|
1362
|
+
stackName: 'create-frigg-app-production',
|
|
1363
|
+
existingLogicalIds: [
|
|
1364
|
+
'FriggLambdaSecurityGroup',
|
|
1365
|
+
'FriggLambdaRouteTable',
|
|
1366
|
+
'FriggPrivateRoute',
|
|
1367
|
+
'FriggPrivateSubnet1RouteTableAssociation',
|
|
1368
|
+
'FriggPrivateSubnet2RouteTableAssociation',
|
|
1369
|
+
'FriggS3VPCEndpoint',
|
|
1370
|
+
'FriggDynamoDBVPCEndpoint',
|
|
1371
|
+
'FriggKMSVPCEndpoint'
|
|
1372
|
+
],
|
|
1373
|
+
// Stack resources (from CloudFormation)
|
|
1374
|
+
lambdaSecurityGroupId: 'sg-01002240c6a446202',
|
|
1375
|
+
routeTableId: 'rtb-08af43bbf0775602d',
|
|
1376
|
+
s3VpcEndpointId: 'vpce-0d1ecb2c53ce9b4b8',
|
|
1377
|
+
dynamodbVpcEndpointId: 'vpce-0fb749b207f1020b0',
|
|
1378
|
+
kmsVpcEndpointId: 'vpce-0e38c25155b86de22',
|
|
1379
|
+
// External resources (discovered via queries)
|
|
1380
|
+
defaultVpcId: 'vpc-0cd17c0e06cb28b28',
|
|
1381
|
+
privateSubnetId1: 'subnet-034f6562dbbc16348',
|
|
1382
|
+
privateSubnetId2: 'subnet-0b8be2b82aeb5cdec',
|
|
1383
|
+
existingNatGatewayId: 'nat-022660c36a47e2d79'
|
|
1384
|
+
};
|
|
1385
|
+
|
|
1386
|
+
const result = await vpcBuilder.build(appDefinition, discoveredResources);
|
|
1387
|
+
|
|
1388
|
+
// === ASSERTIONS: Template Structure ===
|
|
1389
|
+
|
|
1390
|
+
// 1. VPC should be external (not in template)
|
|
1391
|
+
expect(result.resources.FriggVPC).toBeUndefined();
|
|
1392
|
+
expect(result.vpcId).toBe('vpc-0cd17c0e06cb28b28');
|
|
1393
|
+
|
|
1394
|
+
// 2. Security Group MUST be in template (stack-managed)
|
|
1395
|
+
expect(result.resources.FriggLambdaSecurityGroup).toBeDefined();
|
|
1396
|
+
expect(result.resources.FriggLambdaSecurityGroup.Type).toBe('AWS::EC2::SecurityGroup');
|
|
1397
|
+
expect(result.vpcConfig.securityGroupIds).toEqual([{ Ref: 'FriggLambdaSecurityGroup' }]);
|
|
1398
|
+
|
|
1399
|
+
// 3. Subnets should be external (use hardcoded IDs, not in template)
|
|
1400
|
+
expect(result.resources.FriggPrivateSubnet1).toBeUndefined();
|
|
1401
|
+
expect(result.resources.FriggPrivateSubnet2).toBeUndefined();
|
|
1402
|
+
expect(result.vpcConfig.subnetIds).toEqual([
|
|
1403
|
+
'subnet-034f6562dbbc16348',
|
|
1404
|
+
'subnet-0b8be2b82aeb5cdec'
|
|
1405
|
+
]);
|
|
1406
|
+
|
|
1407
|
+
// 4. NAT Gateway should be external (not in template)
|
|
1408
|
+
expect(result.resources.FriggNATGateway).toBeUndefined();
|
|
1409
|
+
expect(result.resources.FriggNATGatewayEIP).toBeUndefined();
|
|
1410
|
+
expect(result.natGatewayId).toBe('nat-022660c36a47e2d79');
|
|
1411
|
+
|
|
1412
|
+
// 5. Route table MUST be in template (stack-managed)
|
|
1413
|
+
expect(result.resources.FriggLambdaRouteTable).toBeDefined();
|
|
1414
|
+
expect(result.resources.FriggLambdaRouteTable.Type).toBe('AWS::EC2::RouteTable');
|
|
1415
|
+
|
|
1416
|
+
// 6. Route table associations MUST be in template
|
|
1417
|
+
expect(result.resources.FriggPrivateSubnet1RouteTableAssociation).toBeDefined();
|
|
1418
|
+
expect(result.resources.FriggPrivateSubnet2RouteTableAssociation).toBeDefined();
|
|
1419
|
+
|
|
1420
|
+
// 7. VPC Endpoints MUST be in template (stack-managed, prevents deletion)
|
|
1421
|
+
expect(result.resources.FriggS3VPCEndpoint).toBeDefined();
|
|
1422
|
+
expect(result.resources.FriggS3VPCEndpoint.Properties.VpcEndpointType).toBe('Gateway');
|
|
1423
|
+
|
|
1424
|
+
expect(result.resources.FriggDynamoDBVPCEndpoint).toBeDefined();
|
|
1425
|
+
expect(result.resources.FriggDynamoDBVPCEndpoint.Properties.VpcEndpointType).toBe('Gateway');
|
|
1426
|
+
|
|
1427
|
+
expect(result.resources.FriggKMSVPCEndpoint).toBeDefined();
|
|
1428
|
+
expect(result.resources.FriggKMSVPCEndpoint.Properties.VpcEndpointType).toBe('Interface');
|
|
1429
|
+
|
|
1430
|
+
// 8. VPC Endpoint Security Group needed for interface endpoints
|
|
1431
|
+
expect(result.resources.FriggVPCEndpointSecurityGroup).toBeDefined();
|
|
1432
|
+
|
|
1433
|
+
// === ASSERTIONS: Resource Count ===
|
|
1434
|
+
const resourceKeys = Object.keys(result.resources);
|
|
1435
|
+
const friggResources = resourceKeys.filter(k => k.startsWith('Frigg') || k.startsWith('VPC'));
|
|
1436
|
+
|
|
1437
|
+
// Should have routing infrastructure + endpoints + security groups
|
|
1438
|
+
// NOT full VPC (no FriggVPC, FriggPrivateSubnet1/2, FriggNATGateway)
|
|
1439
|
+
expect(friggResources).toContain('FriggLambdaSecurityGroup');
|
|
1440
|
+
expect(friggResources).toContain('FriggLambdaRouteTable');
|
|
1441
|
+
expect(friggResources).toContain('FriggS3VPCEndpoint');
|
|
1442
|
+
expect(friggResources).toContain('FriggDynamoDBVPCEndpoint');
|
|
1443
|
+
expect(friggResources).toContain('FriggKMSVPCEndpoint');
|
|
1444
|
+
expect(friggResources).not.toContain('FriggVPC');
|
|
1445
|
+
expect(friggResources).not.toContain('FriggPrivateSubnet1');
|
|
1446
|
+
expect(friggResources).not.toContain('FriggNATGateway');
|
|
1447
|
+
});
|
|
1448
|
+
});
|
|
1449
|
+
|
|
1351
1450
|
describe('convertFlatDiscoveryToStructured - CloudFormation query results', () => {
|
|
1352
1451
|
it('should add VPC from CloudFormation query to external array', () => {
|
|
1353
1452
|
const flatDiscovery = {
|
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.490.
|
|
4
|
+
"version": "2.0.0--canary.490.36b3031.0",
|
|
5
5
|
"bin": {
|
|
6
6
|
"frigg": "./frigg-cli/index.js"
|
|
7
7
|
},
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
"@babel/eslint-parser": "^7.18.9",
|
|
17
17
|
"@babel/parser": "^7.25.3",
|
|
18
18
|
"@babel/traverse": "^7.25.3",
|
|
19
|
-
"@friggframework/core": "2.0.0--canary.490.
|
|
20
|
-
"@friggframework/schemas": "2.0.0--canary.490.
|
|
21
|
-
"@friggframework/test": "2.0.0--canary.490.
|
|
19
|
+
"@friggframework/core": "2.0.0--canary.490.36b3031.0",
|
|
20
|
+
"@friggframework/schemas": "2.0.0--canary.490.36b3031.0",
|
|
21
|
+
"@friggframework/test": "2.0.0--canary.490.36b3031.0",
|
|
22
22
|
"@hapi/boom": "^10.0.1",
|
|
23
23
|
"@inquirer/prompts": "^5.3.8",
|
|
24
24
|
"axios": "^1.7.2",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"validate-npm-package-name": "^5.0.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@friggframework/eslint-config": "2.0.0--canary.490.
|
|
50
|
-
"@friggframework/prettier-config": "2.0.0--canary.490.
|
|
49
|
+
"@friggframework/eslint-config": "2.0.0--canary.490.36b3031.0",
|
|
50
|
+
"@friggframework/prettier-config": "2.0.0--canary.490.36b3031.0",
|
|
51
51
|
"aws-sdk-client-mock": "^4.1.0",
|
|
52
52
|
"aws-sdk-client-mock-jest": "^4.1.0",
|
|
53
53
|
"jest": "^30.1.3",
|
|
@@ -79,5 +79,5 @@
|
|
|
79
79
|
"publishConfig": {
|
|
80
80
|
"access": "public"
|
|
81
81
|
},
|
|
82
|
-
"gitHead": "
|
|
82
|
+
"gitHead": "36b30311e062560a65a75a864b880bff01a745e7"
|
|
83
83
|
}
|