@friggframework/devtools 2.0.0--canary.398.e2147f7.0 → 2.0.0--canary.398.a2fbc38.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 +25 -2
- package/frigg-cli/deploy-command/index.js +26 -2
- package/frigg-cli/generate-iam-command.js +115 -0
- package/frigg-cli/index.js +11 -1
- package/infrastructure/AWS-DISCOVERY-TROUBLESHOOTING.md +245 -0
- package/infrastructure/AWS-IAM-CREDENTIAL-NEEDS.md +23 -3
- package/infrastructure/DEPLOYMENT-INSTRUCTIONS.md +268 -0
- package/infrastructure/GENERATE-IAM-DOCS.md +253 -0
- package/infrastructure/WEBSOCKET-CONFIGURATION.md +105 -0
- package/infrastructure/aws-discovery.js +26 -5
- package/infrastructure/build-time-discovery.js +13 -4
- package/infrastructure/frigg-deployment-iam-stack.yaml +370 -0
- package/infrastructure/iam-generator.js +644 -0
- package/infrastructure/iam-generator.test.js +169 -0
- package/infrastructure/run-discovery.js +108 -0
- package/infrastructure/serverless-template.js +49 -20
- package/package.json +9 -5
|
@@ -1,9 +1,32 @@
|
|
|
1
1
|
const { spawnSync } = require('child_process');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
|
|
4
|
-
function buildCommand(options) {
|
|
4
|
+
async function buildCommand(options) {
|
|
5
5
|
console.log('Building the serverless application...');
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
// Run AWS discovery first
|
|
8
|
+
try {
|
|
9
|
+
const discoveryPath = path.resolve(__dirname, '../../infrastructure/run-discovery.js');
|
|
10
|
+
console.log('🔍 Running AWS resource discovery...');
|
|
11
|
+
|
|
12
|
+
const discoveryResult = spawnSync('node', [discoveryPath], {
|
|
13
|
+
stdio: 'inherit',
|
|
14
|
+
shell: true,
|
|
15
|
+
env: process.env
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
if (discoveryResult.status !== 0) {
|
|
19
|
+
console.error('❌ AWS discovery failed. Build cannot continue.');
|
|
20
|
+
console.error(' See error messages above for troubleshooting steps.');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error('❌ Could not run AWS discovery:', error.message);
|
|
25
|
+
console.error(' This may indicate a configuration or dependency issue.');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
console.log('📦 Packaging serverless application...');
|
|
7
30
|
const backendPath = path.resolve(process.cwd());
|
|
8
31
|
const infrastructurePath = 'infrastructure.js';
|
|
9
32
|
const command = 'serverless';
|
|
@@ -1,8 +1,32 @@
|
|
|
1
|
-
const { spawn } = require('child_process');
|
|
1
|
+
const { spawn, spawnSync } = require('child_process');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
|
|
4
|
-
function deployCommand(options) {
|
|
4
|
+
async function deployCommand(options) {
|
|
5
5
|
console.log('Deploying the serverless application...');
|
|
6
|
+
|
|
7
|
+
// Run AWS discovery first
|
|
8
|
+
try {
|
|
9
|
+
const discoveryPath = path.resolve(__dirname, '../../infrastructure/run-discovery.js');
|
|
10
|
+
console.log('🔍 Running AWS resource discovery...');
|
|
11
|
+
|
|
12
|
+
const discoveryResult = spawnSync('node', [discoveryPath], {
|
|
13
|
+
stdio: 'inherit',
|
|
14
|
+
shell: true,
|
|
15
|
+
env: process.env
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
if (discoveryResult.status !== 0) {
|
|
19
|
+
console.error('❌ AWS discovery failed. Deployment cannot continue.');
|
|
20
|
+
console.error(' See error messages above for troubleshooting steps.');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error('❌ Could not run AWS discovery:', error.message);
|
|
25
|
+
console.error(' This may indicate a configuration or dependency issue.');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
console.log('🚀 Deploying serverless application...');
|
|
6
30
|
const backendPath = path.resolve(process.cwd());
|
|
7
31
|
const infrastructurePath = 'infrastructure.js';
|
|
8
32
|
const command = 'serverless';
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { findNearestBackendPackageJson } = require('@friggframework/core');
|
|
4
|
+
const { generateIAMCloudFormation, getFeatureSummary } = require('../infrastructure/iam-generator');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Generate IAM CloudFormation stack based on current app definition
|
|
8
|
+
* @param {Object} options - Command options
|
|
9
|
+
*/
|
|
10
|
+
async function generateIamCommand(options = {}) {
|
|
11
|
+
try {
|
|
12
|
+
console.log('🔍 Finding Frigg application...');
|
|
13
|
+
|
|
14
|
+
// Find the backend package.json
|
|
15
|
+
const backendPath = findNearestBackendPackageJson();
|
|
16
|
+
if (!backendPath) {
|
|
17
|
+
console.error('❌ Could not find backend package.json');
|
|
18
|
+
console.error(' Make sure you are in a Frigg application directory');
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const backendDir = path.dirname(backendPath);
|
|
23
|
+
const backendFilePath = path.join(backendDir, 'index.js');
|
|
24
|
+
|
|
25
|
+
if (!fs.existsSync(backendFilePath)) {
|
|
26
|
+
console.error('❌ Could not find backend/index.js');
|
|
27
|
+
console.error(' Make sure your Frigg application has a backend/index.js file');
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
console.log(`📱 Found Frigg application at: ${backendDir}`);
|
|
32
|
+
|
|
33
|
+
// Load the app definition
|
|
34
|
+
const backend = require(backendFilePath);
|
|
35
|
+
const appDefinition = backend.Definition;
|
|
36
|
+
|
|
37
|
+
if (!appDefinition) {
|
|
38
|
+
console.error('❌ No Definition found in backend/index.js');
|
|
39
|
+
console.error(' Make sure your backend exports a Definition object');
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Get feature summary
|
|
44
|
+
const summary = getFeatureSummary(appDefinition);
|
|
45
|
+
|
|
46
|
+
console.log('\\n📋 Application Analysis:');
|
|
47
|
+
console.log(` App Name: ${summary.appName}`);
|
|
48
|
+
console.log(` Integrations: ${summary.integrationCount}`);
|
|
49
|
+
console.log('\\n🔧 Features Detected:');
|
|
50
|
+
console.log(` ✅ Core deployment (always included)`);
|
|
51
|
+
console.log(` ${summary.features.vpc ? '✅' : '❌'} VPC support`);
|
|
52
|
+
console.log(` ${summary.features.kms ? '✅' : '❌'} KMS encryption`);
|
|
53
|
+
console.log(` ${summary.features.ssm ? '✅' : '❌'} SSM Parameter Store`);
|
|
54
|
+
console.log(` ${summary.features.websockets ? '✅' : '❌'} WebSocket support`);
|
|
55
|
+
|
|
56
|
+
// Generate the CloudFormation template
|
|
57
|
+
console.log('\\n🏗️ Generating IAM CloudFormation template...');
|
|
58
|
+
|
|
59
|
+
const deploymentUserName = options.user || 'frigg-deployment-user';
|
|
60
|
+
const stackName = options.stackName || 'frigg-deployment-iam';
|
|
61
|
+
|
|
62
|
+
const cloudFormationYaml = generateIAMCloudFormation(appDefinition, {
|
|
63
|
+
deploymentUserName,
|
|
64
|
+
stackName
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Determine output file path
|
|
68
|
+
const outputDir = options.output || path.join(backendDir, 'infrastructure');
|
|
69
|
+
await fs.ensureDir(outputDir);
|
|
70
|
+
|
|
71
|
+
const outputFile = path.join(outputDir, `${stackName}.yaml`);
|
|
72
|
+
|
|
73
|
+
// Write the file
|
|
74
|
+
await fs.writeFile(outputFile, cloudFormationYaml);
|
|
75
|
+
|
|
76
|
+
console.log(`\\n✅ IAM CloudFormation template generated successfully!`);
|
|
77
|
+
console.log(`📄 File: ${outputFile}`);
|
|
78
|
+
|
|
79
|
+
// Show deployment instructions
|
|
80
|
+
console.log('\\n📚 Next Steps:');
|
|
81
|
+
console.log('\\n1. Deploy the CloudFormation stack:');
|
|
82
|
+
console.log(` aws cloudformation deploy \\\\`);
|
|
83
|
+
console.log(` --template-file ${path.relative(process.cwd(), outputFile)} \\\\`);
|
|
84
|
+
console.log(` --stack-name ${stackName} \\\\`);
|
|
85
|
+
console.log(` --capabilities CAPABILITY_NAMED_IAM \\\\`);
|
|
86
|
+
console.log(` --parameter-overrides DeploymentUserName=${deploymentUserName}`);
|
|
87
|
+
|
|
88
|
+
console.log('\\n2. Retrieve credentials:');
|
|
89
|
+
console.log(` aws cloudformation describe-stacks \\\\`);
|
|
90
|
+
console.log(` --stack-name ${stackName} \\\\`);
|
|
91
|
+
console.log(` --query 'Stacks[0].Outputs[?OutputKey==\`AccessKeyId\`].OutputValue' \\\\`);
|
|
92
|
+
console.log(` --output text`);
|
|
93
|
+
|
|
94
|
+
console.log('\\n3. Get secret access key:');
|
|
95
|
+
console.log(` aws secretsmanager get-secret-value \\\\`);
|
|
96
|
+
console.log(` --secret-id frigg-deployment-credentials \\\\`);
|
|
97
|
+
console.log(` --query SecretString \\\\`);
|
|
98
|
+
console.log(` --output text | jq -r .SecretAccessKey`);
|
|
99
|
+
|
|
100
|
+
if (options.verbose) {
|
|
101
|
+
console.log('\\n🔍 Generated Template Summary:');
|
|
102
|
+
console.log(` File size: ${Math.round(cloudFormationYaml.length / 1024)}KB`);
|
|
103
|
+
console.log(` Features enabled: ${Object.values(summary.features).filter(Boolean).length}`);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.error('❌ Error generating IAM template:', error.message);
|
|
108
|
+
if (options.verbose) {
|
|
109
|
+
console.error('Stack trace:', error.stack);
|
|
110
|
+
}
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
module.exports = { generateIamCommand };
|
package/frigg-cli/index.js
CHANGED
|
@@ -5,6 +5,7 @@ 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');
|
|
8
9
|
|
|
9
10
|
const program = new Command();
|
|
10
11
|
program
|
|
@@ -33,6 +34,15 @@ program
|
|
|
33
34
|
.option('-v, --verbose', 'enable verbose output')
|
|
34
35
|
.action(deployCommand);
|
|
35
36
|
|
|
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
|
+
|
|
36
46
|
program.parse(process.argv);
|
|
37
47
|
|
|
38
|
-
module.exports = { installCommand, startCommand, buildCommand, deployCommand };
|
|
48
|
+
module.exports = { installCommand, startCommand, buildCommand, deployCommand, generateIamCommand };
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# AWS Discovery Troubleshooting Guide
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
AWS Discovery automatically finds your default AWS resources (VPC, subnets, security groups, KMS keys) during the build process. This eliminates the need to manually specify resource IDs in your configuration.
|
|
6
|
+
|
|
7
|
+
## When AWS Discovery Runs
|
|
8
|
+
|
|
9
|
+
AWS Discovery runs automatically during `frigg build` and `frigg deploy` when your AppDefinition includes:
|
|
10
|
+
|
|
11
|
+
- `vpc.enable: true` - VPC support
|
|
12
|
+
- `encryption.useDefaultKMSForFieldLevelEncryption: true` - KMS encryption
|
|
13
|
+
- `ssm.enable: true` - SSM Parameter Store
|
|
14
|
+
|
|
15
|
+
## Fail-Fast Behavior
|
|
16
|
+
|
|
17
|
+
⚠️ **Important:** If you enable these features, discovery **must succeed**. The build will fail if:
|
|
18
|
+
- AWS credentials are missing or invalid
|
|
19
|
+
- Required AWS permissions are not granted
|
|
20
|
+
- No VPC/subnets exist in your region
|
|
21
|
+
- Discovery times out or encounters errors
|
|
22
|
+
|
|
23
|
+
This prevents deployments with incorrect or missing AWS resources, which could cause security issues or deployment failures.
|
|
24
|
+
|
|
25
|
+
## Common Issues
|
|
26
|
+
|
|
27
|
+
### 1. "Variables resolution errored" - Environment Variables Not Found
|
|
28
|
+
|
|
29
|
+
**Error:**
|
|
30
|
+
```
|
|
31
|
+
Cannot resolve variable at "provider.vpc.securityGroupIds.0": Value not found at "env" source
|
|
32
|
+
Cannot resolve variable at "provider.vpc.subnetIds.0": Value not found at "env" source
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Cause:** AWS discovery didn't run or failed to set environment variables.
|
|
36
|
+
|
|
37
|
+
**Solutions:**
|
|
38
|
+
|
|
39
|
+
#### Option A: Run Discovery Manually
|
|
40
|
+
```bash
|
|
41
|
+
# Run discovery before building
|
|
42
|
+
node node_modules/@friggframework/devtools/infrastructure/run-discovery.js
|
|
43
|
+
|
|
44
|
+
# Then build
|
|
45
|
+
npx frigg build
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
#### Option B: Check Prerequisites
|
|
49
|
+
1. **AWS Credentials:** Ensure AWS CLI is configured
|
|
50
|
+
```bash
|
|
51
|
+
aws configure list
|
|
52
|
+
aws sts get-caller-identity
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
2. **IAM Permissions:** User needs discovery permissions (see [AWS-IAM-CREDENTIAL-NEEDS.md](./AWS-IAM-CREDENTIAL-NEEDS.md))
|
|
56
|
+
- `sts:GetCallerIdentity`
|
|
57
|
+
- `ec2:DescribeVpcs`
|
|
58
|
+
- `ec2:DescribeSubnets`
|
|
59
|
+
- `ec2:DescribeSecurityGroups`
|
|
60
|
+
- `ec2:DescribeRouteTables`
|
|
61
|
+
- `kms:ListKeys`
|
|
62
|
+
- `kms:DescribeKey`
|
|
63
|
+
|
|
64
|
+
3. **Default VPC:** Ensure you have a VPC in your AWS region
|
|
65
|
+
```bash
|
|
66
|
+
aws ec2 describe-vpcs --region us-east-1
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 2. AWS SDK Not Installed
|
|
70
|
+
|
|
71
|
+
**Error:**
|
|
72
|
+
```bash
|
|
73
|
+
🚨 AWS SDK not installed!
|
|
74
|
+
Cannot find module '@aws-sdk/client-ec2'
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Cause:** AWS SDK dependencies are only installed when needed to keep bundle size minimal.
|
|
78
|
+
|
|
79
|
+
**Solution:**
|
|
80
|
+
```bash
|
|
81
|
+
# Install required AWS SDK packages
|
|
82
|
+
npm install @aws-sdk/client-ec2 @aws-sdk/client-kms @aws-sdk/client-sts
|
|
83
|
+
|
|
84
|
+
# Then run discovery
|
|
85
|
+
npx frigg build
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Note:** AWS SDK is optional - only install if you use VPC/KMS/SSM features.
|
|
89
|
+
|
|
90
|
+
### 3. No Default VPC Found
|
|
91
|
+
|
|
92
|
+
**Error:**
|
|
93
|
+
```
|
|
94
|
+
No VPC found in the account
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Cause:** Your AWS account doesn't have a default VPC or any VPCs in the current region.
|
|
98
|
+
|
|
99
|
+
**Solutions:**
|
|
100
|
+
|
|
101
|
+
#### Option A: Create Default VPC
|
|
102
|
+
```bash
|
|
103
|
+
aws ec2 create-default-vpc --region us-east-1
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### Option B: Disable VPC in AppDefinition
|
|
107
|
+
```javascript
|
|
108
|
+
// backend/index.js
|
|
109
|
+
const appDefinition = {
|
|
110
|
+
// ... other config
|
|
111
|
+
vpc: {
|
|
112
|
+
enable: false // Disable VPC support
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### 4. Permission Denied During Discovery
|
|
118
|
+
|
|
119
|
+
**Error:**
|
|
120
|
+
```
|
|
121
|
+
User: arn:aws:iam::123456789012:user/my-user is not authorized to perform: ec2:DescribeVpcs
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Cause:** IAM user lacks discovery permissions.
|
|
125
|
+
|
|
126
|
+
**Solution:**
|
|
127
|
+
1. Update IAM policy with discovery permissions
|
|
128
|
+
2. Or generate a custom IAM stack:
|
|
129
|
+
```bash
|
|
130
|
+
npx frigg generate-iam
|
|
131
|
+
aws cloudformation deploy --template-file backend/infrastructure/frigg-deployment-iam.yaml --stack-name frigg-deployment-iam --capabilities CAPABILITY_NAMED_IAM
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### 5. Region Configuration Issues
|
|
135
|
+
|
|
136
|
+
**Error:**
|
|
137
|
+
```
|
|
138
|
+
No subnets found in VPC vpc-123456789
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Cause:** AWS discovery is looking in the wrong region or region has no subnets.
|
|
142
|
+
|
|
143
|
+
**Solutions:**
|
|
144
|
+
|
|
145
|
+
#### Option A: Set AWS Region
|
|
146
|
+
```bash
|
|
147
|
+
export AWS_REGION=us-east-1
|
|
148
|
+
npx frigg build
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
#### Option B: Check Current Region
|
|
152
|
+
```bash
|
|
153
|
+
aws configure get region
|
|
154
|
+
aws ec2 describe-availability-zones --query 'AvailabilityZones[0].RegionName'
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Manual Override
|
|
158
|
+
|
|
159
|
+
If AWS discovery continues to fail, you can manually set environment variables:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
# Find your actual resource IDs
|
|
163
|
+
aws ec2 describe-vpcs --query 'Vpcs[0].VpcId' --output text
|
|
164
|
+
aws ec2 describe-subnets --filters "Name=vpc-id,Values=vpc-12345678" --query 'Subnets[0:2].SubnetId' --output text
|
|
165
|
+
|
|
166
|
+
# Set before building
|
|
167
|
+
export AWS_DISCOVERY_VPC_ID=vpc-12345678
|
|
168
|
+
export AWS_DISCOVERY_SECURITY_GROUP_ID=sg-12345678
|
|
169
|
+
export AWS_DISCOVERY_SUBNET_ID_1=subnet-12345678
|
|
170
|
+
export AWS_DISCOVERY_SUBNET_ID_2=subnet-87654321
|
|
171
|
+
export AWS_DISCOVERY_PUBLIC_SUBNET_ID=subnet-abcdef12
|
|
172
|
+
export AWS_DISCOVERY_ROUTE_TABLE_ID=rtb-12345678
|
|
173
|
+
export AWS_DISCOVERY_KMS_KEY_ID=arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012
|
|
174
|
+
|
|
175
|
+
npx frigg build
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**⚠️ Important:** Use real AWS resource IDs, not placeholder values. Fake IDs will cause deployment failures.
|
|
179
|
+
|
|
180
|
+
## Debugging Discovery
|
|
181
|
+
|
|
182
|
+
### Enable Verbose Logging
|
|
183
|
+
```bash
|
|
184
|
+
npx frigg build --verbose
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Test Discovery Standalone
|
|
188
|
+
```bash
|
|
189
|
+
# Test discovery without building
|
|
190
|
+
node node_modules/@friggframework/devtools/infrastructure/run-discovery.js
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Check Environment Variables
|
|
194
|
+
```bash
|
|
195
|
+
# After running discovery
|
|
196
|
+
printenv | grep AWS_DISCOVERY
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Recovery Steps
|
|
200
|
+
|
|
201
|
+
If you're stuck, try this recovery process:
|
|
202
|
+
|
|
203
|
+
1. **Verify AWS Setup**
|
|
204
|
+
```bash
|
|
205
|
+
aws sts get-caller-identity
|
|
206
|
+
aws ec2 describe-vpcs --region us-east-1
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
2. **Check App Definition**
|
|
210
|
+
```bash
|
|
211
|
+
# Ensure your backend/index.js exports Definition correctly
|
|
212
|
+
node -e "console.log(require('./backend/index.js').Definition)"
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
3. **Run Discovery Manually**
|
|
216
|
+
```bash
|
|
217
|
+
node node_modules/@friggframework/devtools/infrastructure/run-discovery.js
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
4. **Disable Features Temporarily**
|
|
221
|
+
```javascript
|
|
222
|
+
// backend/index.js - temporarily disable problematic features
|
|
223
|
+
const appDefinition = {
|
|
224
|
+
vpc: { enable: false },
|
|
225
|
+
encryption: { useDefaultKMSForFieldLevelEncryption: false },
|
|
226
|
+
ssm: { enable: false }
|
|
227
|
+
};
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
5. **Build and Test**
|
|
231
|
+
```bash
|
|
232
|
+
npx frigg build
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Getting Help
|
|
236
|
+
|
|
237
|
+
If discovery continues to fail:
|
|
238
|
+
|
|
239
|
+
1. **Check logs** for specific error messages
|
|
240
|
+
2. **Verify IAM permissions** using the generated IAM stack
|
|
241
|
+
3. **Test AWS CLI access** in your target region
|
|
242
|
+
4. **Review AppDefinition** for correct feature flags
|
|
243
|
+
5. **Try fallback values** as a temporary workaround
|
|
244
|
+
|
|
245
|
+
The discovery system is designed to be resilient, but AWS environment differences can cause issues. Most problems are related to IAM permissions or missing AWS resources in the target region.
|
|
@@ -65,6 +65,7 @@ Required for basic Frigg application deployment:
|
|
|
65
65
|
"cloudformation:DescribeStackEvents",
|
|
66
66
|
"cloudformation:DescribeStackResources",
|
|
67
67
|
"cloudformation:DescribeStackResource",
|
|
68
|
+
"cloudformation:ListStackResources",
|
|
68
69
|
"cloudformation:GetTemplate",
|
|
69
70
|
"cloudformation:ValidateTemplate",
|
|
70
71
|
"cloudformation:DescribeChangeSet",
|
|
@@ -118,7 +119,8 @@ Required for basic Frigg application deployment:
|
|
|
118
119
|
"lambda:PutConcurrency",
|
|
119
120
|
"lambda:DeleteConcurrency",
|
|
120
121
|
"lambda:TagResource",
|
|
121
|
-
"lambda:UntagResource"
|
|
122
|
+
"lambda:UntagResource",
|
|
123
|
+
"lambda:ListVersionsByFunction"
|
|
122
124
|
],
|
|
123
125
|
"Resource": [
|
|
124
126
|
"arn:aws:lambda:*:*:function:*frigg*"
|
|
@@ -145,6 +147,16 @@ Required for basic Frigg application deployment:
|
|
|
145
147
|
"arn:aws:iam::*:role/*frigg*LambdaRole*"
|
|
146
148
|
]
|
|
147
149
|
},
|
|
150
|
+
{
|
|
151
|
+
"Sid": "IAMPolicyVersionPermissions",
|
|
152
|
+
"Effect": "Allow",
|
|
153
|
+
"Action": [
|
|
154
|
+
"iam:ListPolicyVersions"
|
|
155
|
+
],
|
|
156
|
+
"Resource": [
|
|
157
|
+
"arn:aws:iam::*:policy/*"
|
|
158
|
+
]
|
|
159
|
+
},
|
|
148
160
|
{
|
|
149
161
|
"Sid": "FriggMessagingServices",
|
|
150
162
|
"Effect": "Allow",
|
|
@@ -158,7 +170,8 @@ Required for basic Frigg application deployment:
|
|
|
158
170
|
"sqs:UntagQueue"
|
|
159
171
|
],
|
|
160
172
|
"Resource": [
|
|
161
|
-
"arn:aws:sqs:*:*:*frigg*"
|
|
173
|
+
"arn:aws:sqs:*:*:*frigg*",
|
|
174
|
+
"arn:aws:sqs:*:*:internal-error-queue-*"
|
|
162
175
|
]
|
|
163
176
|
},
|
|
164
177
|
{
|
|
@@ -405,7 +418,8 @@ For convenience, here's a single IAM policy that includes all permissions needed
|
|
|
405
418
|
"iam:AttachRolePolicy",
|
|
406
419
|
"iam:DetachRolePolicy",
|
|
407
420
|
"iam:TagRole",
|
|
408
|
-
"iam:UntagRole"
|
|
421
|
+
"iam:UntagRole",
|
|
422
|
+
"iam:ListPolicyVersions"
|
|
409
423
|
],
|
|
410
424
|
"Resource": "arn:aws:iam::*:role/*"
|
|
411
425
|
}
|
|
@@ -450,11 +464,14 @@ For these permissions to work properly, ensure your Frigg applications follow th
|
|
|
450
464
|
- `integration-frigg-service-auth` (Lambda function)
|
|
451
465
|
- `customer-frigg-platform-prod-auth` (Lambda function)
|
|
452
466
|
- `/my-frigg-app/prod/database-url` (SSM parameter)
|
|
467
|
+
- `internal-error-queue-dev` (SQS queue - special pattern for error queues)
|
|
453
468
|
|
|
454
469
|
❌ **Won't Match:**
|
|
455
470
|
- `my-integration-app-dev` (no "frigg" in name)
|
|
456
471
|
- `customer-platform-prod` (no "frigg" in name)
|
|
457
472
|
|
|
473
|
+
**Note:** The `internal-error-queue-*` pattern is specifically allowed for error handling queues.
|
|
474
|
+
|
|
458
475
|
## Security Best Practices
|
|
459
476
|
|
|
460
477
|
### Principle of Least Privilege
|
|
@@ -498,6 +515,9 @@ The discovery process sets these environment variables during build:
|
|
|
498
515
|
2. **VPC Endpoint Creation Fails** - Ensure you have `ec2:CreateVpcEndpoint` permission
|
|
499
516
|
3. **KMS Operations Fail** - Verify KMS key permissions and that the key exists
|
|
500
517
|
4. **SSM Parameter Access Fails** - Check SSM parameter path permissions
|
|
518
|
+
5. **IAM ListPolicyVersions Error** - If you see "User is not authorized to perform: iam:ListPolicyVersions", ensure your deployment user has this permission (added in recent versions)
|
|
519
|
+
6. **SQS SetQueueAttributes Error** - If you see errors for queues like "internal-error-queue-dev", ensure your IAM policy includes the pattern `arn:aws:sqs:*:*:internal-error-queue-*`
|
|
520
|
+
7. **CloudFormation ListStackResources Error** - If you see "User is not authorized to perform: cloudformation:ListStackResources", update your IAM stack with the latest template that includes this permission
|
|
501
521
|
|
|
502
522
|
### Fallback Behavior
|
|
503
523
|
|