@friggframework/devtools 2.0.0-next.32 → 2.0.0-next.34

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,4 +1,3 @@
1
- const fs = require('fs-extra');
2
1
  const path = require('path');
3
2
 
4
3
  /**
@@ -11,11 +10,8 @@ const path = require('path');
11
10
  * @returns {string} CloudFormation YAML template
12
11
  */
13
12
  function generateIAMCloudFormation(appDefinition, options = {}) {
14
- const {
15
- deploymentUserName = 'frigg-deployment-user',
16
- stackName = 'frigg-deployment-iam',
17
- mode = 'auto'
18
- } = options;
13
+ const { deploymentUserName = 'frigg-deployment-user', mode = 'auto' } =
14
+ options;
19
15
 
20
16
  // Determine which features are enabled based on mode
21
17
  let features;
@@ -24,62 +20,77 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
24
20
  vpc: false,
25
21
  kms: false,
26
22
  ssm: false,
27
- websockets: appDefinition.websockets?.enable === true
23
+ websockets: appDefinition.websockets?.enable === true,
28
24
  };
29
25
  } else if (mode === 'full') {
30
26
  features = {
31
27
  vpc: true,
32
28
  kms: true,
33
29
  ssm: true,
34
- websockets: appDefinition.websockets?.enable === true
30
+ websockets: appDefinition.websockets?.enable === true,
35
31
  };
36
- } else { // mode === 'auto'
32
+ } else {
33
+ // mode === 'auto'
37
34
  features = {
38
35
  vpc: appDefinition.vpc?.enable === true,
39
- kms: appDefinition.encryption?.useDefaultKMSForFieldLevelEncryption === true,
36
+ kms:
37
+ appDefinition.encryption
38
+ ?.useDefaultKMSForFieldLevelEncryption === true,
40
39
  ssm: appDefinition.ssm?.enable === true,
41
- websockets: appDefinition.websockets?.enable === true
40
+ websockets: appDefinition.websockets?.enable === true,
42
41
  };
43
42
  }
44
43
 
45
44
  // Build the CloudFormation template
46
45
  const template = {
47
46
  AWSTemplateFormatVersion: '2010-09-09',
48
- Description: `IAM roles and policies for ${appDefinition.name || 'Frigg'} application deployment pipeline`,
49
-
47
+ Description: `IAM roles and policies for ${
48
+ appDefinition.name || 'Frigg'
49
+ } application deployment pipeline`,
50
+
50
51
  Parameters: {
51
52
  DeploymentUserName: {
52
53
  Type: 'String',
53
54
  Default: deploymentUserName,
54
- Description: 'Name for the IAM user that will deploy Frigg applications'
55
+ Description:
56
+ 'Name for the IAM user that will deploy Frigg applications',
55
57
  },
56
58
  EnableVPCSupport: {
57
59
  Type: 'String',
58
60
  Default: features.vpc ? 'true' : 'false',
59
61
  AllowedValues: ['true', 'false'],
60
- Description: 'Enable VPC-related permissions for Frigg applications'
62
+ Description:
63
+ 'Enable VPC-related permissions for Frigg applications',
61
64
  },
62
65
  EnableKMSSupport: {
63
66
  Type: 'String',
64
67
  Default: features.kms ? 'true' : 'false',
65
68
  AllowedValues: ['true', 'false'],
66
- Description: 'Enable KMS encryption permissions for Frigg applications'
69
+ Description:
70
+ 'Enable KMS encryption permissions for Frigg applications',
67
71
  },
68
72
  EnableSSMSupport: {
69
73
  Type: 'String',
70
74
  Default: features.ssm ? 'true' : 'false',
71
75
  AllowedValues: ['true', 'false'],
72
- Description: 'Enable SSM Parameter Store permissions for Frigg applications'
73
- }
76
+ Description:
77
+ 'Enable SSM Parameter Store permissions for Frigg applications',
78
+ },
74
79
  },
75
80
 
76
81
  Conditions: {
77
- CreateVPCPermissions: { 'Fn::Equals': [{ Ref: 'EnableVPCSupport' }, 'true'] },
78
- CreateKMSPermissions: { 'Fn::Equals': [{ Ref: 'EnableKMSSupport' }, 'true'] },
79
- CreateSSMPermissions: { 'Fn::Equals': [{ Ref: 'EnableSSMSupport' }, 'true'] }
82
+ CreateVPCPermissions: {
83
+ 'Fn::Equals': [{ Ref: 'EnableVPCSupport' }, 'true'],
84
+ },
85
+ CreateKMSPermissions: {
86
+ 'Fn::Equals': [{ Ref: 'EnableKMSSupport' }, 'true'],
87
+ },
88
+ CreateSSMPermissions: {
89
+ 'Fn::Equals': [{ Ref: 'EnableSSMSupport' }, 'true'],
90
+ },
80
91
  },
81
92
 
82
- Resources: {}
93
+ Resources: {},
83
94
  };
84
95
 
85
96
  // Add IAM User
@@ -89,34 +100,52 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
89
100
  UserName: { Ref: 'DeploymentUserName' },
90
101
  ManagedPolicyArns: [
91
102
  { Ref: 'FriggDiscoveryPolicy' },
92
- { Ref: 'FriggCoreDeploymentPolicy' }
93
- ]
94
- }
103
+ { Ref: 'FriggCoreDeploymentPolicy' },
104
+ ],
105
+ },
95
106
  };
96
107
 
97
108
  // Conditionally add feature-specific policies
98
109
  if (features.vpc) {
99
- template.Resources.FriggDeploymentUser.Properties.ManagedPolicyArns.push({
100
- 'Fn::If': ['CreateVPCPermissions', { Ref: 'FriggVPCPolicy' }, { Ref: 'AWS::NoValue' }]
101
- });
110
+ template.Resources.FriggDeploymentUser.Properties.ManagedPolicyArns.push(
111
+ {
112
+ 'Fn::If': [
113
+ 'CreateVPCPermissions',
114
+ { Ref: 'FriggVPCPolicy' },
115
+ { Ref: 'AWS::NoValue' },
116
+ ],
117
+ }
118
+ );
102
119
  }
103
120
  if (features.kms) {
104
- template.Resources.FriggDeploymentUser.Properties.ManagedPolicyArns.push({
105
- 'Fn::If': ['CreateKMSPermissions', { Ref: 'FriggKMSPolicy' }, { Ref: 'AWS::NoValue' }]
106
- });
121
+ template.Resources.FriggDeploymentUser.Properties.ManagedPolicyArns.push(
122
+ {
123
+ 'Fn::If': [
124
+ 'CreateKMSPermissions',
125
+ { Ref: 'FriggKMSPolicy' },
126
+ { Ref: 'AWS::NoValue' },
127
+ ],
128
+ }
129
+ );
107
130
  }
108
131
  if (features.ssm) {
109
- template.Resources.FriggDeploymentUser.Properties.ManagedPolicyArns.push({
110
- 'Fn::If': ['CreateSSMPermissions', { Ref: 'FriggSSMPolicy' }, { Ref: 'AWS::NoValue' }]
111
- });
132
+ template.Resources.FriggDeploymentUser.Properties.ManagedPolicyArns.push(
133
+ {
134
+ 'Fn::If': [
135
+ 'CreateSSMPermissions',
136
+ { Ref: 'FriggSSMPolicy' },
137
+ { Ref: 'AWS::NoValue' },
138
+ ],
139
+ }
140
+ );
112
141
  }
113
142
 
114
143
  // Add Access Key
115
144
  template.Resources.FriggDeploymentAccessKey = {
116
145
  Type: 'AWS::IAM::AccessKey',
117
146
  Properties: {
118
- UserName: { Ref: 'FriggDeploymentUser' }
119
- }
147
+ UserName: { Ref: 'FriggDeploymentUser' },
148
+ },
120
149
  };
121
150
 
122
151
  // Add Discovery Policy (always needed)
@@ -124,7 +153,8 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
124
153
  Type: 'AWS::IAM::ManagedPolicy',
125
154
  Properties: {
126
155
  ManagedPolicyName: 'FriggDiscoveryPolicy',
127
- Description: 'Permissions for AWS resource discovery during Frigg build process',
156
+ Description:
157
+ 'Permissions for AWS resource discovery during Frigg build process',
128
158
  PolicyDocument: {
129
159
  Version: '2012-10-17',
130
160
  Statement: [
@@ -140,122 +170,16 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
140
170
  'ec2:DescribeNatGateways',
141
171
  'ec2:DescribeAddresses',
142
172
  'kms:ListKeys',
143
- 'kms:DescribeKey'
173
+ 'kms:DescribeKey',
144
174
  ],
145
- Resource: '*'
146
- }
147
- ]
148
- }
149
- }
175
+ Resource: '*',
176
+ },
177
+ ],
178
+ },
179
+ },
150
180
  };
151
181
 
152
182
  // Add Core Deployment Policy (always needed)
153
- const coreActions = [
154
- // CloudFormation permissions
155
- 'cloudformation:CreateStack',
156
- 'cloudformation:UpdateStack',
157
- 'cloudformation:DeleteStack',
158
- 'cloudformation:DescribeStacks',
159
- 'cloudformation:DescribeStackEvents',
160
- 'cloudformation:DescribeStackResources',
161
- 'cloudformation:DescribeStackResource',
162
- 'cloudformation:ListStackResources',
163
- 'cloudformation:GetTemplate',
164
- 'cloudformation:DescribeChangeSet',
165
- 'cloudformation:CreateChangeSet',
166
- 'cloudformation:DeleteChangeSet',
167
- 'cloudformation:ExecuteChangeSet',
168
- 'cloudformation:ValidateTemplate',
169
-
170
- // Lambda permissions
171
- 'lambda:CreateFunction',
172
- 'lambda:UpdateFunctionCode',
173
- 'lambda:UpdateFunctionConfiguration',
174
- 'lambda:DeleteFunction',
175
- 'lambda:GetFunction',
176
- 'lambda:ListFunctions',
177
- 'lambda:PublishVersion',
178
- 'lambda:CreateAlias',
179
- 'lambda:UpdateAlias',
180
- 'lambda:DeleteAlias',
181
- 'lambda:GetAlias',
182
- 'lambda:AddPermission',
183
- 'lambda:RemovePermission',
184
- 'lambda:GetPolicy',
185
- 'lambda:PutProvisionedConcurrencyConfig',
186
- 'lambda:DeleteProvisionedConcurrencyConfig',
187
- 'lambda:PutConcurrency',
188
- 'lambda:DeleteConcurrency',
189
- 'lambda:TagResource',
190
- 'lambda:UntagResource',
191
- 'lambda:ListVersionsByFunction',
192
-
193
- // IAM permissions
194
- 'iam:CreateRole',
195
- 'iam:DeleteRole',
196
- 'iam:GetRole',
197
- 'iam:PassRole',
198
- 'iam:PutRolePolicy',
199
- 'iam:DeleteRolePolicy',
200
- 'iam:GetRolePolicy',
201
- 'iam:AttachRolePolicy',
202
- 'iam:DetachRolePolicy',
203
- 'iam:TagRole',
204
- 'iam:UntagRole',
205
- 'iam:ListPolicyVersions',
206
-
207
- // S3 permissions
208
- 's3:CreateBucket',
209
- 's3:PutObject',
210
- 's3:GetObject',
211
- 's3:DeleteObject',
212
- 's3:PutBucketPolicy',
213
- 's3:PutBucketVersioning',
214
- 's3:PutBucketPublicAccessBlock',
215
- 's3:GetBucketLocation',
216
- 's3:ListBucket',
217
-
218
- // SQS permissions
219
- 'sqs:CreateQueue',
220
- 'sqs:DeleteQueue',
221
- 'sqs:GetQueueAttributes',
222
- 'sqs:SetQueueAttributes',
223
- 'sqs:GetQueueUrl',
224
- 'sqs:TagQueue',
225
- 'sqs:UntagQueue',
226
-
227
- // SNS permissions
228
- 'sns:CreateTopic',
229
- 'sns:DeleteTopic',
230
- 'sns:GetTopicAttributes',
231
- 'sns:SetTopicAttributes',
232
- 'sns:Subscribe',
233
- 'sns:Unsubscribe',
234
- 'sns:ListSubscriptionsByTopic',
235
- 'sns:TagResource',
236
- 'sns:UntagResource',
237
-
238
- // CloudWatch and Logs permissions
239
- 'cloudwatch:PutMetricAlarm',
240
- 'cloudwatch:DeleteAlarms',
241
- 'cloudwatch:DescribeAlarms',
242
- 'logs:CreateLogGroup',
243
- 'logs:CreateLogStream',
244
- 'logs:DeleteLogGroup',
245
- 'logs:DescribeLogGroups',
246
- 'logs:DescribeLogStreams',
247
- 'logs:FilterLogEvents',
248
- 'logs:PutLogEvents',
249
- 'logs:PutRetentionPolicy',
250
-
251
- // API Gateway permissions
252
- 'apigateway:POST',
253
- 'apigateway:PUT',
254
- 'apigateway:DELETE',
255
- 'apigateway:GET',
256
- 'apigateway:PATCH'
257
- ];
258
-
259
183
  const coreStatements = [
260
184
  {
261
185
  Sid: 'CloudFormationFriggStacks',
@@ -273,17 +197,20 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
273
197
  'cloudformation:DescribeChangeSet',
274
198
  'cloudformation:CreateChangeSet',
275
199
  'cloudformation:DeleteChangeSet',
276
- 'cloudformation:ExecuteChangeSet'
200
+ 'cloudformation:ExecuteChangeSet',
277
201
  ],
278
202
  Resource: [
279
- { 'Fn::Sub': 'arn:aws:cloudformation:*:${AWS::AccountId}:stack/*frigg*/*' }
280
- ]
203
+ {
204
+ 'Fn::Sub':
205
+ 'arn:aws:cloudformation:*:${AWS::AccountId}:stack/*frigg*/*',
206
+ },
207
+ ],
281
208
  },
282
209
  {
283
210
  Sid: 'CloudFormationValidateTemplate',
284
211
  Effect: 'Allow',
285
212
  Action: ['cloudformation:ValidateTemplate'],
286
- Resource: '*'
213
+ Resource: '*',
287
214
  },
288
215
  {
289
216
  Sid: 'S3DeploymentBucket',
@@ -297,12 +224,12 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
297
224
  's3:PutBucketVersioning',
298
225
  's3:PutBucketPublicAccessBlock',
299
226
  's3:GetBucketLocation',
300
- 's3:ListBucket'
227
+ 's3:ListBucket',
301
228
  ],
302
229
  Resource: [
303
230
  'arn:aws:s3:::*serverless*',
304
- 'arn:aws:s3:::*serverless*/*'
305
- ]
231
+ 'arn:aws:s3:::*serverless*/*',
232
+ ],
306
233
  },
307
234
  {
308
235
  Sid: 'LambdaFriggFunctions',
@@ -328,11 +255,14 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
328
255
  'lambda:DeleteConcurrency',
329
256
  'lambda:TagResource',
330
257
  'lambda:UntagResource',
331
- 'lambda:ListVersionsByFunction'
258
+ 'lambda:ListVersionsByFunction',
332
259
  ],
333
260
  Resource: [
334
- { 'Fn::Sub': 'arn:aws:lambda:*:${AWS::AccountId}:function:*frigg*' }
335
- ]
261
+ {
262
+ 'Fn::Sub':
263
+ 'arn:aws:lambda:*:${AWS::AccountId}:function:*frigg*',
264
+ },
265
+ ],
336
266
  },
337
267
  {
338
268
  Sid: 'IAMRolesForFriggLambda',
@@ -348,18 +278,23 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
348
278
  'iam:AttachRolePolicy',
349
279
  'iam:DetachRolePolicy',
350
280
  'iam:TagRole',
351
- 'iam:UntagRole'
281
+ 'iam:UntagRole',
352
282
  ],
353
283
  Resource: [
354
284
  { 'Fn::Sub': 'arn:aws:iam::${AWS::AccountId}:role/*frigg*' },
355
- { 'Fn::Sub': 'arn:aws:iam::${AWS::AccountId}:role/*frigg*LambdaRole*' }
356
- ]
285
+ {
286
+ 'Fn::Sub':
287
+ 'arn:aws:iam::${AWS::AccountId}:role/*frigg*LambdaRole*',
288
+ },
289
+ ],
357
290
  },
358
291
  {
359
292
  Sid: 'IAMPolicyVersionPermissions',
360
293
  Effect: 'Allow',
361
294
  Action: ['iam:ListPolicyVersions'],
362
- Resource: [{ 'Fn::Sub': 'arn:aws:iam::${AWS::AccountId}:policy/*' }]
295
+ Resource: [
296
+ { 'Fn::Sub': 'arn:aws:iam::${AWS::AccountId}:policy/*' },
297
+ ],
363
298
  },
364
299
  {
365
300
  Sid: 'FriggMessagingServices',
@@ -371,12 +306,15 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
371
306
  'sqs:SetQueueAttributes',
372
307
  'sqs:GetQueueUrl',
373
308
  'sqs:TagQueue',
374
- 'sqs:UntagQueue'
309
+ 'sqs:UntagQueue',
375
310
  ],
376
311
  Resource: [
377
312
  { 'Fn::Sub': 'arn:aws:sqs:*:${AWS::AccountId}:*frigg*' },
378
- { 'Fn::Sub': 'arn:aws:sqs:*:${AWS::AccountId}:internal-error-queue-*' }
379
- ]
313
+ {
314
+ 'Fn::Sub':
315
+ 'arn:aws:sqs:*:${AWS::AccountId}:internal-error-queue-*',
316
+ },
317
+ ],
380
318
  },
381
319
  {
382
320
  Sid: 'FriggSNSTopics',
@@ -390,11 +328,11 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
390
328
  'sns:Unsubscribe',
391
329
  'sns:ListSubscriptionsByTopic',
392
330
  'sns:TagResource',
393
- 'sns:UntagResource'
331
+ 'sns:UntagResource',
394
332
  ],
395
333
  Resource: [
396
- { 'Fn::Sub': 'arn:aws:sns:*:${AWS::AccountId}:*frigg*' }
397
- ]
334
+ { 'Fn::Sub': 'arn:aws:sns:*:${AWS::AccountId}:*frigg*' },
335
+ ],
398
336
  },
399
337
  {
400
338
  Sid: 'FriggMonitoringAndLogs',
@@ -410,13 +348,22 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
410
348
  'logs:DescribeLogStreams',
411
349
  'logs:FilterLogEvents',
412
350
  'logs:PutLogEvents',
413
- 'logs:PutRetentionPolicy'
351
+ 'logs:PutRetentionPolicy',
414
352
  ],
415
353
  Resource: [
416
- { 'Fn::Sub': 'arn:aws:logs:*:${AWS::AccountId}:log-group:/aws/lambda/*frigg*' },
417
- { 'Fn::Sub': 'arn:aws:logs:*:${AWS::AccountId}:log-group:/aws/lambda/*frigg*:*' },
418
- { 'Fn::Sub': 'arn:aws:cloudwatch:*:${AWS::AccountId}:alarm:*frigg*' }
419
- ]
354
+ {
355
+ 'Fn::Sub':
356
+ 'arn:aws:logs:*:${AWS::AccountId}:log-group:/aws/lambda/*frigg*',
357
+ },
358
+ {
359
+ 'Fn::Sub':
360
+ 'arn:aws:logs:*:${AWS::AccountId}:log-group:/aws/lambda/*frigg*:*',
361
+ },
362
+ {
363
+ 'Fn::Sub':
364
+ 'arn:aws:cloudwatch:*:${AWS::AccountId}:alarm:*frigg*',
365
+ },
366
+ ],
420
367
  },
421
368
  {
422
369
  Sid: 'FriggAPIGateway',
@@ -426,15 +373,37 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
426
373
  'apigateway:PUT',
427
374
  'apigateway:DELETE',
428
375
  'apigateway:GET',
429
- 'apigateway:PATCH'
376
+ 'apigateway:PATCH',
430
377
  ],
431
378
  Resource: [
432
379
  'arn:aws:apigateway:*::/restapis',
433
380
  'arn:aws:apigateway:*::/restapis/*',
434
381
  'arn:aws:apigateway:*::/domainnames',
435
- 'arn:aws:apigateway:*::/domainnames/*'
436
- ]
437
- }
382
+ 'arn:aws:apigateway:*::/domainnames/*',
383
+ ],
384
+ },
385
+ {
386
+ Sid: 'FriggAPIGatewayV2',
387
+ Effect: 'Allow',
388
+ Action: [
389
+ 'apigateway:GET',
390
+ 'apigateway:DELETE',
391
+ 'apigateway:PATCH',
392
+ 'apigateway:POST',
393
+ 'apigateway:PUT',
394
+ ],
395
+ Resource: [
396
+ 'arn:aws:apigateway:*::/apis',
397
+ 'arn:aws:apigateway:*::/apis/*',
398
+ 'arn:aws:apigateway:*::/apis/*/stages',
399
+ 'arn:aws:apigateway:*::/apis/*/stages/*',
400
+ 'arn:aws:apigateway:*::/apis/*/mappings',
401
+ 'arn:aws:apigateway:*::/apis/*/mappings/*',
402
+ 'arn:aws:apigateway:*::/domainnames',
403
+ 'arn:aws:apigateway:*::/domainnames/*',
404
+ 'arn:aws:apigateway:*::/domainnames/*/apimappings',
405
+ ],
406
+ },
438
407
  ];
439
408
 
440
409
  template.Resources.FriggCoreDeploymentPolicy = {
@@ -444,9 +413,9 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
444
413
  Description: 'Core permissions for deploying Frigg applications',
445
414
  PolicyDocument: {
446
415
  Version: '2012-10-17',
447
- Statement: coreStatements
448
- }
449
- }
416
+ Statement: coreStatements,
417
+ },
418
+ },
450
419
  };
451
420
 
452
421
  // Add feature-specific policies only if needed
@@ -486,13 +455,15 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
486
455
  'ec2:AuthorizeSecurityGroupEgress',
487
456
  'ec2:AuthorizeSecurityGroupIngress',
488
457
  'ec2:RevokeSecurityGroupEgress',
489
- 'ec2:RevokeSecurityGroupIngress'
458
+ 'ec2:RevokeSecurityGroupIngress',
459
+ 'ec2:DetachInternetGateway',
460
+ 'ec2:DeleteSubnet',
490
461
  ],
491
- Resource: '*'
492
- }
493
- ]
494
- }
495
- }
462
+ Resource: '*',
463
+ },
464
+ ],
465
+ },
466
+ },
496
467
  };
497
468
  }
498
469
 
@@ -502,32 +473,33 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
502
473
  Condition: 'CreateKMSPermissions',
503
474
  Properties: {
504
475
  ManagedPolicyName: 'FriggKMSPolicy',
505
- Description: 'KMS encryption permissions for Frigg applications',
476
+ Description:
477
+ 'KMS encryption permissions for Frigg applications',
506
478
  PolicyDocument: {
507
479
  Version: '2012-10-17',
508
480
  Statement: [
509
481
  {
510
482
  Sid: 'FriggKMSEncryptionRuntime',
511
483
  Effect: 'Allow',
512
- Action: [
513
- 'kms:GenerateDataKey',
514
- 'kms:Decrypt'
515
- ],
484
+ Action: ['kms:GenerateDataKey', 'kms:Decrypt'],
516
485
  Resource: [
517
- { 'Fn::Sub': 'arn:aws:kms:*:${AWS::AccountId}:key/*' }
486
+ {
487
+ 'Fn::Sub':
488
+ 'arn:aws:kms:*:${AWS::AccountId}:key/*',
489
+ },
518
490
  ],
519
491
  Condition: {
520
492
  StringEquals: {
521
493
  'kms:ViaService': [
522
494
  'lambda.*.amazonaws.com',
523
- 's3.*.amazonaws.com'
524
- ]
525
- }
526
- }
527
- }
528
- ]
529
- }
530
- }
495
+ 's3.*.amazonaws.com',
496
+ ],
497
+ },
498
+ },
499
+ },
500
+ ],
501
+ },
502
+ },
531
503
  };
532
504
  }
533
505
 
@@ -537,7 +509,8 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
537
509
  Condition: 'CreateSSMPermissions',
538
510
  Properties: {
539
511
  ManagedPolicyName: 'FriggSSMPolicy',
540
- Description: 'SSM Parameter Store permissions for Frigg applications',
512
+ Description:
513
+ 'SSM Parameter Store permissions for Frigg applications',
541
514
  PolicyDocument: {
542
515
  Version: '2012-10-17',
543
516
  Statement: [
@@ -547,16 +520,22 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
547
520
  Action: [
548
521
  'ssm:GetParameter',
549
522
  'ssm:GetParameters',
550
- 'ssm:GetParametersByPath'
523
+ 'ssm:GetParametersByPath',
551
524
  ],
552
525
  Resource: [
553
- { 'Fn::Sub': 'arn:aws:ssm:*:${AWS::AccountId}:parameter/*frigg*' },
554
- { 'Fn::Sub': 'arn:aws:ssm:*:${AWS::AccountId}:parameter/*frigg*/*' }
555
- ]
556
- }
557
- ]
558
- }
559
- }
526
+ {
527
+ 'Fn::Sub':
528
+ 'arn:aws:ssm:*:${AWS::AccountId}:parameter/*frigg*',
529
+ },
530
+ {
531
+ 'Fn::Sub':
532
+ 'arn:aws:ssm:*:${AWS::AccountId}:parameter/*frigg*/*',
533
+ },
534
+ ],
535
+ },
536
+ ],
537
+ },
538
+ },
560
539
  };
561
540
  }
562
541
 
@@ -569,10 +548,11 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
569
548
  SecretString: {
570
549
  'Fn::Sub': JSON.stringify({
571
550
  AccessKeyId: '${FriggDeploymentAccessKey}',
572
- SecretAccessKey: '${FriggDeploymentAccessKey.SecretAccessKey}'
573
- })
574
- }
575
- }
551
+ SecretAccessKey:
552
+ '${FriggDeploymentAccessKey.SecretAccessKey}',
553
+ }),
554
+ },
555
+ },
576
556
  };
577
557
 
578
558
  // Add Outputs
@@ -581,29 +561,30 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
581
561
  Description: 'ARN of the Frigg deployment user',
582
562
  Value: { 'Fn::GetAtt': ['FriggDeploymentUser', 'Arn'] },
583
563
  Export: {
584
- Name: { 'Fn::Sub': '${AWS::StackName}-UserArn' }
585
- }
564
+ Name: { 'Fn::Sub': '${AWS::StackName}-UserArn' },
565
+ },
586
566
  },
587
567
  AccessKeyId: {
588
568
  Description: 'Access Key ID for the deployment user',
589
569
  Value: { Ref: 'FriggDeploymentAccessKey' },
590
570
  Export: {
591
- Name: { 'Fn::Sub': '${AWS::StackName}-AccessKeyId' }
592
- }
571
+ Name: { 'Fn::Sub': '${AWS::StackName}-AccessKeyId' },
572
+ },
593
573
  },
594
574
  SecretAccessKeyCommand: {
595
575
  Description: 'Command to retrieve the secret access key',
596
576
  Value: {
597
- 'Fn::Sub': 'aws secretsmanager get-secret-value --secret-id frigg-deployment-credentials --query SecretString --output text | jq -r .SecretAccessKey'
598
- }
577
+ 'Fn::Sub':
578
+ 'aws secretsmanager get-secret-value --secret-id frigg-deployment-credentials --query SecretString --output text | jq -r .SecretAccessKey',
579
+ },
599
580
  },
600
581
  CredentialsSecretArn: {
601
582
  Description: 'ARN of the secret containing deployment credentials',
602
583
  Value: { Ref: 'FriggDeploymentCredentials' },
603
584
  Export: {
604
- Name: { 'Fn::Sub': '${AWS::StackName}-CredentialsSecretArn' }
605
- }
606
- }
585
+ Name: { 'Fn::Sub': '${AWS::StackName}-CredentialsSecretArn' },
586
+ },
587
+ },
607
588
  };
608
589
 
609
590
  // Convert to YAML
@@ -621,7 +602,7 @@ function convertToYAML(obj) {
621
602
  indent: 2,
622
603
  lineWidth: 120,
623
604
  noRefs: true,
624
- sortKeys: false
605
+ sortKeys: false,
625
606
  });
626
607
  }
627
608
 
@@ -634,9 +615,11 @@ function getFeatureSummary(appDefinition) {
634
615
  const features = {
635
616
  core: true, // Always enabled
636
617
  vpc: appDefinition.vpc?.enable === true,
637
- kms: appDefinition.encryption?.useDefaultKMSForFieldLevelEncryption === true,
618
+ kms:
619
+ appDefinition.encryption?.useDefaultKMSForFieldLevelEncryption ===
620
+ true,
638
621
  ssm: appDefinition.ssm?.enable === true,
639
- websockets: appDefinition.websockets?.enable === true
622
+ websockets: appDefinition.websockets?.enable === true,
640
623
  };
641
624
 
642
625
  const integrationCount = appDefinition.integrations?.length || 0;
@@ -644,7 +627,7 @@ function getFeatureSummary(appDefinition) {
644
627
  return {
645
628
  features,
646
629
  integrationCount,
647
- appName: appDefinition.name || 'Unnamed Frigg App'
630
+ appName: appDefinition.name || 'Unnamed Frigg App',
648
631
  };
649
632
  }
650
633
 
@@ -683,5 +666,5 @@ module.exports = {
683
666
  getFeatureSummary,
684
667
  generateBasicIAMPolicy,
685
668
  generateFullIAMPolicy,
686
- generateIAMPolicy
687
- };
669
+ generateIAMPolicy,
670
+ };