@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.
- package/frigg-cli/deploy-command/index.js +2 -1
- package/infrastructure/AWS-IAM-CREDENTIAL-NEEDS.md +442 -411
- package/infrastructure/GENERATE-IAM-DOCS.md +91 -66
- package/infrastructure/frigg-deployment-iam-stack.yaml +22 -0
- package/infrastructure/iam-generator.js +214 -131
- package/infrastructure/serverless-template.js +418 -251
- package/package.json +6 -6
|
@@ -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
|
-
|
|
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 {
|
|
32
|
+
} else {
|
|
33
|
+
// mode === 'auto'
|
|
37
34
|
features = {
|
|
38
35
|
vpc: appDefinition.vpc?.enable === true,
|
|
39
|
-
kms:
|
|
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 ${
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
73
|
-
|
|
76
|
+
Description:
|
|
77
|
+
'Enable SSM Parameter Store permissions for Frigg applications',
|
|
78
|
+
},
|
|
74
79
|
},
|
|
75
80
|
|
|
76
81
|
Conditions: {
|
|
77
|
-
CreateVPCPermissions: {
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
{
|
|
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
|
-
{
|
|
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
|
-
{
|
|
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: [
|
|
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
|
-
{
|
|
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
|
-
{
|
|
419
|
-
|
|
420
|
-
|
|
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:
|
|
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
|
-
{
|
|
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:
|
|
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
|
-
{
|
|
562
|
-
|
|
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:
|
|
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':
|
|
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:
|
|
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
|
+
};
|