-
Notifications
You must be signed in to change notification settings - Fork 0
/
iam-stack.yaml
553 lines (523 loc) · 20.6 KB
/
iam-stack.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
AWSTemplateFormatVersion: '2010-09-09'
Description: |-
> Deploys the identity management for the deployment
Parameters:
RootDomainName:
Type: String
Description: The root (without www or https) DNS name of the website e.g. cloudarchitecture.io
AllowedPattern: (?!-)[a-zA-Z0-9-.]{1,63}(?<!-)
ConstraintDescription: Must be a valid root domain name
WebStackName:
Type: String
Description: Name of the web stack, e.g. namethatsnotlonger-web-stack.
DnsStackName:
Type: String
Description: Name of the DNS stack, e.g. namethatsnotlonger-dns-stack.
CertificateStackName:
Type: String
Description: Name of the certificate stack, e.g. namethatsnotlonger-cert-stack.
Resources: # Granularity cheatsheet: https://iam.cloudonaut.io/
# -----------------------------
# ------ User & Groups --------
# -----------------------------
DeploymentGroup:
Type: AWS::IAM::Group
Properties:
# GroupName: No hardcoded naming because of easier CloudFormation management
ManagedPolicyArns:
- !Ref AllowValidateTemplatePolicy
DeploymentUser:
Type: AWS::IAM::User
Properties:
# # UserName: No hardcoded naming because of easier CloudFormation management
# # Policies: Assing policies on group level
Tags:
-
Key: Application
Value: !Ref RootDomainName
AddDeploymentUserToDeploymentGroup:
Type: AWS::IAM::UserToGroupAddition
Properties:
GroupName: !Ref DeploymentGroup
Users:
- !Ref DeploymentUser
# -----------------------------
# ----------- Roles -----------
# -----------------------------
IamStackDeployRole:
Type: AWS::IAM::Role
Properties:
Description: Allows to deploy IAM stack
AssumeRolePolicyDocument:
Statement:
-
Effect: Allow
Principal:
AWS: !GetAtt DeploymentUser.Arn
Action: sts:AssumeRole
Tags:
-
Key: Application
Value: !Ref RootDomainName
ManagedPolicyArns:
- !Ref CloudFormationDeployPolicy
- !Ref PolicyDeployPolicy
- !Ref IamStackDeployPolicy
CertStackDeployRole: # We use shorter name ("cert") to allow longer stack names (stackname+rolename cannot reach 50 chars with managed names) & IAM rules work with stack prefix
Type: AWS::IAM::Role
Properties:
Description: Allows to deploy certificate stack
AssumeRolePolicyDocument:
Statement:
-
Effect: Allow
Principal:
AWS: !GetAtt DeploymentUser.Arn
Action: sts:AssumeRole
Tags:
-
Key: Application
Value: !Ref RootDomainName
ManagedPolicyArns:
- !Ref CloudFormationDeployPolicy
- !Ref LambdaBackedCustomResourceDeployPolicy
- !Ref RecordSetUpdatePolicy
DnsStackDeployRole:
Type: AWS::IAM::Role
Properties:
Description: Allows to deploy DNS stack
AssumeRolePolicyDocument:
Statement:
-
Effect: Allow
Principal:
AWS: !GetAtt DeploymentUser.Arn
Action: sts:AssumeRole
Tags:
-
Key: Application
Value: !Ref RootDomainName
ManagedPolicyArns:
- !Ref CloudFormationDeployPolicy
- !Ref DnsStackDeployPolicy
WebStackDeployRole:
Type: AWS::IAM::Role
Properties:
Description: Allows to deploy web stack
AssumeRolePolicyDocument:
Statement:
-
Effect: Allow
Principal:
AWS: !GetAtt DeploymentUser.Arn
Action: sts:AssumeRole
Tags:
-
Key: Application
Value: !Ref RootDomainName
ManagedPolicyArns:
- !Ref CloudFormationDeployPolicy
- !Ref WebStackDeployPolicy
- !Ref WebStackLambdaEdgeDeployPolicy
- !Ref RecordSetUpdatePolicy
S3AppDeployRole:
Type: 'AWS::IAM::Role'
Properties:
Description: "Allows to deploy website to S3"
AssumeRolePolicyDocument:
Statement:
-
Effect: Allow
Principal:
AWS: !GetAtt DeploymentUser.Arn
Action: sts:AssumeRole
Tags:
-
Key: Application
Value: !Ref RootDomainName
ManagedPolicyArns:
- !Ref S3SiteDeployPolicy
- !Ref StackExportReaderPolicy
CFAppDeployRole: # We use shorter name ("CF") to allow longer stack names (stackname+rolename cannot reach 50 chars with managed names) & IAM rules work with stack prefix
Type: 'AWS::IAM::Role'
Properties:
Description: "Allows to informs to CloudFront to renew its cache from S3"
AssumeRolePolicyDocument:
Statement:
-
Effect: Allow
Principal:
AWS: !GetAtt DeploymentUser.Arn
Action: sts:AssumeRole
Tags:
-
Key: Application
Value: !Ref RootDomainName
ManagedPolicyArns:
- !Ref CloudFrontInvalidationPolicy
- !Ref StackExportReaderPolicy
# --------------------------------
# ----------- Policies -----------
# --------------------------------
AllowValidateTemplatePolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
Description: "No read & writes to resources, reveals just basic CloudFormation API to be used for validating templates"
# ManagedPolicyName: No hardcoded naming because of easier CloudFormation management
PolicyDocument:
Version: 2012-10-17
Statement:
-
Sid: AllowCloudFormationTemplateValidation
Effect: Allow
Action:
- cloudformation:ValidateTemplate
Resource: '*' # Cannot be specified
CloudFormationDeployPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
Description: "Allows deploying CloudFormation using CLI command 'aws cloudformation deploy' (with change sets)"
# ManagedPolicyName: No hardcoded naming because of easier CloudFormation management
PolicyDocument:
Version: 2012-10-17
Statement:
-
Sid: AllowCloudFormationStackOperations
Effect: Allow
Action:
- cloudformation:GetTemplateSummary
- cloudformation:DescribeStacks
- cloudformation:CreateChangeSet
- cloudformation:ExecuteChangeSet
- cloudformation:DescribeChangeSet
Resource:
- !Sub arn:aws:cloudformation:*:${AWS::AccountId}:stack/${WebStackName}/*
- !Sub arn:aws:cloudformation:*:${AWS::AccountId}:stack/${WebStackName}-extend/*
- !Sub arn:aws:cloudformation:*:${AWS::AccountId}:stack/${DnsStackName}/*
- !Sub arn:aws:cloudformation:*:${AWS::AccountId}:stack/${AWS::StackName}/*
- !Sub arn:aws:cloudformation:*:${AWS::AccountId}:stack/${CertificateStackName}/*
IamStackDeployPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
Description: !Sub Allows deploying ${AWS::StackName}
# ManagedPolicyName: No hardcoded naming because of easier CloudFormation management
PolicyDocument:
Version: 2012-10-17
Statement:
-
Sid: AllowUserArnExport
Effect: Allow
Action:
- iam:GetUser
Resource:
- !GetAtt DeploymentUser.Arn # arn:aws:iam::$account:user/$user-name
-
Sid: AllowTagging
Effect: Allow
Action:
- iam:TagResource
Resource:
- !Sub arn:aws:cloudformation::${AWS::AccountId}:stack/${AWS::StackName}/*
- !GetAtt DeploymentUser.Arn
-
Sid: AllowRoleDeployment
Effect: Allow
Action:
- iam:CreateRole
- iam:DeleteRole
Resource:
- !Sub arn:aws:iam::${AWS::AccountId}:role/${AWS::StackName}-* # arn:aws:iam::$account:role/$role-name
LambdaBackedCustomResourceDeployPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
Description: !Sub Allows deploying a lambda-backed custom resource in ${CertificateStackName}
# ManagedPolicyName: # ManagedPolicyName: No hardcoded naming because of easier CloudFormation management
PolicyDocument:
Version: 2012-10-17
Statement:
-
Sid: AllowLambdaDeployment
Effect: Allow
Action:
- lambda:GetFunction
- lambda:DeleteFunction
- lambda:CreateFunction
- lambda:GetFunctionConfiguration
- lambda:InvokeFunction
- lambda:ListTags
- lambda:TagResource
- lambda:UntagResource
Resource:
- !Sub arn:aws:lambda:*:${AWS::AccountId}:function:${CertificateStackName}-* # arn:aws:lambda:$region:$account:function:$function-name
-
Sid: AllowLambdaInvoke
Effect: Allow
Action:
- lambda:InvokeFunction
Resource:
- !Sub arn:aws:lambda:*:${AWS::AccountId}:function:${CertificateStackName}-* # arn:aws:lambda:$region:$account:function:$function-name
-
Sid: AllowLambdaRoleDeployment # So lambda execution role can be deployed & we can add policies on role
Effect: Allow
Action:
- iam:CreateRole
- iam:DeleteRole
- iam:PassRole
- iam:AttachRolePolicy
- iam:DetachRolePolicy
- iam:GetRole
Resource:
- !Sub arn:aws:iam::${AWS::AccountId}:role/${CertificateStackName}-* # arn:aws:iam::$account:role/$role-name
-
Sid: AllowPolicyUpdates
Effect: Allow
Action:
- iam:ListPolicyVersions
- iam:CreatePolicyVersion
- iam:DeletePolicyVersion
- iam:CreatePolicy
- iam:DeletePolicy
- iam:GetPolicy
Resource:
- !Sub arn:aws:iam::${AWS::AccountId}:policy/${CertificateStackName}-* # when ManagedPolicyName is not given policies get name like StackName-*
PolicyDeployPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
Description: !Sub Allows deployment of policies in ${AWS::StackName}
# ManagedPolicyName: Commented out because CloudFormation requires to rename when replacing custom-named resource
PolicyDocument:
Version: 2012-10-17
Statement:
-
Sid: AllowPolicyUpdates
Effect: Allow
Action:
- iam:ListPolicyVersions
- iam:CreatePolicyVersion
- iam:DeletePolicyVersion
- iam:CreatePolicy
- iam:DeletePolicy
- iam:GetPolicy
Resource:
- !Sub arn:aws:iam::${AWS::AccountId}:policy/${AWS::StackName}-* # when ManagedPolicyName is not given policies get name like StackName-*
-
Sid: AllowPoliciesOnRoles
Effect: Allow
Action:
- iam:AttachRolePolicy
- iam:DetachRolePolicy
- iam:GetRole
Resource:
- !Sub arn:aws:iam::${AWS::AccountId}:role/${AWS::StackName}-* # arn:aws:iam::$account:role/$role-name
-
Sid: AllowPolicyAssigmentToGroup
Effect: Allow
Action:
- iam:AttachGroupPolicy
- iam:DetachGroupPolicy
Resource:
- !GetAtt DeploymentGroup.Arn # arn:aws:iam::$account:group/$group-name
-
Sid: AllowGettingGroupInformation
Effect: Allow
Action:
- iam:GetGroup
Resource:
- !GetAtt DeploymentGroup.Arn # arn:aws:iam::$account:group/$group-name
DnsStackDeployPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
Description: !Sub Allows deployment of ${CertificateStackName}
PolicyDocument:
Version: 2012-10-17
Statement:
-
Sid: AllowHostedZoneDeployment
Effect: Allow
Action:
- route53:CreateHostedZone
- route53:ListQueryLoggingConfigs
- route53:DeleteHostedZone
- route53:GetChange
- route53:ChangeTagsForResource
- route53:GetHostedZone
- route53:ListTagsForResource
Resource: '*' # Does not support resource-level permissions https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/access-control-overview.html#access-control-manage-access-intro-resource-policies
WebStackDeployPolicy:
# We need a role to run s3:PutBucketPolicy, IAM users cannot run it. See https://stackoverflow.com/a/48551383
Type: AWS::IAM::ManagedPolicy
Properties:
Description: !Sub Allows deployment of resources in ${WebStackName}
PolicyDocument:
Version: 2012-10-17
Statement:
-
Sid: AllowCloudFrontOAIDeployment
Effect: Allow
Action:
- cloudfront:GetCloudFrontOriginAccessIdentity
- cloudfront:CreateCloudFrontOriginAccessIdentity
- cloudfront:GetCloudFrontOriginAccessIdentityConfig
- cloudfront:DeleteCloudFrontOriginAccessIdentity
Resource: '*' # Does not support resource-level permissions https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cf-api-permissions-ref.html
-
Sid: AllowCloudFrontDistributionDeployment
Effect: Allow
Action:
- cloudfront:CreateDistribution
- cloudfront:DeleteDistribution
- cloudfront:UpdateDistribution
- cloudfront:GetDistribution
- cloudfront:TagResource
- cloudfront:UpdateCloudFrontOriginAccessIdentity
Resource: !Sub arn:aws:cloudfront::${AWS::AccountId}:* # arn:aws:cloudfront::$account-id:*
-
Sid: AllowS3BucketAccess
Effect: Allow
Action:
- s3:CreateBucket
- s3:DeleteBucket
- s3:PutBucketWebsite
- s3:DeleteBucketPolicy
- s3:PutBucketPolicy
- s3:GetBucketPolicy
- s3:PutBucketCORS
- s3:DeleteBucketCORS
- s3:PutBucketTagging
Resource: !Sub arn:aws:s3:::${WebStackName}* # arn:aws:s3:::$bucket-name
WebStackLambdaEdgeDeployPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
Description: !Sub Allows deployment of lambda @Edge in ${WebStackName}
PolicyDocument:
Version: 2012-10-17
Statement:
-
Sid: AllowLambdaRoleDeployment # So lambda execution role can be deployed & we can add policies on role
Effect: Allow
Action:
- iam:CreateRole
- iam:DeleteRole
- iam:PassRole
- iam:AttachRolePolicy
- iam:DetachRolePolicy
- iam:GetRole
Resource:
- !Sub arn:aws:iam::${AWS::AccountId}:role/${WebStackName}-* # arn:aws:iam::$account:role/$role-name
-
Sid: AllowLambdaDeployment
Effect: Allow
Action:
- lambda:GetFunction
- lambda:DeleteFunction
- lambda:CreateFunction
- lambda:GetFunctionConfiguration
- lambda:ListTags
- lambda:TagResource
- lambda:UntagResource
Resource:
- !Sub arn:aws:lambda:*:${AWS::AccountId}:function:${WebStackName}-* # arn:aws:lambda:$region:$account:function:$function-name
-
Sid: AllowAssigningLambdaToCloudFront
Effect: Allow
Action:
- lambda:EnableReplication* # https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-edge-permissions.html#lambda-edge-permissions-required
- lambda:ListVersionsByFunction # we cannot assign lambdas, we must assign versions
- lambda:PublishVersion # we cannot assign lambdas, we must assign versions
Resource: !Sub arn:aws:lambda:*:${AWS::AccountId}:function:${WebStackName}-* # arn:aws:lambda:$region:$account:function:$function-name
-
Sid: AllowCreatingServiceLinkedRoles # https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-edge-permissions.html#lambda-edge-permissions-required
Effect: Allow
Action:
- iam:CreateServiceLinkedRole
- iam:DeleteServiceLinkedRole
Resource: !Sub arn:aws:iam::${AWS::AccountId}:role/aws-service-role/*
Condition:
StringLike:
iam:AWSServiceName:
- replicator.lambda.amazonaws.com
- logger.cloudfront.amazonaws.com
RecordSetUpdatePolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
Description: Allows you to update records on Route 53.
PolicyDocument:
Version: 2012-10-17
Statement:
-
Sid: AllowRecordDeploymentToRoute53
Effect: Allow
Action:
- route53:GetHostedZone
- route53:ChangeResourceRecordSets
- route53:GetChange
- route53:ListResourceRecordSets
Resource: '*' # Does not support resource-level permissions https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/access-control-overview.html#access-control-manage-access-intro-resource-policies
S3SiteDeployPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
Description: !Sub Allows for listing buckets in ${WebStackName} to be able to list objects in a bucket
# ManagedPolicyName: Commented out because CloudFormation requires to rename when replacing custom-named resources
PolicyDocument:
Version: 2012-10-17
Statement:
-
Sid: AllowListingObjects
Effect: Allow
Action:
- s3:ListBucket # To allow ListObjectsV2
Resource: !Sub arn:aws:s3:::${WebStackName}* # arn:aws:s3:::$bucket-name
-
Sid: AllowUpdatingObjects
Effect: Allow
Action:
- s3:PutObject
- s3:DeleteObject
Resource: !Sub arn:aws:s3:::${WebStackName}*/* # arn:aws:s3:::$bucket-name/$key-name
CloudFrontInvalidationPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
Description: Allows creating invalidations on CloudFront
# ManagedPolicyName: Commented out because CloudFormation requires to rename when replacing custom-named resource
PolicyDocument:
Version: 2012-10-17
Statement:
-
Sid: AllowCloudFrontInvalidations
Effect: Allow
Action:
- cloudfront:CreateInvalidation
Resource: "*" # Does not support resource-level permissions https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cf-api-permissions-ref.html
StackExportReaderPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
Description: !Sub allows creating invalidations on CloudFront in ${WebStackName}
# ManagedPolicyName: Commented out because CloudFormation requires to rename when replacing custom-named resource
PolicyDocument:
Version: 2012-10-17
Statement:
-
Sid: AllowGettingBucketName
Effect: Allow
Action:
- cloudformation:DescribeStacks
Resource: !Sub arn:aws:cloudformation:*:${AWS::AccountId}:stack/${WebStackName}/* # arn:aws:cloudformation:$region:$account:stack/$stack-name/*
Outputs:
CertStackDeployRoleArn: # To be used by the deploy tool
Description: "Secret name: AWS_CERTIFICATE_STACK_DEPLOYMENT_ROLE_ARN"
Value: !GetAtt CertStackDeployRole.Arn
DnsStackDeployRoleArn: # To be used by the deploy tool
Description: "Secret name: AWS_DNS_STACK_DEPLOYMENT_ROLE_ARN"
Value: !GetAtt DnsStackDeployRole.Arn
IamStackDeployRoleArn: # To be used by the deploy tool
Description: "Secret name: AWS_IAM_STACK_DEPLOYMENT_ROLE_ARN"
Value: !GetAtt IamStackDeployRole.Arn
WebStackDeployRoleArn: # To be used by the deploy tool
Description: "Secret name: AWS_WEB_STACK_DEPLOYMENT_ROLE_ARN"
Value: !GetAtt WebStackDeployRole.Arn
S3AppDeployRoleArn: # To be used by the deploy tool
Description: "Secret name: AWS_S3_SITE_DEPLOYMENT_ROLE_ARN"
Value: !GetAtt S3AppDeployRole.Arn
CFAppDeployRoleArn: # To be used by the deploy tool
Description: "Secret name: AWS_CLOUDFRONT_SITE_DEPLOYMENT_ROLE_ARN"
Value: !GetAtt CFAppDeployRole.Arn