@friggframework/devtools 2.0.0-next.33 → 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,17 +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/*',
381
+ 'arn:aws:apigateway:*::/domainnames',
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: [
434
396
  'arn:aws:apigateway:*::/apis',
435
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/*',
436
402
  'arn:aws:apigateway:*::/domainnames',
437
- 'arn:aws:apigateway:*::/domainnames/*'
438
- ]
439
- }
403
+ 'arn:aws:apigateway:*::/domainnames/*',
404
+ 'arn:aws:apigateway:*::/domainnames/*/apimappings',
405
+ ],
406
+ },
440
407
  ];
441
408
 
442
409
  template.Resources.FriggCoreDeploymentPolicy = {
@@ -446,9 +413,9 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
446
413
  Description: 'Core permissions for deploying Frigg applications',
447
414
  PolicyDocument: {
448
415
  Version: '2012-10-17',
449
- Statement: coreStatements
450
- }
451
- }
416
+ Statement: coreStatements,
417
+ },
418
+ },
452
419
  };
453
420
 
454
421
  // Add feature-specific policies only if needed
@@ -488,13 +455,15 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
488
455
  'ec2:AuthorizeSecurityGroupEgress',
489
456
  'ec2:AuthorizeSecurityGroupIngress',
490
457
  'ec2:RevokeSecurityGroupEgress',
491
- 'ec2:RevokeSecurityGroupIngress'
458
+ 'ec2:RevokeSecurityGroupIngress',
459
+ 'ec2:DetachInternetGateway',
460
+ 'ec2:DeleteSubnet',
492
461
  ],
493
- Resource: '*'
494
- }
495
- ]
496
- }
497
- }
462
+ Resource: '*',
463
+ },
464
+ ],
465
+ },
466
+ },
498
467
  };
499
468
  }
500
469
 
@@ -504,32 +473,33 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
504
473
  Condition: 'CreateKMSPermissions',
505
474
  Properties: {
506
475
  ManagedPolicyName: 'FriggKMSPolicy',
507
- Description: 'KMS encryption permissions for Frigg applications',
476
+ Description:
477
+ 'KMS encryption permissions for Frigg applications',
508
478
  PolicyDocument: {
509
479
  Version: '2012-10-17',
510
480
  Statement: [
511
481
  {
512
482
  Sid: 'FriggKMSEncryptionRuntime',
513
483
  Effect: 'Allow',
514
- Action: [
515
- 'kms:GenerateDataKey',
516
- 'kms:Decrypt'
517
- ],
484
+ Action: ['kms:GenerateDataKey', 'kms:Decrypt'],
518
485
  Resource: [
519
- { 'Fn::Sub': 'arn:aws:kms:*:${AWS::AccountId}:key/*' }
486
+ {
487
+ 'Fn::Sub':
488
+ 'arn:aws:kms:*:${AWS::AccountId}:key/*',
489
+ },
520
490
  ],
521
491
  Condition: {
522
492
  StringEquals: {
523
493
  'kms:ViaService': [
524
494
  'lambda.*.amazonaws.com',
525
- 's3.*.amazonaws.com'
526
- ]
527
- }
528
- }
529
- }
530
- ]
531
- }
532
- }
495
+ 's3.*.amazonaws.com',
496
+ ],
497
+ },
498
+ },
499
+ },
500
+ ],
501
+ },
502
+ },
533
503
  };
534
504
  }
535
505
 
@@ -539,7 +509,8 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
539
509
  Condition: 'CreateSSMPermissions',
540
510
  Properties: {
541
511
  ManagedPolicyName: 'FriggSSMPolicy',
542
- Description: 'SSM Parameter Store permissions for Frigg applications',
512
+ Description:
513
+ 'SSM Parameter Store permissions for Frigg applications',
543
514
  PolicyDocument: {
544
515
  Version: '2012-10-17',
545
516
  Statement: [
@@ -549,16 +520,22 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
549
520
  Action: [
550
521
  'ssm:GetParameter',
551
522
  'ssm:GetParameters',
552
- 'ssm:GetParametersByPath'
523
+ 'ssm:GetParametersByPath',
553
524
  ],
554
525
  Resource: [
555
- { 'Fn::Sub': 'arn:aws:ssm:*:${AWS::AccountId}:parameter/*frigg*' },
556
- { 'Fn::Sub': 'arn:aws:ssm:*:${AWS::AccountId}:parameter/*frigg*/*' }
557
- ]
558
- }
559
- ]
560
- }
561
- }
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
+ },
562
539
  };
563
540
  }
564
541
 
@@ -571,10 +548,11 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
571
548
  SecretString: {
572
549
  'Fn::Sub': JSON.stringify({
573
550
  AccessKeyId: '${FriggDeploymentAccessKey}',
574
- SecretAccessKey: '${FriggDeploymentAccessKey.SecretAccessKey}'
575
- })
576
- }
577
- }
551
+ SecretAccessKey:
552
+ '${FriggDeploymentAccessKey.SecretAccessKey}',
553
+ }),
554
+ },
555
+ },
578
556
  };
579
557
 
580
558
  // Add Outputs
@@ -583,29 +561,30 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
583
561
  Description: 'ARN of the Frigg deployment user',
584
562
  Value: { 'Fn::GetAtt': ['FriggDeploymentUser', 'Arn'] },
585
563
  Export: {
586
- Name: { 'Fn::Sub': '${AWS::StackName}-UserArn' }
587
- }
564
+ Name: { 'Fn::Sub': '${AWS::StackName}-UserArn' },
565
+ },
588
566
  },
589
567
  AccessKeyId: {
590
568
  Description: 'Access Key ID for the deployment user',
591
569
  Value: { Ref: 'FriggDeploymentAccessKey' },
592
570
  Export: {
593
- Name: { 'Fn::Sub': '${AWS::StackName}-AccessKeyId' }
594
- }
571
+ Name: { 'Fn::Sub': '${AWS::StackName}-AccessKeyId' },
572
+ },
595
573
  },
596
574
  SecretAccessKeyCommand: {
597
575
  Description: 'Command to retrieve the secret access key',
598
576
  Value: {
599
- 'Fn::Sub': 'aws secretsmanager get-secret-value --secret-id frigg-deployment-credentials --query SecretString --output text | jq -r .SecretAccessKey'
600
- }
577
+ 'Fn::Sub':
578
+ 'aws secretsmanager get-secret-value --secret-id frigg-deployment-credentials --query SecretString --output text | jq -r .SecretAccessKey',
579
+ },
601
580
  },
602
581
  CredentialsSecretArn: {
603
582
  Description: 'ARN of the secret containing deployment credentials',
604
583
  Value: { Ref: 'FriggDeploymentCredentials' },
605
584
  Export: {
606
- Name: { 'Fn::Sub': '${AWS::StackName}-CredentialsSecretArn' }
607
- }
608
- }
585
+ Name: { 'Fn::Sub': '${AWS::StackName}-CredentialsSecretArn' },
586
+ },
587
+ },
609
588
  };
610
589
 
611
590
  // Convert to YAML
@@ -623,7 +602,7 @@ function convertToYAML(obj) {
623
602
  indent: 2,
624
603
  lineWidth: 120,
625
604
  noRefs: true,
626
- sortKeys: false
605
+ sortKeys: false,
627
606
  });
628
607
  }
629
608
 
@@ -636,9 +615,11 @@ function getFeatureSummary(appDefinition) {
636
615
  const features = {
637
616
  core: true, // Always enabled
638
617
  vpc: appDefinition.vpc?.enable === true,
639
- kms: appDefinition.encryption?.useDefaultKMSForFieldLevelEncryption === true,
618
+ kms:
619
+ appDefinition.encryption?.useDefaultKMSForFieldLevelEncryption ===
620
+ true,
640
621
  ssm: appDefinition.ssm?.enable === true,
641
- websockets: appDefinition.websockets?.enable === true
622
+ websockets: appDefinition.websockets?.enable === true,
642
623
  };
643
624
 
644
625
  const integrationCount = appDefinition.integrations?.length || 0;
@@ -646,7 +627,7 @@ function getFeatureSummary(appDefinition) {
646
627
  return {
647
628
  features,
648
629
  integrationCount,
649
- appName: appDefinition.name || 'Unnamed Frigg App'
630
+ appName: appDefinition.name || 'Unnamed Frigg App',
650
631
  };
651
632
  }
652
633
 
@@ -685,5 +666,5 @@ module.exports = {
685
666
  getFeatureSummary,
686
667
  generateBasicIAMPolicy,
687
668
  generateFullIAMPolicy,
688
- generateIAMPolicy
689
- };
669
+ generateIAMPolicy,
670
+ };