@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.
- package/frigg-cli/deploy-command/index.js +6 -3
- 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 +210 -229
- package/infrastructure/serverless-template.js +412 -243
- 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,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
|
-
{
|
|
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
|
-
{
|
|
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
|
-
{
|
|
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: [
|
|
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
|
-
{
|
|
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
|
-
{
|
|
417
|
-
|
|
418
|
-
|
|
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:
|
|
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
|
-
{
|
|
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:
|
|
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
|
-
{
|
|
556
|
-
|
|
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:
|
|
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':
|
|
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:
|
|
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
|
+
};
|