@friggframework/devtools 2.0.0--canary.414.db76eeb.0 → 2.0.0--canary.417.1ca8d39.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.
|
@@ -1,13 +1,23 @@
|
|
|
1
|
-
const { spawn
|
|
1
|
+
const { spawn } = require('child_process');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
|
|
5
|
+
// Configuration constants
|
|
6
|
+
const PATHS = {
|
|
7
|
+
APP_DEFINITION: 'index.js',
|
|
8
|
+
INFRASTRUCTURE: 'infrastructure.js'
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const COMMANDS = {
|
|
12
|
+
SERVERLESS: 'serverless'
|
|
13
|
+
};
|
|
14
|
+
|
|
5
15
|
/**
|
|
6
16
|
* Constructs filtered environment variables for serverless deployment
|
|
7
|
-
* @param {string[]}
|
|
17
|
+
* @param {string[]} appDefinedVariables - Array of environment variable names from app definition
|
|
8
18
|
* @returns {Object} Filtered environment variables object
|
|
9
19
|
*/
|
|
10
|
-
function buildFilteredEnvironment(
|
|
20
|
+
function buildFilteredEnvironment(appDefinedVariables) {
|
|
11
21
|
return {
|
|
12
22
|
// Essential system variables needed to run serverless
|
|
13
23
|
PATH: process.env.PATH,
|
|
@@ -23,116 +33,123 @@ function buildFilteredEnvironment(envVars) {
|
|
|
23
33
|
|
|
24
34
|
// App-defined environment variables
|
|
25
35
|
...Object.fromEntries(
|
|
26
|
-
|
|
36
|
+
appDefinedVariables
|
|
27
37
|
.map((key) => [key, process.env[key]])
|
|
28
38
|
.filter(([_, value]) => value !== undefined)
|
|
29
39
|
),
|
|
30
40
|
};
|
|
31
41
|
}
|
|
32
42
|
|
|
33
|
-
|
|
34
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Loads and parses the app definition from index.js
|
|
45
|
+
* @returns {Object|null} App definition object or null if not found
|
|
46
|
+
*/
|
|
47
|
+
function loadAppDefinition() {
|
|
48
|
+
const appDefPath = path.join(process.cwd(), PATHS.APP_DEFINITION);
|
|
49
|
+
|
|
50
|
+
if (!fs.existsSync(appDefPath)) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const { Definition } = require(appDefPath);
|
|
56
|
+
return Definition;
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.warn('Could not load appDefinition environment config:', error.message);
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Extracts environment variable names from app definition
|
|
65
|
+
* @param {Object} appDefinition - App definition object
|
|
66
|
+
* @returns {string[]} Array of environment variable names
|
|
67
|
+
*/
|
|
68
|
+
function extractEnvironmentVariables(appDefinition) {
|
|
69
|
+
if (!appDefinition?.environment) {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
console.log('🔧 Loading environment configuration from appDefinition...');
|
|
74
|
+
|
|
75
|
+
const appDefinedVariables = Object.keys(appDefinition.environment).filter(
|
|
76
|
+
(key) => appDefinition.environment[key] === true
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
console.log(` Found ${appDefinedVariables.length} environment variables: ${appDefinedVariables.join(', ')}`);
|
|
80
|
+
return appDefinedVariables;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Handles environment validation warnings
|
|
85
|
+
* @param {Object} validation - Validation result object
|
|
86
|
+
* @param {Object} options - Deploy command options
|
|
87
|
+
*/
|
|
88
|
+
function handleValidationWarnings(validation, options) {
|
|
89
|
+
if (validation.missing.length === 0 || options.skipEnvValidation) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
console.warn(`⚠️ Warning: Missing ${validation.missing.length} environment variables: ${validation.missing.join(', ')}`);
|
|
94
|
+
console.warn(' These variables are optional and deployment will continue');
|
|
95
|
+
console.warn(' Run with --skip-env-validation to bypass this check');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Validates environment variables and builds filtered environment
|
|
100
|
+
* @param {Object} appDefinition - App definition object
|
|
101
|
+
* @param {Object} options - Deploy command options
|
|
102
|
+
* @returns {Object} Filtered environment variables
|
|
103
|
+
*/
|
|
104
|
+
function validateAndBuildEnvironment(appDefinition, options) {
|
|
105
|
+
if (!appDefinition) {
|
|
106
|
+
return buildFilteredEnvironment([]);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const appDefinedVariables = extractEnvironmentVariables(appDefinition);
|
|
110
|
+
|
|
111
|
+
// Try to use the env-validator if available
|
|
112
|
+
try {
|
|
113
|
+
const { validateEnvironmentVariables } = require('@friggframework/devtools/infrastructure/env-validator');
|
|
114
|
+
const validation = validateEnvironmentVariables(appDefinition);
|
|
115
|
+
|
|
116
|
+
handleValidationWarnings(validation, options);
|
|
117
|
+
return buildFilteredEnvironment(appDefinedVariables);
|
|
35
118
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (Definition.environment) {
|
|
46
|
-
console.log(
|
|
47
|
-
'🔧 Loading environment configuration from appDefinition...'
|
|
48
|
-
);
|
|
49
|
-
const envVars = Object.keys(Definition.environment).filter(
|
|
50
|
-
(key) => Definition.environment[key] === true
|
|
51
|
-
);
|
|
52
|
-
console.log(
|
|
53
|
-
` Found ${
|
|
54
|
-
envVars.length
|
|
55
|
-
} environment variables: ${envVars.join(', ')}`
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
// Try to use the env-validator if available
|
|
59
|
-
try {
|
|
60
|
-
const {
|
|
61
|
-
validateEnvironmentVariables,
|
|
62
|
-
} = require('@friggframework/devtools/infrastructure/env-validator');
|
|
63
|
-
const validation = validateEnvironmentVariables(Definition);
|
|
64
|
-
|
|
65
|
-
if (
|
|
66
|
-
validation.missing.length > 0 &&
|
|
67
|
-
!options.skipEnvValidation
|
|
68
|
-
) {
|
|
69
|
-
console.warn(
|
|
70
|
-
`⚠️ Warning: Missing ${
|
|
71
|
-
validation.missing.length
|
|
72
|
-
} environment variables: ${validation.missing.join(
|
|
73
|
-
', '
|
|
74
|
-
)}`
|
|
75
|
-
);
|
|
76
|
-
console.warn(
|
|
77
|
-
' These variables are optional and deployment will continue'
|
|
78
|
-
);
|
|
79
|
-
console.warn(
|
|
80
|
-
' Run with --skip-env-validation to bypass this check'
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Pass essential system variables + AWS credentials + app-defined environment variables
|
|
85
|
-
integrationEnvironmentVariables =
|
|
86
|
-
buildFilteredEnvironment(envVars);
|
|
87
|
-
} catch (validatorError) {
|
|
88
|
-
// Validator not available in current version, just warn
|
|
89
|
-
const missing = envVars.filter((v) => !process.env[v]);
|
|
90
|
-
if (missing.length > 0) {
|
|
91
|
-
console.warn(
|
|
92
|
-
`⚠️ Warning: Missing ${
|
|
93
|
-
missing.length
|
|
94
|
-
} environment variables: ${missing.join(', ')}`
|
|
95
|
-
);
|
|
96
|
-
console.warn(
|
|
97
|
-
' These variables are optional and deployment will continue'
|
|
98
|
-
);
|
|
99
|
-
console.warn(
|
|
100
|
-
' Set them in your CI/CD environment or .env file if needed'
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Pass essential system variables + AWS credentials + app-defined environment variables
|
|
105
|
-
integrationEnvironmentVariables =
|
|
106
|
-
buildFilteredEnvironment(envVars);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
} catch (error) {
|
|
110
|
-
console.warn(
|
|
111
|
-
'Could not load appDefinition environment config:',
|
|
112
|
-
error.message
|
|
113
|
-
);
|
|
114
|
-
// Keep all env vars if we can't validate
|
|
119
|
+
} catch (validatorError) {
|
|
120
|
+
// Validator not available, do basic validation
|
|
121
|
+
const missingVariables = appDefinedVariables.filter((variable) => !process.env[variable]);
|
|
122
|
+
|
|
123
|
+
if (missingVariables.length > 0) {
|
|
124
|
+
console.warn(`⚠️ Warning: Missing ${missingVariables.length} environment variables: ${missingVariables.join(', ')}`);
|
|
125
|
+
console.warn(' These variables are optional and deployment will continue');
|
|
126
|
+
console.warn(' Set them in your CI/CD environment or .env file if needed');
|
|
115
127
|
}
|
|
128
|
+
|
|
129
|
+
return buildFilteredEnvironment(appDefinedVariables);
|
|
116
130
|
}
|
|
131
|
+
}
|
|
117
132
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
133
|
+
/**
|
|
134
|
+
* Executes the serverless deployment command
|
|
135
|
+
* @param {Object} environment - Environment variables to pass to serverless
|
|
136
|
+
* @param {Object} options - Deploy command options
|
|
137
|
+
*/
|
|
138
|
+
function executeServerlessDeployment(environment, options) {
|
|
139
|
+
console.log('🚀 Deploying serverless application...');
|
|
140
|
+
|
|
123
141
|
const serverlessArgs = [
|
|
124
142
|
'deploy',
|
|
125
143
|
'--config',
|
|
126
|
-
|
|
144
|
+
PATHS.INFRASTRUCTURE,
|
|
127
145
|
'--stage',
|
|
128
146
|
options.stage,
|
|
129
|
-
options.stage,
|
|
130
147
|
];
|
|
131
148
|
|
|
132
|
-
const childProcess = spawn(
|
|
133
|
-
cwd:
|
|
149
|
+
const childProcess = spawn(COMMANDS.SERVERLESS, serverlessArgs, {
|
|
150
|
+
cwd: path.resolve(process.cwd()),
|
|
134
151
|
stdio: 'inherit',
|
|
135
|
-
env:
|
|
152
|
+
env: environment,
|
|
136
153
|
});
|
|
137
154
|
|
|
138
155
|
childProcess.on('error', (error) => {
|
|
@@ -146,4 +163,13 @@ async function deployCommand(options) {
|
|
|
146
163
|
});
|
|
147
164
|
}
|
|
148
165
|
|
|
166
|
+
async function deployCommand(options) {
|
|
167
|
+
console.log('Deploying the serverless application...');
|
|
168
|
+
|
|
169
|
+
const appDefinition = loadAppDefinition();
|
|
170
|
+
const environment = validateAndBuildEnvironment(appDefinition, options);
|
|
171
|
+
|
|
172
|
+
executeServerlessDeployment(environment, options);
|
|
173
|
+
}
|
|
174
|
+
|
|
149
175
|
module.exports = { deployCommand };
|
package/infrastructure/README.md
CHANGED
|
@@ -27,7 +27,7 @@ infrastructure/
|
|
|
27
27
|
├── AWS-DISCOVERY-TROUBLESHOOTING.md # AWS discovery troubleshooting
|
|
28
28
|
├── DEPLOYMENT-INSTRUCTIONS.md # General deployment instructions
|
|
29
29
|
├── README-TESTING.md # Testing strategy documentation
|
|
30
|
-
├──
|
|
30
|
+
├──
|
|
31
31
|
├── cloudformation/ # CloudFormation templates
|
|
32
32
|
│ ├── monitoring-infrastructure.yaml # Enhanced monitoring (Phase 3)
|
|
33
33
|
│ ├── cdn-infrastructure.yaml # CDN and UI distribution (Phase 3)
|
|
@@ -60,71 +60,79 @@ infrastructure/
|
|
|
60
60
|
#### 1. Serverless Template Generator (`serverless-template.js`)
|
|
61
61
|
|
|
62
62
|
Generates complete serverless.yml configurations with:
|
|
63
|
-
|
|
64
|
-
-
|
|
65
|
-
-
|
|
66
|
-
-
|
|
67
|
-
-
|
|
63
|
+
|
|
64
|
+
- VPC configuration and resource discovery
|
|
65
|
+
- KMS encryption for field-level encryption
|
|
66
|
+
- SSM Parameter Store integration
|
|
67
|
+
- Integration-specific functions and queues
|
|
68
|
+
- WebSocket support for real-time features
|
|
68
69
|
|
|
69
70
|
#### 2. AWS Discovery (`aws-discovery.js`)
|
|
70
71
|
|
|
71
72
|
Automatically discovers existing AWS resources:
|
|
72
|
-
|
|
73
|
-
-
|
|
74
|
-
-
|
|
75
|
-
-
|
|
73
|
+
|
|
74
|
+
- Default VPC and security groups
|
|
75
|
+
- Private subnets for Lambda functions
|
|
76
|
+
- Customer-managed KMS keys
|
|
77
|
+
- Route tables for VPC endpoints
|
|
76
78
|
|
|
77
79
|
#### 3. Build-Time Discovery (`build-time-discovery.js`)
|
|
78
80
|
|
|
79
81
|
Integrates AWS discovery into the build process:
|
|
80
|
-
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
-
|
|
82
|
+
|
|
83
|
+
- Pre-build hook for serverless deployments
|
|
84
|
+
- Environment variable injection
|
|
85
|
+
- Template variable replacement
|
|
86
|
+
- Error handling and fallback values
|
|
84
87
|
|
|
85
88
|
### Phase 3 Infrastructure
|
|
86
89
|
|
|
87
90
|
#### 1. Enhanced Monitoring (`cloudformation/monitoring-infrastructure.yaml`)
|
|
88
91
|
|
|
89
92
|
Production-ready monitoring with:
|
|
90
|
-
|
|
91
|
-
-
|
|
92
|
-
-
|
|
93
|
-
-
|
|
93
|
+
|
|
94
|
+
- Code generation service monitoring
|
|
95
|
+
- UI distribution monitoring
|
|
96
|
+
- Advanced CloudWatch dashboards
|
|
97
|
+
- Custom metrics and alarms
|
|
94
98
|
|
|
95
99
|
#### 2. CDN Infrastructure (`cloudformation/cdn-infrastructure.yaml`)
|
|
96
100
|
|
|
97
101
|
CloudFront distribution for UI packages:
|
|
98
|
-
|
|
99
|
-
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
+
|
|
103
|
+
- S3 bucket for multi-framework UI packages
|
|
104
|
+
- CloudFront distribution with custom domains
|
|
105
|
+
- Lambda function for package deployment
|
|
106
|
+
- API Gateway for package management
|
|
102
107
|
|
|
103
108
|
#### 3. Code Generation Infrastructure (`cloudformation/codegen-infrastructure.yaml`)
|
|
104
109
|
|
|
105
110
|
Serverless code generation platform:
|
|
106
|
-
|
|
107
|
-
-
|
|
108
|
-
-
|
|
109
|
-
-
|
|
110
|
-
-
|
|
111
|
+
|
|
112
|
+
- SQS queue for generation requests
|
|
113
|
+
- Lambda function with AI/ML integration
|
|
114
|
+
- DynamoDB tracking table
|
|
115
|
+
- S3 storage for templates and generated code
|
|
116
|
+
- ElastiCache for template caching
|
|
111
117
|
|
|
112
118
|
#### 4. Advanced Alerting (`cloudformation/alerting-infrastructure.yaml`)
|
|
113
119
|
|
|
114
120
|
Multi-channel alerting system:
|
|
115
|
-
|
|
116
|
-
-
|
|
117
|
-
-
|
|
118
|
-
-
|
|
119
|
-
-
|
|
121
|
+
|
|
122
|
+
- Multiple SNS topics for alert severity levels
|
|
123
|
+
- Lambda function for alert processing
|
|
124
|
+
- PagerDuty and Slack integration
|
|
125
|
+
- Composite alarms for system health
|
|
126
|
+
- Advanced metrics collection
|
|
120
127
|
|
|
121
128
|
#### 5. Deployment Pipeline (`cloudformation/deployment-pipeline.yaml`)
|
|
122
129
|
|
|
123
130
|
CI/CD pipeline for automated deployments:
|
|
124
|
-
|
|
125
|
-
-
|
|
126
|
-
-
|
|
127
|
-
-
|
|
131
|
+
|
|
132
|
+
- CodePipeline with GitHub integration
|
|
133
|
+
- CodeBuild projects for backend and UI
|
|
134
|
+
- Multi-stage deployment workflow
|
|
135
|
+
- Integration testing and approval gates
|
|
128
136
|
|
|
129
137
|
## Configuration Options
|
|
130
138
|
|
|
@@ -135,7 +143,7 @@ const appDefinition = {
|
|
|
135
143
|
// Basic configuration
|
|
136
144
|
name: 'my-frigg-app',
|
|
137
145
|
provider: 'aws',
|
|
138
|
-
|
|
146
|
+
|
|
139
147
|
// VPC configuration
|
|
140
148
|
vpc: {
|
|
141
149
|
enable: true,
|
|
@@ -144,22 +152,22 @@ const appDefinition = {
|
|
|
144
152
|
subnetIds: [...], // Optional: custom subnets
|
|
145
153
|
enableVPCEndpoints: true // Optional: create VPC endpoints
|
|
146
154
|
},
|
|
147
|
-
|
|
155
|
+
|
|
148
156
|
// KMS encryption
|
|
149
157
|
encryption: {
|
|
150
158
|
useDefaultKMSForFieldLevelEncryption: true
|
|
151
159
|
},
|
|
152
|
-
|
|
160
|
+
|
|
153
161
|
// SSM Parameter Store
|
|
154
162
|
ssm: {
|
|
155
163
|
enable: true
|
|
156
164
|
},
|
|
157
|
-
|
|
165
|
+
|
|
158
166
|
// WebSocket support (Phase 3)
|
|
159
167
|
websockets: {
|
|
160
168
|
enable: true
|
|
161
169
|
},
|
|
162
|
-
|
|
170
|
+
|
|
163
171
|
// Integrations
|
|
164
172
|
integrations: [
|
|
165
173
|
{ Definition: { name: 'hubspot' } },
|
|
@@ -195,10 +203,8 @@ SERVICE_NAME=my-frigg-app
|
|
|
195
203
|
const { composeServerlessDefinition } = require('./serverless-template');
|
|
196
204
|
|
|
197
205
|
const appDefinition = {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
{ Definition: { name: 'hubspot' } }
|
|
201
|
-
]
|
|
206
|
+
name: 'my-app',
|
|
207
|
+
integrations: [{ Definition: { name: 'hubspot' } }],
|
|
202
208
|
};
|
|
203
209
|
|
|
204
210
|
const serverlessConfig = await composeServerlessDefinition(appDefinition);
|
|
@@ -209,13 +215,11 @@ const serverlessConfig = await composeServerlessDefinition(appDefinition);
|
|
|
209
215
|
|
|
210
216
|
```javascript
|
|
211
217
|
const appDefinition = {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
{ Definition: { name: 'salesforce' } }
|
|
218
|
-
]
|
|
218
|
+
name: 'secure-app',
|
|
219
|
+
vpc: { enable: true },
|
|
220
|
+
encryption: { useDefaultKMSForFieldLevelEncryption: true },
|
|
221
|
+
ssm: { enable: true },
|
|
222
|
+
integrations: [{ Definition: { name: 'salesforce' } }],
|
|
219
223
|
};
|
|
220
224
|
|
|
221
225
|
const serverlessConfig = await composeServerlessDefinition(appDefinition);
|
|
@@ -225,12 +229,10 @@ const serverlessConfig = await composeServerlessDefinition(appDefinition);
|
|
|
225
229
|
|
|
226
230
|
```javascript
|
|
227
231
|
const appDefinition = {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
{ Definition: { name: 'slack' } }
|
|
233
|
-
]
|
|
232
|
+
name: 'realtime-app',
|
|
233
|
+
websockets: { enable: true },
|
|
234
|
+
vpc: { enable: true },
|
|
235
|
+
integrations: [{ Definition: { name: 'slack' } }],
|
|
234
236
|
};
|
|
235
237
|
|
|
236
238
|
const serverlessConfig = await composeServerlessDefinition(appDefinition);
|
|
@@ -259,19 +261,21 @@ npm test -- --watch
|
|
|
259
261
|
### Test Categories
|
|
260
262
|
|
|
261
263
|
1. **Unit Tests**: Test individual components
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
264
|
+
|
|
265
|
+
- AWS discovery utilities
|
|
266
|
+
- Serverless template generation
|
|
267
|
+
- IAM policy generation
|
|
265
268
|
|
|
266
269
|
2. **Integration Tests**: Test end-to-end workflows
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
+
|
|
271
|
+
- Complete discovery and template generation
|
|
272
|
+
- Plugin integration
|
|
273
|
+
- Phase 3 infrastructure validation
|
|
270
274
|
|
|
271
275
|
3. **Performance Tests**: Validate infrastructure limits
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
276
|
+
- CloudFormation template sizes
|
|
277
|
+
- Resource count limits
|
|
278
|
+
- Cross-stack dependencies
|
|
275
279
|
|
|
276
280
|
### Mock Data
|
|
277
281
|
|
|
@@ -279,11 +283,12 @@ Tests use mock AWS resources to avoid real AWS API calls:
|
|
|
279
283
|
|
|
280
284
|
```javascript
|
|
281
285
|
const mockAWSResources = {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
286
|
+
defaultVpcId: 'vpc-12345678',
|
|
287
|
+
defaultSecurityGroupId: 'sg-12345678',
|
|
288
|
+
privateSubnetId1: 'subnet-private-1',
|
|
289
|
+
privateSubnetId2: 'subnet-private-2',
|
|
290
|
+
defaultKmsKeyId:
|
|
291
|
+
'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012',
|
|
287
292
|
};
|
|
288
293
|
```
|
|
289
294
|
|
|
@@ -293,18 +298,18 @@ const mockAWSResources = {
|
|
|
293
298
|
|
|
294
299
|
The infrastructure requires specific IAM permissions for AWS resource discovery and deployment:
|
|
295
300
|
|
|
296
|
-
-
|
|
297
|
-
-
|
|
298
|
-
-
|
|
299
|
-
-
|
|
300
|
-
-
|
|
301
|
-
-
|
|
302
|
-
-
|
|
303
|
-
-
|
|
304
|
-
-
|
|
305
|
-
-
|
|
306
|
-
-
|
|
307
|
-
-
|
|
301
|
+
- **EC2**: Describe VPCs, subnets, security groups, route tables
|
|
302
|
+
- **KMS**: List keys, describe keys
|
|
303
|
+
- **STS**: Get caller identity
|
|
304
|
+
- **CloudFormation**: Full access for stack operations
|
|
305
|
+
- **Lambda**: Function management
|
|
306
|
+
- **API Gateway**: API management
|
|
307
|
+
- **S3**: Bucket and object operations (including tagging)
|
|
308
|
+
- **DynamoDB**: Table operations
|
|
309
|
+
- **SQS**: Queue operations
|
|
310
|
+
- **SNS**: Topic operations
|
|
311
|
+
- **CloudWatch**: Metrics and alarms
|
|
312
|
+
- **IAM**: Role and policy management
|
|
308
313
|
|
|
309
314
|
### Best Practices
|
|
310
315
|
|
|
@@ -348,6 +353,8 @@ serverless print
|
|
|
348
353
|
aws cloudformation validate-template --template-body file://template.json
|
|
349
354
|
```
|
|
350
355
|
|
|
356
|
+
- **Connectivity to external services (e.g., databases):** If your Lambda functions in a VPC cannot connect to external services, ensure that the `FriggLambdaSecurityGroup` has the correct **egress** rules to allow outbound traffic on the required ports (e.g., port 27017 for MongoDB).
|
|
357
|
+
|
|
351
358
|
#### Infrastructure Test Failures
|
|
352
359
|
|
|
353
360
|
```bash
|
|
@@ -364,19 +371,22 @@ npm run test:debug
|
|
|
364
371
|
### Performance Optimization
|
|
365
372
|
|
|
366
373
|
#### Lambda Cold Starts
|
|
367
|
-
|
|
368
|
-
-
|
|
369
|
-
-
|
|
374
|
+
|
|
375
|
+
- Use provisioned concurrency for critical functions
|
|
376
|
+
- Optimize function size and dependencies
|
|
377
|
+
- Monitor cold start metrics
|
|
370
378
|
|
|
371
379
|
#### VPC Performance
|
|
372
|
-
|
|
373
|
-
-
|
|
374
|
-
-
|
|
380
|
+
|
|
381
|
+
- Use VPC endpoints to reduce NAT Gateway costs
|
|
382
|
+
- Monitor ENI creation/deletion times
|
|
383
|
+
- Consider Lambda@Edge for global distribution
|
|
375
384
|
|
|
376
385
|
#### Cost Optimization
|
|
377
|
-
|
|
378
|
-
-
|
|
379
|
-
-
|
|
386
|
+
|
|
387
|
+
- Use S3 Intelligent Tiering
|
|
388
|
+
- Configure CloudWatch log retention
|
|
389
|
+
- Monitor and alert on unexpected usage
|
|
380
390
|
|
|
381
391
|
## Contributing
|
|
382
392
|
|
|
@@ -405,17 +415,17 @@ npm run test:debug
|
|
|
405
415
|
|
|
406
416
|
## Support
|
|
407
417
|
|
|
408
|
-
-
|
|
409
|
-
-
|
|
410
|
-
-
|
|
411
|
-
-
|
|
412
|
-
-
|
|
418
|
+
- **Documentation**: See `PHASE3-DEPLOYMENT-GUIDE.md` for detailed deployment instructions
|
|
419
|
+
- **Testing**: See `README-TESTING.md` for testing strategy
|
|
420
|
+
- **Troubleshooting**: See `AWS-DISCOVERY-TROUBLESHOOTING.md` for common issues
|
|
421
|
+
- **Issues**: Create GitHub issues for bugs and feature requests
|
|
422
|
+
- **Discussions**: Use GitHub Discussions for questions and ideas
|
|
413
423
|
|
|
414
424
|
## Related Documentation
|
|
415
425
|
|
|
416
|
-
-
|
|
417
|
-
-
|
|
418
|
-
-
|
|
419
|
-
-
|
|
420
|
-
-
|
|
421
|
-
-
|
|
426
|
+
- [Phase 3 Deployment Guide](./PHASE3-DEPLOYMENT-GUIDE.md)
|
|
427
|
+
- [Testing Strategy](./README-TESTING.md)
|
|
428
|
+
- [AWS Discovery Troubleshooting](./AWS-DISCOVERY-TROUBLESHOOTING.md)
|
|
429
|
+
- [IAM Policy Templates](./IAM-POLICY-TEMPLATES.md)
|
|
430
|
+
- [VPC Configuration](./VPC-CONFIGURATION.md)
|
|
431
|
+
- [WebSocket Configuration](./WEBSOCKET-CONFIGURATION.md)
|
|
@@ -12,15 +12,15 @@ const validateEnvironmentVariables = (AppDefinition) => {
|
|
|
12
12
|
const results = {
|
|
13
13
|
valid: [],
|
|
14
14
|
missing: [],
|
|
15
|
-
warnings: []
|
|
15
|
+
warnings: [],
|
|
16
16
|
};
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
if (!AppDefinition.environment) {
|
|
19
19
|
return results;
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
console.log('🔍 Validating environment variables...');
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
for (const [key, value] of Object.entries(AppDefinition.environment)) {
|
|
25
25
|
if (value === true) {
|
|
26
26
|
if (process.env[key]) {
|
|
@@ -30,30 +30,34 @@ const validateEnvironmentVariables = (AppDefinition) => {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
// Special handling for certain variables
|
|
35
35
|
if (results.missing.includes('NODE_ENV')) {
|
|
36
36
|
results.warnings.push('NODE_ENV not set, defaulting to "production"');
|
|
37
37
|
// Remove from missing since it has a default
|
|
38
|
-
results.missing = results.missing.filter(v => v !== 'NODE_ENV');
|
|
38
|
+
results.missing = results.missing.filter((v) => v !== 'NODE_ENV');
|
|
39
39
|
}
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
// Report results
|
|
42
42
|
if (results.valid.length > 0) {
|
|
43
|
-
console.log(
|
|
43
|
+
console.log(
|
|
44
|
+
` ✅ Valid: ${results.valid.length} environment variables found`
|
|
45
|
+
);
|
|
44
46
|
}
|
|
45
|
-
|
|
47
|
+
|
|
46
48
|
if (results.missing.length > 0) {
|
|
47
49
|
console.log(` ⚠️ Missing: ${results.missing.join(', ')}`);
|
|
48
|
-
results.warnings.push(
|
|
50
|
+
results.warnings.push(
|
|
51
|
+
`Missing ${results.missing.length} environment variables. These should be set in your CI/CD environment or .env file`
|
|
52
|
+
);
|
|
49
53
|
}
|
|
50
|
-
|
|
54
|
+
|
|
51
55
|
if (results.warnings.length > 0) {
|
|
52
|
-
results.warnings.forEach(warning => {
|
|
56
|
+
results.warnings.forEach((warning) => {
|
|
53
57
|
console.log(` ⚠️ ${warning}`);
|
|
54
58
|
});
|
|
55
59
|
}
|
|
56
|
-
|
|
60
|
+
|
|
57
61
|
return results;
|
|
58
62
|
};
|
|
59
63
|
|
|
@@ -67,7 +71,7 @@ const hasAllRequiredEnvVars = (AppDefinition) => {
|
|
|
67
71
|
return results.missing.length === 0;
|
|
68
72
|
};
|
|
69
73
|
|
|
70
|
-
module.exports = {
|
|
74
|
+
module.exports = {
|
|
71
75
|
validateEnvironmentVariables,
|
|
72
|
-
hasAllRequiredEnvVars
|
|
73
|
-
};
|
|
76
|
+
hasAllRequiredEnvVars,
|
|
77
|
+
};
|
|
@@ -450,6 +450,13 @@ const createVPCInfrastructure = (AppDefinition) => {
|
|
|
450
450
|
CidrIp: '0.0.0.0/0',
|
|
451
451
|
Description: 'DNS UDP',
|
|
452
452
|
},
|
|
453
|
+
{
|
|
454
|
+
IpProtocol: 'tcp',
|
|
455
|
+
FromPort: 27017,
|
|
456
|
+
ToPort: 27017,
|
|
457
|
+
CidrIp: '0.0.0.0/0',
|
|
458
|
+
Description: 'MongoDB outbound',
|
|
459
|
+
},
|
|
453
460
|
],
|
|
454
461
|
Tags: [
|
|
455
462
|
{
|
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.
|
|
4
|
+
"version": "2.0.0--canary.417.1ca8d39.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.
|
|
13
|
-
"@friggframework/test": "2.0.0--canary.
|
|
12
|
+
"@friggframework/schemas": "2.0.0--canary.417.1ca8d39.0",
|
|
13
|
+
"@friggframework/test": "2.0.0--canary.417.1ca8d39.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.
|
|
36
|
-
"@friggframework/prettier-config": "2.0.0--canary.
|
|
35
|
+
"@friggframework/eslint-config": "2.0.0--canary.417.1ca8d39.0",
|
|
36
|
+
"@friggframework/prettier-config": "2.0.0--canary.417.1ca8d39.0",
|
|
37
37
|
"prettier": "^2.7.1",
|
|
38
38
|
"serverless": "3.39.0",
|
|
39
39
|
"serverless-dotenv-plugin": "^6.0.0",
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"publishConfig": {
|
|
66
66
|
"access": "public"
|
|
67
67
|
},
|
|
68
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "1ca8d392729c0a2650c1ecd3f6269206938f1157"
|
|
69
69
|
}
|