@friggframework/devtools 2.0.0--canary.414.891364b.0 → 2.0.0--canary.414.db76eeb.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,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,13 +170,13 @@ 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)
@@ -166,7 +196,7 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
166
196
  'cloudformation:DeleteChangeSet',
167
197
  'cloudformation:ExecuteChangeSet',
168
198
  'cloudformation:ValidateTemplate',
169
-
199
+
170
200
  // Lambda permissions
171
201
  'lambda:CreateFunction',
172
202
  'lambda:UpdateFunctionCode',
@@ -189,7 +219,7 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
189
219
  'lambda:TagResource',
190
220
  'lambda:UntagResource',
191
221
  'lambda:ListVersionsByFunction',
192
-
222
+
193
223
  // IAM permissions
194
224
  'iam:CreateRole',
195
225
  'iam:DeleteRole',
@@ -203,7 +233,7 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
203
233
  'iam:TagRole',
204
234
  'iam:UntagRole',
205
235
  'iam:ListPolicyVersions',
206
-
236
+
207
237
  // S3 permissions
208
238
  's3:CreateBucket',
209
239
  's3:PutObject',
@@ -214,7 +244,7 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
214
244
  's3:PutBucketPublicAccessBlock',
215
245
  's3:GetBucketLocation',
216
246
  's3:ListBucket',
217
-
247
+
218
248
  // SQS permissions
219
249
  'sqs:CreateQueue',
220
250
  'sqs:DeleteQueue',
@@ -223,7 +253,7 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
223
253
  'sqs:GetQueueUrl',
224
254
  'sqs:TagQueue',
225
255
  'sqs:UntagQueue',
226
-
256
+
227
257
  // SNS permissions
228
258
  'sns:CreateTopic',
229
259
  'sns:DeleteTopic',
@@ -234,7 +264,7 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
234
264
  'sns:ListSubscriptionsByTopic',
235
265
  'sns:TagResource',
236
266
  'sns:UntagResource',
237
-
267
+
238
268
  // CloudWatch and Logs permissions
239
269
  'cloudwatch:PutMetricAlarm',
240
270
  'cloudwatch:DeleteAlarms',
@@ -247,7 +277,7 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
247
277
  'logs:FilterLogEvents',
248
278
  'logs:PutLogEvents',
249
279
  'logs:PutRetentionPolicy',
250
-
280
+
251
281
  // API Gateway permissions
252
282
  'apigateway:POST',
253
283
  'apigateway:PUT',
@@ -255,7 +285,7 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
255
285
  'apigateway:GET',
256
286
  'apigateway:PATCH',
257
287
  'apigateway:TagResource',
258
- 'apigateway:UntagResource'
288
+ 'apigateway:UntagResource',
259
289
  ];
260
290
 
261
291
  const coreStatements = [
@@ -275,17 +305,20 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
275
305
  'cloudformation:DescribeChangeSet',
276
306
  'cloudformation:CreateChangeSet',
277
307
  'cloudformation:DeleteChangeSet',
278
- 'cloudformation:ExecuteChangeSet'
308
+ 'cloudformation:ExecuteChangeSet',
279
309
  ],
280
310
  Resource: [
281
- { 'Fn::Sub': 'arn:aws:cloudformation:*:${AWS::AccountId}:stack/*frigg*/*' }
282
- ]
311
+ {
312
+ 'Fn::Sub':
313
+ 'arn:aws:cloudformation:*:${AWS::AccountId}:stack/*frigg*/*',
314
+ },
315
+ ],
283
316
  },
284
317
  {
285
318
  Sid: 'CloudFormationValidateTemplate',
286
319
  Effect: 'Allow',
287
320
  Action: ['cloudformation:ValidateTemplate'],
288
- Resource: '*'
321
+ Resource: '*',
289
322
  },
290
323
  {
291
324
  Sid: 'S3DeploymentBucket',
@@ -299,12 +332,12 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
299
332
  's3:PutBucketVersioning',
300
333
  's3:PutBucketPublicAccessBlock',
301
334
  's3:GetBucketLocation',
302
- 's3:ListBucket'
335
+ 's3:ListBucket',
303
336
  ],
304
337
  Resource: [
305
338
  'arn:aws:s3:::*serverless*',
306
- 'arn:aws:s3:::*serverless*/*'
307
- ]
339
+ 'arn:aws:s3:::*serverless*/*',
340
+ ],
308
341
  },
309
342
  {
310
343
  Sid: 'LambdaFriggFunctions',
@@ -330,11 +363,14 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
330
363
  'lambda:DeleteConcurrency',
331
364
  'lambda:TagResource',
332
365
  'lambda:UntagResource',
333
- 'lambda:ListVersionsByFunction'
366
+ 'lambda:ListVersionsByFunction',
334
367
  ],
335
368
  Resource: [
336
- { 'Fn::Sub': 'arn:aws:lambda:*:${AWS::AccountId}:function:*frigg*' }
337
- ]
369
+ {
370
+ 'Fn::Sub':
371
+ 'arn:aws:lambda:*:${AWS::AccountId}:function:*frigg*',
372
+ },
373
+ ],
338
374
  },
339
375
  {
340
376
  Sid: 'IAMRolesForFriggLambda',
@@ -350,18 +386,23 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
350
386
  'iam:AttachRolePolicy',
351
387
  'iam:DetachRolePolicy',
352
388
  'iam:TagRole',
353
- 'iam:UntagRole'
389
+ 'iam:UntagRole',
354
390
  ],
355
391
  Resource: [
356
392
  { 'Fn::Sub': 'arn:aws:iam::${AWS::AccountId}:role/*frigg*' },
357
- { 'Fn::Sub': 'arn:aws:iam::${AWS::AccountId}:role/*frigg*LambdaRole*' }
358
- ]
393
+ {
394
+ 'Fn::Sub':
395
+ 'arn:aws:iam::${AWS::AccountId}:role/*frigg*LambdaRole*',
396
+ },
397
+ ],
359
398
  },
360
399
  {
361
400
  Sid: 'IAMPolicyVersionPermissions',
362
401
  Effect: 'Allow',
363
402
  Action: ['iam:ListPolicyVersions'],
364
- Resource: [{ 'Fn::Sub': 'arn:aws:iam::${AWS::AccountId}:policy/*' }]
403
+ Resource: [
404
+ { 'Fn::Sub': 'arn:aws:iam::${AWS::AccountId}:policy/*' },
405
+ ],
365
406
  },
366
407
  {
367
408
  Sid: 'FriggMessagingServices',
@@ -373,12 +414,15 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
373
414
  'sqs:SetQueueAttributes',
374
415
  'sqs:GetQueueUrl',
375
416
  'sqs:TagQueue',
376
- 'sqs:UntagQueue'
417
+ 'sqs:UntagQueue',
377
418
  ],
378
419
  Resource: [
379
420
  { 'Fn::Sub': 'arn:aws:sqs:*:${AWS::AccountId}:*frigg*' },
380
- { 'Fn::Sub': 'arn:aws:sqs:*:${AWS::AccountId}:internal-error-queue-*' }
381
- ]
421
+ {
422
+ 'Fn::Sub':
423
+ 'arn:aws:sqs:*:${AWS::AccountId}:internal-error-queue-*',
424
+ },
425
+ ],
382
426
  },
383
427
  {
384
428
  Sid: 'FriggSNSTopics',
@@ -392,11 +436,11 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
392
436
  'sns:Unsubscribe',
393
437
  'sns:ListSubscriptionsByTopic',
394
438
  'sns:TagResource',
395
- 'sns:UntagResource'
439
+ 'sns:UntagResource',
396
440
  ],
397
441
  Resource: [
398
- { 'Fn::Sub': 'arn:aws:sns:*:${AWS::AccountId}:*frigg*' }
399
- ]
442
+ { 'Fn::Sub': 'arn:aws:sns:*:${AWS::AccountId}:*frigg*' },
443
+ ],
400
444
  },
401
445
  {
402
446
  Sid: 'FriggMonitoringAndLogs',
@@ -412,13 +456,22 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
412
456
  'logs:DescribeLogStreams',
413
457
  'logs:FilterLogEvents',
414
458
  'logs:PutLogEvents',
415
- 'logs:PutRetentionPolicy'
459
+ 'logs:PutRetentionPolicy',
416
460
  ],
417
461
  Resource: [
418
- { 'Fn::Sub': 'arn:aws:logs:*:${AWS::AccountId}:log-group:/aws/lambda/*frigg*' },
419
- { 'Fn::Sub': 'arn:aws:logs:*:${AWS::AccountId}:log-group:/aws/lambda/*frigg*:*' },
420
- { 'Fn::Sub': 'arn:aws:cloudwatch:*:${AWS::AccountId}:alarm:*frigg*' }
421
- ]
462
+ {
463
+ 'Fn::Sub':
464
+ 'arn:aws:logs:*:${AWS::AccountId}:log-group:/aws/lambda/*frigg*',
465
+ },
466
+ {
467
+ 'Fn::Sub':
468
+ 'arn:aws:logs:*:${AWS::AccountId}:log-group:/aws/lambda/*frigg*:*',
469
+ },
470
+ {
471
+ 'Fn::Sub':
472
+ 'arn:aws:cloudwatch:*:${AWS::AccountId}:alarm:*frigg*',
473
+ },
474
+ ],
422
475
  },
423
476
  {
424
477
  Sid: 'FriggAPIGateway',
@@ -430,19 +483,35 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
430
483
  'apigateway:GET',
431
484
  'apigateway:PATCH',
432
485
  'apigateway:TagResource',
433
- 'apigateway:UntagResource'
486
+ 'apigateway:UntagResource',
434
487
  ],
435
488
  Resource: [
436
489
  'arn:aws:apigateway:*::/restapis',
437
490
  'arn:aws:apigateway:*::/restapis/*',
491
+ 'arn:aws:apigateway:*::/domainnames',
492
+ 'arn:aws:apigateway:*::/domainnames/*',
493
+ ],
494
+ },
495
+ {
496
+ Sid: 'FriggAPIGatewayV2',
497
+ Effect: 'Allow',
498
+ Action: [
499
+ 'apigateway:GET',
500
+ 'apigateway:DELETE',
501
+ 'apigateway:PATCH',
502
+ 'apigateway:POST',
503
+ 'apigateway:PUT',
504
+ ],
505
+ Resource: [
438
506
  'arn:aws:apigateway:*::/apis',
439
507
  'arn:aws:apigateway:*::/apis/*',
440
508
  'arn:aws:apigateway:*::/apis/*/stages',
441
509
  'arn:aws:apigateway:*::/apis/*/stages/*',
442
510
  'arn:aws:apigateway:*::/domainnames',
443
- 'arn:aws:apigateway:*::/domainnames/*'
444
- ]
445
- }
511
+ 'arn:aws:apigateway:*::/domainnames/*',
512
+ 'arn:aws:apigateway:*::/domainnames/*/apimappings',
513
+ ],
514
+ },
446
515
  ];
447
516
 
448
517
  template.Resources.FriggCoreDeploymentPolicy = {
@@ -452,9 +521,9 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
452
521
  Description: 'Core permissions for deploying Frigg applications',
453
522
  PolicyDocument: {
454
523
  Version: '2012-10-17',
455
- Statement: coreStatements
456
- }
457
- }
524
+ Statement: coreStatements,
525
+ },
526
+ },
458
527
  };
459
528
 
460
529
  // Add feature-specific policies only if needed
@@ -494,13 +563,15 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
494
563
  'ec2:AuthorizeSecurityGroupEgress',
495
564
  'ec2:AuthorizeSecurityGroupIngress',
496
565
  'ec2:RevokeSecurityGroupEgress',
497
- 'ec2:RevokeSecurityGroupIngress'
566
+ 'ec2:RevokeSecurityGroupIngress',
567
+ 'ec2:DetachInternetGateway',
568
+ 'ec2:DeleteSubnet',
498
569
  ],
499
- Resource: '*'
500
- }
501
- ]
502
- }
503
- }
570
+ Resource: '*',
571
+ },
572
+ ],
573
+ },
574
+ },
504
575
  };
505
576
  }
506
577
 
@@ -510,32 +581,33 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
510
581
  Condition: 'CreateKMSPermissions',
511
582
  Properties: {
512
583
  ManagedPolicyName: 'FriggKMSPolicy',
513
- Description: 'KMS encryption permissions for Frigg applications',
584
+ Description:
585
+ 'KMS encryption permissions for Frigg applications',
514
586
  PolicyDocument: {
515
587
  Version: '2012-10-17',
516
588
  Statement: [
517
589
  {
518
590
  Sid: 'FriggKMSEncryptionRuntime',
519
591
  Effect: 'Allow',
520
- Action: [
521
- 'kms:GenerateDataKey',
522
- 'kms:Decrypt'
523
- ],
592
+ Action: ['kms:GenerateDataKey', 'kms:Decrypt'],
524
593
  Resource: [
525
- { 'Fn::Sub': 'arn:aws:kms:*:${AWS::AccountId}:key/*' }
594
+ {
595
+ 'Fn::Sub':
596
+ 'arn:aws:kms:*:${AWS::AccountId}:key/*',
597
+ },
526
598
  ],
527
599
  Condition: {
528
600
  StringEquals: {
529
601
  'kms:ViaService': [
530
602
  'lambda.*.amazonaws.com',
531
- 's3.*.amazonaws.com'
532
- ]
533
- }
534
- }
535
- }
536
- ]
537
- }
538
- }
603
+ 's3.*.amazonaws.com',
604
+ ],
605
+ },
606
+ },
607
+ },
608
+ ],
609
+ },
610
+ },
539
611
  };
540
612
  }
541
613
 
@@ -545,7 +617,8 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
545
617
  Condition: 'CreateSSMPermissions',
546
618
  Properties: {
547
619
  ManagedPolicyName: 'FriggSSMPolicy',
548
- Description: 'SSM Parameter Store permissions for Frigg applications',
620
+ Description:
621
+ 'SSM Parameter Store permissions for Frigg applications',
549
622
  PolicyDocument: {
550
623
  Version: '2012-10-17',
551
624
  Statement: [
@@ -555,16 +628,22 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
555
628
  Action: [
556
629
  'ssm:GetParameter',
557
630
  'ssm:GetParameters',
558
- 'ssm:GetParametersByPath'
631
+ 'ssm:GetParametersByPath',
559
632
  ],
560
633
  Resource: [
561
- { 'Fn::Sub': 'arn:aws:ssm:*:${AWS::AccountId}:parameter/*frigg*' },
562
- { 'Fn::Sub': 'arn:aws:ssm:*:${AWS::AccountId}:parameter/*frigg*/*' }
563
- ]
564
- }
565
- ]
566
- }
567
- }
634
+ {
635
+ 'Fn::Sub':
636
+ 'arn:aws:ssm:*:${AWS::AccountId}:parameter/*frigg*',
637
+ },
638
+ {
639
+ 'Fn::Sub':
640
+ 'arn:aws:ssm:*:${AWS::AccountId}:parameter/*frigg*/*',
641
+ },
642
+ ],
643
+ },
644
+ ],
645
+ },
646
+ },
568
647
  };
569
648
  }
570
649
 
@@ -577,10 +656,11 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
577
656
  SecretString: {
578
657
  'Fn::Sub': JSON.stringify({
579
658
  AccessKeyId: '${FriggDeploymentAccessKey}',
580
- SecretAccessKey: '${FriggDeploymentAccessKey.SecretAccessKey}'
581
- })
582
- }
583
- }
659
+ SecretAccessKey:
660
+ '${FriggDeploymentAccessKey.SecretAccessKey}',
661
+ }),
662
+ },
663
+ },
584
664
  };
585
665
 
586
666
  // Add Outputs
@@ -589,29 +669,30 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
589
669
  Description: 'ARN of the Frigg deployment user',
590
670
  Value: { 'Fn::GetAtt': ['FriggDeploymentUser', 'Arn'] },
591
671
  Export: {
592
- Name: { 'Fn::Sub': '${AWS::StackName}-UserArn' }
593
- }
672
+ Name: { 'Fn::Sub': '${AWS::StackName}-UserArn' },
673
+ },
594
674
  },
595
675
  AccessKeyId: {
596
676
  Description: 'Access Key ID for the deployment user',
597
677
  Value: { Ref: 'FriggDeploymentAccessKey' },
598
678
  Export: {
599
- Name: { 'Fn::Sub': '${AWS::StackName}-AccessKeyId' }
600
- }
679
+ Name: { 'Fn::Sub': '${AWS::StackName}-AccessKeyId' },
680
+ },
601
681
  },
602
682
  SecretAccessKeyCommand: {
603
683
  Description: 'Command to retrieve the secret access key',
604
684
  Value: {
605
- 'Fn::Sub': 'aws secretsmanager get-secret-value --secret-id frigg-deployment-credentials --query SecretString --output text | jq -r .SecretAccessKey'
606
- }
685
+ 'Fn::Sub':
686
+ 'aws secretsmanager get-secret-value --secret-id frigg-deployment-credentials --query SecretString --output text | jq -r .SecretAccessKey',
687
+ },
607
688
  },
608
689
  CredentialsSecretArn: {
609
690
  Description: 'ARN of the secret containing deployment credentials',
610
691
  Value: { Ref: 'FriggDeploymentCredentials' },
611
692
  Export: {
612
- Name: { 'Fn::Sub': '${AWS::StackName}-CredentialsSecretArn' }
613
- }
614
- }
693
+ Name: { 'Fn::Sub': '${AWS::StackName}-CredentialsSecretArn' },
694
+ },
695
+ },
615
696
  };
616
697
 
617
698
  // Convert to YAML
@@ -629,7 +710,7 @@ function convertToYAML(obj) {
629
710
  indent: 2,
630
711
  lineWidth: 120,
631
712
  noRefs: true,
632
- sortKeys: false
713
+ sortKeys: false,
633
714
  });
634
715
  }
635
716
 
@@ -642,9 +723,11 @@ function getFeatureSummary(appDefinition) {
642
723
  const features = {
643
724
  core: true, // Always enabled
644
725
  vpc: appDefinition.vpc?.enable === true,
645
- kms: appDefinition.encryption?.useDefaultKMSForFieldLevelEncryption === true,
726
+ kms:
727
+ appDefinition.encryption?.useDefaultKMSForFieldLevelEncryption ===
728
+ true,
646
729
  ssm: appDefinition.ssm?.enable === true,
647
- websockets: appDefinition.websockets?.enable === true
730
+ websockets: appDefinition.websockets?.enable === true,
648
731
  };
649
732
 
650
733
  const integrationCount = appDefinition.integrations?.length || 0;
@@ -652,7 +735,7 @@ function getFeatureSummary(appDefinition) {
652
735
  return {
653
736
  features,
654
737
  integrationCount,
655
- appName: appDefinition.name || 'Unnamed Frigg App'
738
+ appName: appDefinition.name || 'Unnamed Frigg App',
656
739
  };
657
740
  }
658
741
 
@@ -691,5 +774,5 @@ module.exports = {
691
774
  getFeatureSummary,
692
775
  generateBasicIAMPolicy,
693
776
  generateFullIAMPolicy,
694
- generateIAMPolicy
695
- };
777
+ generateIAMPolicy,
778
+ };