@friggframework/devtools 2.0.0--canary.400.545e7a8.0 → 2.0.0--canary.404.e9d4980.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.
- package/frigg-cli/build-command/index.js +2 -4
- package/frigg-cli/deploy-command/index.js +2 -5
- package/frigg-cli/index.js +1 -11
- package/infrastructure/create-frigg-infrastructure.js +2 -2
- package/infrastructure/serverless-template.js +77 -340
- package/package.json +5 -9
- package/frigg-cli/generate-iam-command.js +0 -115
- package/infrastructure/AWS-DISCOVERY-TROUBLESHOOTING.md +0 -245
- package/infrastructure/AWS-IAM-CREDENTIAL-NEEDS.md +0 -596
- package/infrastructure/DEPLOYMENT-INSTRUCTIONS.md +0 -268
- package/infrastructure/GENERATE-IAM-DOCS.md +0 -253
- package/infrastructure/IAM-POLICY-TEMPLATES.md +0 -176
- package/infrastructure/README-TESTING.md +0 -332
- package/infrastructure/README.md +0 -421
- package/infrastructure/WEBSOCKET-CONFIGURATION.md +0 -105
- package/infrastructure/__tests__/fixtures/mock-aws-resources.js +0 -391
- package/infrastructure/__tests__/helpers/test-utils.js +0 -277
- package/infrastructure/aws-discovery.js +0 -568
- package/infrastructure/aws-discovery.test.js +0 -373
- package/infrastructure/build-time-discovery.js +0 -206
- package/infrastructure/build-time-discovery.test.js +0 -375
- package/infrastructure/frigg-deployment-iam-stack.yaml +0 -379
- package/infrastructure/iam-generator.js +0 -687
- package/infrastructure/iam-generator.test.js +0 -169
- package/infrastructure/iam-policy-basic.json +0 -212
- package/infrastructure/iam-policy-full.json +0 -282
- package/infrastructure/integration.test.js +0 -383
- package/infrastructure/run-discovery.js +0 -110
- package/infrastructure/serverless-template.test.js +0 -541
- package/management-ui/dist/assets/FriggLogo-B7Xx8ZW1.svg +0 -1
- package/management-ui/dist/assets/index-CbM64Oba.js +0 -1221
- package/management-ui/dist/assets/index-CkvseXTC.css +0 -1
- package/management-ui/dist/index.html +0 -14
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
const { spawnSync } = require('child_process');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
function buildCommand(options) {
|
|
5
5
|
console.log('Building the serverless application...');
|
|
6
|
-
|
|
7
|
-
// AWS discovery is now handled directly in serverless-template.js
|
|
8
|
-
console.log('📦 Packaging serverless application...');
|
|
6
|
+
console.log('Hello from npm link world')
|
|
9
7
|
const backendPath = path.resolve(process.cwd());
|
|
10
8
|
const infrastructurePath = 'infrastructure.js';
|
|
11
9
|
const command = 'serverless';
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
const { spawn
|
|
1
|
+
const { spawn } = require('child_process');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
function deployCommand(options) {
|
|
5
5
|
console.log('Deploying the serverless application...');
|
|
6
|
-
|
|
7
|
-
// AWS discovery is now handled directly in serverless-template.js
|
|
8
|
-
console.log('🚀 Deploying serverless application...');
|
|
9
6
|
const backendPath = path.resolve(process.cwd());
|
|
10
7
|
const infrastructurePath = 'infrastructure.js';
|
|
11
8
|
const command = 'serverless';
|
package/frigg-cli/index.js
CHANGED
|
@@ -5,7 +5,6 @@ const { installCommand } = require('./install-command');
|
|
|
5
5
|
const { startCommand } = require('./start-command'); // Assuming you have a startCommand module
|
|
6
6
|
const { buildCommand } = require('./build-command');
|
|
7
7
|
const { deployCommand } = require('./deploy-command');
|
|
8
|
-
const { generateIamCommand } = require('./generate-iam-command');
|
|
9
8
|
|
|
10
9
|
const program = new Command();
|
|
11
10
|
program
|
|
@@ -34,15 +33,6 @@ program
|
|
|
34
33
|
.option('-v, --verbose', 'enable verbose output')
|
|
35
34
|
.action(deployCommand);
|
|
36
35
|
|
|
37
|
-
program
|
|
38
|
-
.command('generate-iam')
|
|
39
|
-
.description('Generate IAM CloudFormation template based on app definition')
|
|
40
|
-
.option('-o, --output <path>', 'output directory', 'backend/infrastructure')
|
|
41
|
-
.option('-u, --user <name>', 'deployment user name', 'frigg-deployment-user')
|
|
42
|
-
.option('-s, --stack-name <name>', 'CloudFormation stack name', 'frigg-deployment-iam')
|
|
43
|
-
.option('-v, --verbose', 'enable verbose output')
|
|
44
|
-
.action(generateIamCommand);
|
|
45
|
-
|
|
46
36
|
program.parse(process.argv);
|
|
47
37
|
|
|
48
|
-
module.exports = { installCommand, startCommand, buildCommand, deployCommand
|
|
38
|
+
module.exports = { installCommand, startCommand, buildCommand, deployCommand };
|
|
@@ -4,7 +4,7 @@ const { composeServerlessDefinition } = require('./serverless-template');
|
|
|
4
4
|
|
|
5
5
|
const { findNearestBackendPackageJson } = require('@friggframework/core');
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
function createFriggInfrastructure() {
|
|
8
8
|
const backendPath = findNearestBackendPackageJson();
|
|
9
9
|
if (!backendPath) {
|
|
10
10
|
throw new Error('Could not find backend package.json');
|
|
@@ -23,7 +23,7 @@ async function createFriggInfrastructure() {
|
|
|
23
23
|
// __dirname,
|
|
24
24
|
// './serverless-template.js'
|
|
25
25
|
// ));
|
|
26
|
-
const definition =
|
|
26
|
+
const definition = composeServerlessDefinition(
|
|
27
27
|
appDefinition,
|
|
28
28
|
backend.IntegrationFactory
|
|
29
29
|
);
|
|
@@ -1,26 +1,7 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const fs = require('fs');
|
|
3
|
-
const { AWSDiscovery } = require('./aws-discovery');
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
* Check if AWS discovery should run based on AppDefinition
|
|
7
|
-
* @param {Object} AppDefinition - Application definition
|
|
8
|
-
* @returns {boolean} True if discovery should run
|
|
9
|
-
*/
|
|
10
|
-
const shouldRunDiscovery = (AppDefinition) => {
|
|
11
|
-
return AppDefinition.vpc?.enable === true ||
|
|
12
|
-
AppDefinition.encryption?.useDefaultKMSForFieldLevelEncryption === true ||
|
|
13
|
-
AppDefinition.ssm?.enable === true;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Find the actual path to node_modules directory
|
|
18
|
-
* Tries multiple methods to locate node_modules:
|
|
19
|
-
* 1. Traversing up from current directory
|
|
20
|
-
* 2. Using npm root command
|
|
21
|
-
* 3. Looking for package.json and adjacent node_modules
|
|
22
|
-
* @returns {string} Path to node_modules directory
|
|
23
|
-
*/
|
|
4
|
+
// Function to find the actual path to node_modules
|
|
24
5
|
const findNodeModulesPath = () => {
|
|
25
6
|
try {
|
|
26
7
|
// Method 1: Try to find node_modules by traversing up from current directory
|
|
@@ -94,12 +75,7 @@ const findNodeModulesPath = () => {
|
|
|
94
75
|
}
|
|
95
76
|
};
|
|
96
77
|
|
|
97
|
-
|
|
98
|
-
* Modify handler paths to point to the correct node_modules location
|
|
99
|
-
* Only modifies paths when running in offline mode
|
|
100
|
-
* @param {Object} functions - Serverless functions configuration object
|
|
101
|
-
* @returns {Object} Modified functions object with updated handler paths
|
|
102
|
-
*/
|
|
78
|
+
// Function to modify handler paths to point to the correct node_modules
|
|
103
79
|
const modifyHandlerPaths = (functions) => {
|
|
104
80
|
// Check if we're running in offline mode
|
|
105
81
|
const isOffline = process.argv.includes('offline');
|
|
@@ -118,8 +94,7 @@ const modifyHandlerPaths = (functions) => {
|
|
|
118
94
|
const functionDef = modifiedFunctions[functionName];
|
|
119
95
|
if (functionDef?.handler?.includes('node_modules/')) {
|
|
120
96
|
// Replace node_modules/ with the actual path to node_modules/
|
|
121
|
-
|
|
122
|
-
functionDef.handler = functionDef.handler.replace('node_modules/', `${relativePath}/`);
|
|
97
|
+
functionDef.handler = functionDef.handler.replace('node_modules/', '../node_modules/');
|
|
123
98
|
console.log(`Updated handler for ${functionName}: ${functionDef.handler}`);
|
|
124
99
|
}
|
|
125
100
|
}
|
|
@@ -127,14 +102,7 @@ const modifyHandlerPaths = (functions) => {
|
|
|
127
102
|
return modifiedFunctions;
|
|
128
103
|
};
|
|
129
104
|
|
|
130
|
-
|
|
131
|
-
* Create VPC infrastructure resources for CloudFormation
|
|
132
|
-
* Creates VPC, subnets, NAT gateway, route tables, and security groups
|
|
133
|
-
* @param {Object} AppDefinition - Application definition object
|
|
134
|
-
* @param {Object} AppDefinition.vpc - VPC configuration
|
|
135
|
-
* @param {string} [AppDefinition.vpc.cidrBlock='10.0.0.0/16'] - CIDR block for VPC
|
|
136
|
-
* @returns {Object} CloudFormation resources for VPC infrastructure
|
|
137
|
-
*/
|
|
105
|
+
// Helper function to create VPC infrastructure resources
|
|
138
106
|
const createVPCInfrastructure = (AppDefinition) => {
|
|
139
107
|
const vpcResources = {
|
|
140
108
|
// VPC
|
|
@@ -437,57 +405,7 @@ const createVPCInfrastructure = (AppDefinition) => {
|
|
|
437
405
|
return vpcResources;
|
|
438
406
|
};
|
|
439
407
|
|
|
440
|
-
|
|
441
|
-
* Compose a complete serverless framework configuration from app definition
|
|
442
|
-
* @param {Object} AppDefinition - Application definition object
|
|
443
|
-
* @param {string} [AppDefinition.name] - Application name
|
|
444
|
-
* @param {string} [AppDefinition.provider='aws'] - Cloud provider
|
|
445
|
-
* @param {Array} AppDefinition.integrations - Array of integration definitions
|
|
446
|
-
* @param {Object} [AppDefinition.vpc] - VPC configuration
|
|
447
|
-
* @param {Object} [AppDefinition.encryption] - KMS encryption configuration
|
|
448
|
-
* @param {Object} [AppDefinition.ssm] - SSM parameter store configuration
|
|
449
|
-
* @param {Object} [AppDefinition.websockets] - WebSocket configuration
|
|
450
|
-
* @param {boolean} [AppDefinition.websockets.enable=false] - Enable WebSocket support for live update streaming
|
|
451
|
-
* @returns {Object} Complete serverless framework configuration
|
|
452
|
-
*/
|
|
453
|
-
const composeServerlessDefinition = async (AppDefinition) => {
|
|
454
|
-
// Store discovered resources
|
|
455
|
-
let discoveredResources = {};
|
|
456
|
-
|
|
457
|
-
// Run AWS discovery if needed
|
|
458
|
-
if (shouldRunDiscovery(AppDefinition)) {
|
|
459
|
-
console.log('🔍 Running AWS resource discovery for serverless template...');
|
|
460
|
-
try {
|
|
461
|
-
const region = process.env.AWS_REGION || 'us-east-1';
|
|
462
|
-
const discovery = new AWSDiscovery(region);
|
|
463
|
-
|
|
464
|
-
const config = {
|
|
465
|
-
vpc: AppDefinition.vpc || {},
|
|
466
|
-
encryption: AppDefinition.encryption || {},
|
|
467
|
-
ssm: AppDefinition.ssm || {}
|
|
468
|
-
};
|
|
469
|
-
|
|
470
|
-
discoveredResources = await discovery.discoverResources(config);
|
|
471
|
-
|
|
472
|
-
console.log('✅ AWS discovery completed successfully!');
|
|
473
|
-
if (discoveredResources.defaultVpcId) {
|
|
474
|
-
console.log(` VPC: ${discoveredResources.defaultVpcId}`);
|
|
475
|
-
}
|
|
476
|
-
if (discoveredResources.privateSubnetId1 && discoveredResources.privateSubnetId2) {
|
|
477
|
-
console.log(` Subnets: ${discoveredResources.privateSubnetId1}, ${discoveredResources.privateSubnetId2}`);
|
|
478
|
-
}
|
|
479
|
-
if (discoveredResources.defaultSecurityGroupId) {
|
|
480
|
-
console.log(` Security Group: ${discoveredResources.defaultSecurityGroupId}`);
|
|
481
|
-
}
|
|
482
|
-
if (discoveredResources.defaultKmsKeyId) {
|
|
483
|
-
console.log(` KMS Key: ${discoveredResources.defaultKmsKeyId}`);
|
|
484
|
-
}
|
|
485
|
-
} catch (error) {
|
|
486
|
-
console.error('❌ AWS discovery failed:', error.message);
|
|
487
|
-
throw new Error(`AWS discovery failed: ${error.message}`);
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
|
|
408
|
+
const composeServerlessDefinition = (AppDefinition) => {
|
|
491
409
|
const definition = {
|
|
492
410
|
frameworkVersion: '>=3.17.0',
|
|
493
411
|
service: AppDefinition.name || 'create-frigg-app',
|
|
@@ -500,19 +418,11 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
500
418
|
name: AppDefinition.provider || 'aws',
|
|
501
419
|
runtime: 'nodejs20.x',
|
|
502
420
|
timeout: 30,
|
|
503
|
-
region:
|
|
421
|
+
region: 'us-east-1',
|
|
504
422
|
stage: '${opt:stage}',
|
|
505
423
|
environment: {
|
|
506
424
|
STAGE: '${opt:stage}',
|
|
507
425
|
AWS_NODEJS_CONNECTION_REUSE_ENABLED: 1,
|
|
508
|
-
// Add discovered resources to environment if available
|
|
509
|
-
...(discoveredResources.defaultVpcId && { AWS_DISCOVERY_VPC_ID: discoveredResources.defaultVpcId }),
|
|
510
|
-
...(discoveredResources.defaultSecurityGroupId && { AWS_DISCOVERY_SECURITY_GROUP_ID: discoveredResources.defaultSecurityGroupId }),
|
|
511
|
-
...(discoveredResources.privateSubnetId1 && { AWS_DISCOVERY_SUBNET_ID_1: discoveredResources.privateSubnetId1 }),
|
|
512
|
-
...(discoveredResources.privateSubnetId2 && { AWS_DISCOVERY_SUBNET_ID_2: discoveredResources.privateSubnetId2 }),
|
|
513
|
-
...(discoveredResources.publicSubnetId && { AWS_DISCOVERY_PUBLIC_SUBNET_ID: discoveredResources.publicSubnetId }),
|
|
514
|
-
...(discoveredResources.defaultRouteTableId && { AWS_DISCOVERY_ROUTE_TABLE_ID: discoveredResources.defaultRouteTableId }),
|
|
515
|
-
...(discoveredResources.defaultKmsKeyId && { AWS_DISCOVERY_KMS_KEY_ID: discoveredResources.defaultKmsKeyId }),
|
|
516
426
|
},
|
|
517
427
|
iamRoleStatements: [
|
|
518
428
|
{
|
|
@@ -563,7 +473,7 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
563
473
|
autoCreate: false,
|
|
564
474
|
apiVersion: '2012-11-05',
|
|
565
475
|
endpoint: 'http://localhost:4566',
|
|
566
|
-
region:
|
|
476
|
+
region: 'us-east-1',
|
|
567
477
|
accessKeyId: 'root',
|
|
568
478
|
secretAccessKey: 'root',
|
|
569
479
|
skipCacheInvalidation: false,
|
|
@@ -573,6 +483,26 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
573
483
|
},
|
|
574
484
|
},
|
|
575
485
|
functions: {
|
|
486
|
+
defaultWebsocket: {
|
|
487
|
+
handler: 'node_modules/@friggframework/core/handlers/routers/websocket.handler',
|
|
488
|
+
events: [
|
|
489
|
+
{
|
|
490
|
+
websocket: {
|
|
491
|
+
route: '$connect',
|
|
492
|
+
},
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
websocket: {
|
|
496
|
+
route: '$default',
|
|
497
|
+
},
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
websocket: {
|
|
501
|
+
route: '$disconnect',
|
|
502
|
+
},
|
|
503
|
+
},
|
|
504
|
+
],
|
|
505
|
+
},
|
|
576
506
|
auth: {
|
|
577
507
|
handler: 'node_modules/@friggframework/core/handlers/routers/auth.handler',
|
|
578
508
|
events: [
|
|
@@ -637,7 +567,7 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
637
567
|
Type: 'AWS::SQS::Queue',
|
|
638
568
|
Properties: {
|
|
639
569
|
QueueName:
|
|
640
|
-
'
|
|
570
|
+
'internal-error-queue-${self:provider.stage}',
|
|
641
571
|
MessageRetentionPeriod: 300,
|
|
642
572
|
},
|
|
643
573
|
},
|
|
@@ -721,7 +651,6 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
721
651
|
},
|
|
722
652
|
};
|
|
723
653
|
|
|
724
|
-
|
|
725
654
|
// KMS Configuration based on App Definition
|
|
726
655
|
if (AppDefinition.encryption?.useDefaultKMSForFieldLevelEncryption === true) {
|
|
727
656
|
// Add KMS IAM permissions
|
|
@@ -740,14 +669,39 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
740
669
|
// Add serverless-kms-grants plugin
|
|
741
670
|
definition.plugins.push('serverless-kms-grants');
|
|
742
671
|
|
|
743
|
-
// Configure KMS grants with
|
|
672
|
+
// Configure KMS grants with default key
|
|
744
673
|
definition.custom.kmsGrants = {
|
|
745
|
-
kmsKeyId:
|
|
674
|
+
kmsKeyId: '*'
|
|
746
675
|
};
|
|
747
676
|
}
|
|
748
677
|
|
|
749
678
|
// VPC Configuration based on App Definition
|
|
750
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
|
+
|
|
751
705
|
// Add VPC-related IAM permissions
|
|
752
706
|
definition.provider.iamRoleStatements.push({
|
|
753
707
|
Effect: 'Allow',
|
|
@@ -761,179 +715,17 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
761
715
|
Resource: '*'
|
|
762
716
|
});
|
|
763
717
|
|
|
764
|
-
//
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
const vpcConfig = {};
|
|
768
|
-
|
|
769
|
-
if (AppDefinition.vpc.securityGroupIds) {
|
|
770
|
-
// User provided custom security groups
|
|
771
|
-
vpcConfig.securityGroupIds = AppDefinition.vpc.securityGroupIds;
|
|
772
|
-
} else {
|
|
773
|
-
// Use auto-created security group
|
|
774
|
-
vpcConfig.securityGroupIds = [{ Ref: 'FriggLambdaSecurityGroup' }];
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
if (AppDefinition.vpc.subnetIds) {
|
|
778
|
-
// User provided custom subnets
|
|
779
|
-
vpcConfig.subnetIds = AppDefinition.vpc.subnetIds;
|
|
780
|
-
} else {
|
|
781
|
-
// Use auto-created private subnets
|
|
782
|
-
vpcConfig.subnetIds = [
|
|
783
|
-
{ Ref: 'FriggPrivateSubnet1' },
|
|
784
|
-
{ Ref: 'FriggPrivateSubnet2' }
|
|
785
|
-
];
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
// Set VPC config for Lambda functions
|
|
789
|
-
definition.provider.vpc = vpcConfig;
|
|
790
|
-
|
|
791
|
-
// Add VPC infrastructure resources to CloudFormation
|
|
792
|
-
const vpcResources = createVPCInfrastructure(AppDefinition);
|
|
793
|
-
Object.assign(definition.resources.Resources, vpcResources);
|
|
794
|
-
} else {
|
|
795
|
-
// Option 2: Use AWS Discovery (default behavior)
|
|
796
|
-
// VPC configuration using discovered or explicitly provided resources
|
|
797
|
-
const vpcConfig = {
|
|
798
|
-
securityGroupIds: AppDefinition.vpc.securityGroupIds ||
|
|
799
|
-
(discoveredResources.defaultSecurityGroupId ? [discoveredResources.defaultSecurityGroupId] : []),
|
|
800
|
-
subnetIds: AppDefinition.vpc.subnetIds ||
|
|
801
|
-
(discoveredResources.privateSubnetId1 && discoveredResources.privateSubnetId2 ?
|
|
802
|
-
[discoveredResources.privateSubnetId1, discoveredResources.privateSubnetId2] :
|
|
803
|
-
[])
|
|
804
|
-
};
|
|
805
|
-
|
|
806
|
-
// Set VPC config for Lambda functions only if we have valid subnet IDs
|
|
807
|
-
if (vpcConfig.subnetIds.length >= 2 && vpcConfig.securityGroupIds.length > 0) {
|
|
808
|
-
definition.provider.vpc = vpcConfig;
|
|
809
|
-
|
|
810
|
-
// Check if we have an existing NAT Gateway to use
|
|
811
|
-
if (!discoveredResources.existingNatGatewayId) {
|
|
812
|
-
// No existing NAT Gateway, create new resources
|
|
813
|
-
|
|
814
|
-
// Only create EIP if we don't have an existing one available
|
|
815
|
-
if (!discoveredResources.existingElasticIpAllocationId) {
|
|
816
|
-
definition.resources.Resources.FriggNATGatewayEIP = {
|
|
817
|
-
Type: 'AWS::EC2::EIP',
|
|
818
|
-
Properties: {
|
|
819
|
-
Domain: 'vpc',
|
|
820
|
-
Tags: [
|
|
821
|
-
{ Key: 'Name', Value: '${self:service}-${self:provider.stage}-nat-eip' }
|
|
822
|
-
]
|
|
823
|
-
}
|
|
824
|
-
};
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
definition.resources.Resources.FriggNATGateway = {
|
|
828
|
-
Type: 'AWS::EC2::NatGateway',
|
|
829
|
-
Properties: {
|
|
830
|
-
AllocationId: discoveredResources.existingElasticIpAllocationId ||
|
|
831
|
-
{ 'Fn::GetAtt': ['FriggNATGatewayEIP', 'AllocationId'] },
|
|
832
|
-
SubnetId: discoveredResources.publicSubnetId || discoveredResources.privateSubnetId1, // Use first discovered subnet if no public subnet found
|
|
833
|
-
Tags: [
|
|
834
|
-
{ Key: 'Name', Value: '${self:service}-${self:provider.stage}-nat-gateway' }
|
|
835
|
-
]
|
|
836
|
-
}
|
|
837
|
-
};
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
// Create route table for Lambda subnets to use NAT Gateway
|
|
841
|
-
definition.resources.Resources.FriggLambdaRouteTable = {
|
|
842
|
-
Type: 'AWS::EC2::RouteTable',
|
|
843
|
-
Properties: {
|
|
844
|
-
VpcId: discoveredResources.defaultVpcId || { Ref: 'FriggVPC' },
|
|
845
|
-
Tags: [
|
|
846
|
-
{ Key: 'Name', Value: '${self:service}-${self:provider.stage}-lambda-rt' }
|
|
847
|
-
]
|
|
848
|
-
}
|
|
849
|
-
};
|
|
850
|
-
|
|
851
|
-
definition.resources.Resources.FriggNATRoute = {
|
|
852
|
-
Type: 'AWS::EC2::Route',
|
|
853
|
-
Properties: {
|
|
854
|
-
RouteTableId: { Ref: 'FriggLambdaRouteTable' },
|
|
855
|
-
DestinationCidrBlock: '0.0.0.0/0',
|
|
856
|
-
NatGatewayId: discoveredResources.existingNatGatewayId || { Ref: 'FriggNATGateway' }
|
|
857
|
-
}
|
|
858
|
-
};
|
|
859
|
-
|
|
860
|
-
// Associate Lambda subnets with NAT Gateway route table
|
|
861
|
-
definition.resources.Resources.FriggSubnet1RouteAssociation = {
|
|
862
|
-
Type: 'AWS::EC2::SubnetRouteTableAssociation',
|
|
863
|
-
Properties: {
|
|
864
|
-
SubnetId: vpcConfig.subnetIds[0],
|
|
865
|
-
RouteTableId: { Ref: 'FriggLambdaRouteTable' }
|
|
866
|
-
}
|
|
867
|
-
};
|
|
868
|
-
|
|
869
|
-
definition.resources.Resources.FriggSubnet2RouteAssociation = {
|
|
870
|
-
Type: 'AWS::EC2::SubnetRouteTableAssociation',
|
|
871
|
-
Properties: {
|
|
872
|
-
SubnetId: vpcConfig.subnetIds[1],
|
|
873
|
-
RouteTableId: { Ref: 'FriggLambdaRouteTable' }
|
|
874
|
-
}
|
|
875
|
-
};
|
|
876
|
-
|
|
877
|
-
// Add VPC endpoints for AWS service optimization (optional but recommended)
|
|
878
|
-
if (AppDefinition.vpc.enableVPCEndpoints !== false) {
|
|
879
|
-
definition.resources.Resources.VPCEndpointS3 = {
|
|
880
|
-
Type: 'AWS::EC2::VPCEndpoint',
|
|
881
|
-
Properties: {
|
|
882
|
-
VpcId: discoveredResources.defaultVpcId,
|
|
883
|
-
ServiceName: 'com.amazonaws.${self:provider.region}.s3',
|
|
884
|
-
VpcEndpointType: 'Gateway',
|
|
885
|
-
RouteTableIds: [{ Ref: 'FriggLambdaRouteTable' }]
|
|
886
|
-
}
|
|
887
|
-
};
|
|
888
|
-
|
|
889
|
-
definition.resources.Resources.VPCEndpointDynamoDB = {
|
|
890
|
-
Type: 'AWS::EC2::VPCEndpoint',
|
|
891
|
-
Properties: {
|
|
892
|
-
VpcId: discoveredResources.defaultVpcId,
|
|
893
|
-
ServiceName: 'com.amazonaws.${self:provider.region}.dynamodb',
|
|
894
|
-
VpcEndpointType: 'Gateway',
|
|
895
|
-
RouteTableIds: [{ Ref: 'FriggLambdaRouteTable' }]
|
|
896
|
-
}
|
|
897
|
-
};
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
|
|
903
|
-
// SSM Parameter Store Configuration based on App Definition
|
|
904
|
-
if (AppDefinition.ssm?.enable === true) {
|
|
905
|
-
// Add AWS Parameters and Secrets Lambda Extension layer
|
|
906
|
-
definition.provider.layers = [
|
|
907
|
-
'arn:aws:lambda:${self:provider.region}:177933569100:layer:AWS-Parameters-and-Secrets-Lambda-Extension:11'
|
|
908
|
-
];
|
|
909
|
-
|
|
910
|
-
// Add SSM IAM permissions
|
|
911
|
-
definition.provider.iamRoleStatements.push({
|
|
912
|
-
Effect: 'Allow',
|
|
913
|
-
Action: [
|
|
914
|
-
'ssm:GetParameter',
|
|
915
|
-
'ssm:GetParameters',
|
|
916
|
-
'ssm:GetParametersByPath'
|
|
917
|
-
],
|
|
918
|
-
Resource: [
|
|
919
|
-
'arn:aws:ssm:${self:provider.region}:*:parameter/${self:service}/${self:provider.stage}/*'
|
|
920
|
-
]
|
|
921
|
-
});
|
|
922
|
-
|
|
923
|
-
// Add environment variable for SSM parameter prefix
|
|
924
|
-
definition.provider.environment.SSM_PARAMETER_PREFIX = '/${self:service}/${self:provider.stage}';
|
|
718
|
+
// Add VPC infrastructure resources to CloudFormation
|
|
719
|
+
const vpcResources = createVPCInfrastructure(AppDefinition);
|
|
720
|
+
Object.assign(definition.resources.Resources, vpcResources);
|
|
925
721
|
}
|
|
926
722
|
|
|
927
723
|
// Add integration-specific functions and resources
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
if (!integration || !integration.Definition || !integration.Definition.name) {
|
|
931
|
-
throw new Error('Invalid integration: missing Definition or name');
|
|
932
|
-
}
|
|
933
|
-
const integrationName = integration.Definition.name;
|
|
724
|
+
for (const integration of AppDefinition.integrations) {
|
|
725
|
+
const integrationName = integration.Definition.name;
|
|
934
726
|
|
|
935
|
-
|
|
936
|
-
|
|
727
|
+
// Add function for the integration
|
|
728
|
+
definition.functions[integrationName] = {
|
|
937
729
|
handler: `node_modules/@friggframework/core/handlers/routers/integration-defined-routers.handlers.${integrationName}.handler`,
|
|
938
730
|
events: [
|
|
939
731
|
{
|
|
@@ -946,11 +738,11 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
946
738
|
],
|
|
947
739
|
};
|
|
948
740
|
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
741
|
+
// Add SQS Queue for the integration
|
|
742
|
+
const queueReference = `${integrationName.charAt(0).toUpperCase() + integrationName.slice(1)
|
|
743
|
+
}Queue`;
|
|
744
|
+
const queueName = `\${self:service}--\${self:provider.stage}-${queueReference}`;
|
|
745
|
+
definition.resources.Resources[queueReference] = {
|
|
954
746
|
Type: 'AWS::SQS::Queue',
|
|
955
747
|
Properties: {
|
|
956
748
|
QueueName: `\${self:custom.${queueReference}}`,
|
|
@@ -965,9 +757,9 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
965
757
|
},
|
|
966
758
|
};
|
|
967
759
|
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
760
|
+
// Add Queue Worker for the integration
|
|
761
|
+
const queueWorkerName = `${integrationName}QueueWorker`;
|
|
762
|
+
definition.functions[queueWorkerName] = {
|
|
971
763
|
handler: `node_modules/@friggframework/core/handlers/workers/integration-defined-workers.handlers.${integrationName}.queueWorker`,
|
|
972
764
|
reservedConcurrency: 5,
|
|
973
765
|
events: [
|
|
@@ -983,70 +775,15 @@ const composeServerlessDefinition = async (AppDefinition) => {
|
|
|
983
775
|
timeout: 600,
|
|
984
776
|
};
|
|
985
777
|
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
};
|
|
993
|
-
|
|
994
|
-
definition.custom[queueReference] = queueName;
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
// Discovery has already run successfully at this point if needed
|
|
999
|
-
// The discoveredResources object contains all the necessary AWS resources
|
|
1000
|
-
|
|
1001
|
-
// Add websocket function if enabled
|
|
1002
|
-
if (AppDefinition.websockets?.enable === true) {
|
|
1003
|
-
definition.functions.defaultWebsocket = {
|
|
1004
|
-
handler: 'node_modules/@friggframework/core/handlers/routers/websocket.handler',
|
|
1005
|
-
events: [
|
|
1006
|
-
{
|
|
1007
|
-
websocket: {
|
|
1008
|
-
route: '$connect',
|
|
1009
|
-
},
|
|
1010
|
-
},
|
|
1011
|
-
{
|
|
1012
|
-
websocket: {
|
|
1013
|
-
route: '$default',
|
|
1014
|
-
},
|
|
1015
|
-
},
|
|
1016
|
-
{
|
|
1017
|
-
websocket: {
|
|
1018
|
-
route: '$disconnect',
|
|
1019
|
-
},
|
|
1020
|
-
},
|
|
1021
|
-
],
|
|
778
|
+
// Add Queue URL for the integration to the ENVironment variables
|
|
779
|
+
definition.provider.environment = {
|
|
780
|
+
...definition.provider.environment,
|
|
781
|
+
[`${integrationName.toUpperCase()}_QUEUE_URL`]: {
|
|
782
|
+
Ref: queueReference,
|
|
783
|
+
},
|
|
1022
784
|
};
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
// Discovery has already run successfully at this point if needed
|
|
1026
|
-
// The discoveredResources object contains all the necessary AWS resources
|
|
1027
785
|
|
|
1028
|
-
|
|
1029
|
-
if (AppDefinition.websockets?.enable === true) {
|
|
1030
|
-
definition.functions.defaultWebsocket = {
|
|
1031
|
-
handler: 'node_modules/@friggframework/core/handlers/routers/websocket.handler',
|
|
1032
|
-
events: [
|
|
1033
|
-
{
|
|
1034
|
-
websocket: {
|
|
1035
|
-
route: '$connect',
|
|
1036
|
-
},
|
|
1037
|
-
},
|
|
1038
|
-
{
|
|
1039
|
-
websocket: {
|
|
1040
|
-
route: '$default',
|
|
1041
|
-
},
|
|
1042
|
-
},
|
|
1043
|
-
{
|
|
1044
|
-
websocket: {
|
|
1045
|
-
route: '$disconnect',
|
|
1046
|
-
},
|
|
1047
|
-
},
|
|
1048
|
-
],
|
|
1049
|
-
};
|
|
786
|
+
definition.custom[queueReference] = queueName;
|
|
1050
787
|
}
|
|
1051
788
|
|
|
1052
789
|
// Modify handler paths to point to the correct node_modules location
|
package/package.json
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@friggframework/devtools",
|
|
3
3
|
"prettier": "@friggframework/prettier-config",
|
|
4
|
-
"version": "2.0.0--canary.
|
|
4
|
+
"version": "2.0.0--canary.404.e9d4980.0",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@aws-sdk/client-ec2": "^3.835.0",
|
|
7
|
-
"@aws-sdk/client-kms": "^3.835.0",
|
|
8
|
-
"@aws-sdk/client-sts": "^3.835.0",
|
|
9
6
|
"@babel/eslint-parser": "^7.18.9",
|
|
10
7
|
"@babel/parser": "^7.25.3",
|
|
11
8
|
"@babel/traverse": "^7.25.3",
|
|
12
|
-
"@friggframework/test": "2.0.0--canary.
|
|
9
|
+
"@friggframework/test": "2.0.0--canary.404.e9d4980.0",
|
|
13
10
|
"@hapi/boom": "^10.0.1",
|
|
14
11
|
"@inquirer/prompts": "^5.3.8",
|
|
15
12
|
"axios": "^1.7.2",
|
|
@@ -26,13 +23,12 @@
|
|
|
26
23
|
"express": "^4.19.2",
|
|
27
24
|
"express-async-handler": "^1.2.0",
|
|
28
25
|
"fs-extra": "^11.2.0",
|
|
29
|
-
"js-yaml": "^4.1.0",
|
|
30
26
|
"lodash": "4.17.21",
|
|
31
27
|
"serverless-http": "^2.7.0"
|
|
32
28
|
},
|
|
33
29
|
"devDependencies": {
|
|
34
|
-
"@friggframework/eslint-config": "2.0.0--canary.
|
|
35
|
-
"@friggframework/prettier-config": "2.0.0--canary.
|
|
30
|
+
"@friggframework/eslint-config": "2.0.0--canary.404.e9d4980.0",
|
|
31
|
+
"@friggframework/prettier-config": "2.0.0--canary.404.e9d4980.0",
|
|
36
32
|
"prettier": "^2.7.1",
|
|
37
33
|
"serverless": "3.39.0",
|
|
38
34
|
"serverless-dotenv-plugin": "^6.0.0",
|
|
@@ -64,5 +60,5 @@
|
|
|
64
60
|
"publishConfig": {
|
|
65
61
|
"access": "public"
|
|
66
62
|
},
|
|
67
|
-
"gitHead": "
|
|
63
|
+
"gitHead": "e9d4980828d7deda79e33dfbb2fed93cb6fef84d"
|
|
68
64
|
}
|