@friggframework/devtools 2.0.0--canary.461.4c872e7.0 → 2.0.0--canary.461.9f988ca.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.
|
@@ -65,7 +65,11 @@ class MigrationBuilder extends InfrastructureBuilder {
|
|
|
65
65
|
DeletionPolicy: 'Retain', // Protect migration history during stack rollbacks/deletions
|
|
66
66
|
UpdateReplacePolicy: 'Retain', // Protect during stack updates that require replacement
|
|
67
67
|
Properties: {
|
|
68
|
-
|
|
68
|
+
// Let CloudFormation auto-generate bucket name for global uniqueness
|
|
69
|
+
// Result: ${StackName}-friggmigrationstatusbucket-${randomHash}
|
|
70
|
+
// Example: quo-integrations-prod-friggmigrationstatusbucket-abc123xyz
|
|
71
|
+
// This ensures no conflicts across accounts/regions/stages
|
|
72
|
+
// BucketName: undefined (CloudFormation generates unique name)
|
|
69
73
|
VersioningConfiguration: {
|
|
70
74
|
Status: 'Enabled', // Enable versioning for audit trail
|
|
71
75
|
},
|
|
@@ -182,7 +186,7 @@ class MigrationBuilder extends InfrastructureBuilder {
|
|
|
182
186
|
'node_modules/@prisma/**', // Prisma engines
|
|
183
187
|
'node_modules/.prisma/**',
|
|
184
188
|
'node_modules/@friggframework/core/generated/**', // Generated clients
|
|
185
|
-
|
|
189
|
+
|
|
186
190
|
// Base exclusions
|
|
187
191
|
'node_modules/**/node_modules/**',
|
|
188
192
|
'node_modules/aws-sdk/**',
|
|
@@ -320,7 +324,7 @@ class MigrationBuilder extends InfrastructureBuilder {
|
|
|
320
324
|
// Add IAM permissions for S3 (migration status storage)
|
|
321
325
|
// Migration functions need to read/write migration status in S3
|
|
322
326
|
// to avoid chicken-and-egg dependency on User/Process tables
|
|
323
|
-
|
|
327
|
+
|
|
324
328
|
// Object-level permissions (put, get, delete)
|
|
325
329
|
result.iamStatements.push({
|
|
326
330
|
Effect: 'Allow',
|
|
@@ -147,11 +147,12 @@ class VpcBuilder extends InfrastructureBuilder {
|
|
|
147
147
|
dynamodb: discoveredResources.dynamodbVpcEndpointId,
|
|
148
148
|
kms: discoveredResources.kmsVpcEndpointId,
|
|
149
149
|
secretsManager: discoveredResources.secretsManagerVpcEndpointId,
|
|
150
|
+
sqs: discoveredResources.sqsVpcEndpointId,
|
|
150
151
|
};
|
|
151
152
|
const allEndpointsExist = existingEndpoints.s3 && existingEndpoints.dynamodb &&
|
|
152
|
-
existingEndpoints.kms && existingEndpoints.secretsManager;
|
|
153
|
+
existingEndpoints.kms && existingEndpoints.secretsManager && existingEndpoints.sqs;
|
|
153
154
|
const someEndpointsExist = existingEndpoints.s3 || existingEndpoints.dynamodb ||
|
|
154
|
-
existingEndpoints.kms || existingEndpoints.secretsManager;
|
|
155
|
+
existingEndpoints.kms || existingEndpoints.secretsManager || existingEndpoints.sqs;
|
|
155
156
|
|
|
156
157
|
if (appDefinition.vpc.enableVPCEndpoints !== false) {
|
|
157
158
|
if (vpcManagement === 'create-new') {
|
|
@@ -682,6 +683,8 @@ class VpcBuilder extends InfrastructureBuilder {
|
|
|
682
683
|
if (!existingEndpoints.dynamodb) missing.push('DynamoDB');
|
|
683
684
|
if (!existingEndpoints.kms && appDefinition.encryption?.fieldLevelEncryptionMethod === 'kms') missing.push('KMS');
|
|
684
685
|
if (!existingEndpoints.secretsManager) missing.push('Secrets Manager');
|
|
686
|
+
// SQS endpoint needed for database migrations (migration queue)
|
|
687
|
+
if (!existingEndpoints.sqs && appDefinition.database?.postgres?.enable) missing.push('SQS');
|
|
685
688
|
|
|
686
689
|
if (missing.length > 0) {
|
|
687
690
|
console.log(` Creating missing VPC Endpoints: ${missing.join(', ')}...`);
|
|
@@ -733,8 +736,8 @@ class VpcBuilder extends InfrastructureBuilder {
|
|
|
733
736
|
};
|
|
734
737
|
}
|
|
735
738
|
|
|
736
|
-
// VPC Endpoint Security Group (only if KMS
|
|
737
|
-
if (!existingEndpoints.kms || !existingEndpoints.secretsManager) {
|
|
739
|
+
// VPC Endpoint Security Group (only if KMS, Secrets Manager, or SQS are missing)
|
|
740
|
+
if (!existingEndpoints.kms || !existingEndpoints.secretsManager || (!existingEndpoints.sqs && appDefinition.database?.postgres?.enable)) {
|
|
738
741
|
result.resources.FriggVPCEndpointSecurityGroup = {
|
|
739
742
|
Type: 'AWS::EC2::SecurityGroup',
|
|
740
743
|
Properties: {
|
|
@@ -787,6 +790,21 @@ class VpcBuilder extends InfrastructureBuilder {
|
|
|
787
790
|
};
|
|
788
791
|
}
|
|
789
792
|
|
|
793
|
+
// SQS Interface Endpoint (only if missing AND database migrations are enabled)
|
|
794
|
+
if (!existingEndpoints.sqs && appDefinition.database?.postgres?.enable) {
|
|
795
|
+
result.resources.FriggSQSVPCEndpoint = {
|
|
796
|
+
Type: 'AWS::EC2::VPCEndpoint',
|
|
797
|
+
Properties: {
|
|
798
|
+
VpcId: vpcId,
|
|
799
|
+
ServiceName: 'com.amazonaws.${self:provider.region}.sqs',
|
|
800
|
+
VpcEndpointType: 'Interface',
|
|
801
|
+
SubnetIds: result.vpcConfig.subnetIds,
|
|
802
|
+
SecurityGroupIds: [{ Ref: 'FriggVPCEndpointSecurityGroup' }],
|
|
803
|
+
PrivateDnsEnabled: true,
|
|
804
|
+
},
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
|
|
790
808
|
console.log(` ✅ Created ${missing.length} VPC endpoint(s): ${missing.join(', ')}`);
|
|
791
809
|
}
|
|
792
810
|
}
|
|
@@ -120,6 +120,9 @@ class VpcDiscovery {
|
|
|
120
120
|
const secretsManagerEndpoint = rawResources.vpcEndpoints.find(
|
|
121
121
|
ep => ep.ServiceName && ep.ServiceName.includes('.secretsmanager')
|
|
122
122
|
);
|
|
123
|
+
const sqsEndpoint = rawResources.vpcEndpoints.find(
|
|
124
|
+
ep => ep.ServiceName && ep.ServiceName.includes('.sqs')
|
|
125
|
+
);
|
|
123
126
|
|
|
124
127
|
if (s3Endpoint) {
|
|
125
128
|
result.s3VpcEndpointId = s3Endpoint.VpcEndpointId;
|
|
@@ -133,6 +136,9 @@ class VpcDiscovery {
|
|
|
133
136
|
if (secretsManagerEndpoint) {
|
|
134
137
|
result.secretsManagerVpcEndpointId = secretsManagerEndpoint.VpcEndpointId;
|
|
135
138
|
}
|
|
139
|
+
if (sqsEndpoint) {
|
|
140
|
+
result.sqsVpcEndpointId = sqsEndpoint.VpcEndpointId;
|
|
141
|
+
}
|
|
136
142
|
}
|
|
137
143
|
|
|
138
144
|
console.log(` ✓ Found VPC: ${result.defaultVpcId}`);
|
|
@@ -145,8 +151,8 @@ class VpcDiscovery {
|
|
|
145
151
|
if (result.existingNatGatewayId) {
|
|
146
152
|
console.log(` ✓ Found NAT Gateway: ${result.existingNatGatewayId}`);
|
|
147
153
|
}
|
|
148
|
-
if (result.s3VpcEndpointId || result.dynamodbVpcEndpointId || result.kmsVpcEndpointId || result.secretsManagerVpcEndpointId) {
|
|
149
|
-
console.log(` ✓ Found VPC Endpoints: S3=${result.s3VpcEndpointId ? 'Yes' : 'No'}, DynamoDB=${result.dynamodbVpcEndpointId ? 'Yes' : 'No'}, KMS=${result.kmsVpcEndpointId ? 'Yes' : 'No'}, SecretsManager=${result.secretsManagerVpcEndpointId ? 'Yes' : 'No'}`);
|
|
154
|
+
if (result.s3VpcEndpointId || result.dynamodbVpcEndpointId || result.kmsVpcEndpointId || result.secretsManagerVpcEndpointId || result.sqsVpcEndpointId) {
|
|
155
|
+
console.log(` ✓ Found VPC Endpoints: S3=${result.s3VpcEndpointId ? 'Yes' : 'No'}, DynamoDB=${result.dynamodbVpcEndpointId ? 'Yes' : 'No'}, KMS=${result.kmsVpcEndpointId ? 'Yes' : 'No'}, SecretsManager=${result.secretsManagerVpcEndpointId ? 'Yes' : 'No'}, SQS=${result.sqsVpcEndpointId ? 'Yes' : 'No'}`);
|
|
150
156
|
}
|
|
151
157
|
|
|
152
158
|
return result;
|
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.461.
|
|
4
|
+
"version": "2.0.0--canary.461.9f988ca.0",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@aws-sdk/client-ec2": "^3.835.0",
|
|
7
7
|
"@aws-sdk/client-kms": "^3.835.0",
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"@babel/eslint-parser": "^7.18.9",
|
|
12
12
|
"@babel/parser": "^7.25.3",
|
|
13
13
|
"@babel/traverse": "^7.25.3",
|
|
14
|
-
"@friggframework/schemas": "2.0.0--canary.461.
|
|
15
|
-
"@friggframework/test": "2.0.0--canary.461.
|
|
14
|
+
"@friggframework/schemas": "2.0.0--canary.461.9f988ca.0",
|
|
15
|
+
"@friggframework/test": "2.0.0--canary.461.9f988ca.0",
|
|
16
16
|
"@hapi/boom": "^10.0.1",
|
|
17
17
|
"@inquirer/prompts": "^5.3.8",
|
|
18
18
|
"axios": "^1.7.2",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"serverless-http": "^2.7.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@friggframework/eslint-config": "2.0.0--canary.461.
|
|
38
|
-
"@friggframework/prettier-config": "2.0.0--canary.461.
|
|
37
|
+
"@friggframework/eslint-config": "2.0.0--canary.461.9f988ca.0",
|
|
38
|
+
"@friggframework/prettier-config": "2.0.0--canary.461.9f988ca.0",
|
|
39
39
|
"aws-sdk-client-mock": "^4.1.0",
|
|
40
40
|
"aws-sdk-client-mock-jest": "^4.1.0",
|
|
41
41
|
"jest": "^30.1.3",
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"publishConfig": {
|
|
71
71
|
"access": "public"
|
|
72
72
|
},
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "9f988cad38fe00d1953292ea77dbcd46da275f23"
|
|
74
74
|
}
|