1
1
# Amazon S3 Construct Library
2
+
2
3
<!-- BEGIN STABILITY BANNER-->
3
4
4
5
---
@@ -19,24 +20,24 @@ const bucket = new s3.Bucket(this, 'MyFirstBucket');
19
20
20
21
` Bucket ` constructs expose the following deploy-time attributes:
21
22
22
- * ` bucketArn ` - the ARN of the bucket (i.e. ` arn:aws:s3:::bucket_name ` )
23
- * ` bucketName ` - the name of the bucket (i.e. ` bucket_name ` )
24
- * ` bucketWebsiteUrl ` - the Website URL of the bucket (i.e.
25
- ` http://bucket_name.s3-website-us-west-1.amazonaws.com ` )
26
- * ` bucketDomainName ` - the URL of the bucket (i.e. ` bucket_name.s3.amazonaws.com ` )
27
- * ` bucketDualStackDomainName ` - the dual-stack URL of the bucket (i.e.
28
- ` bucket_name.s3.dualstack.eu-west-1.amazonaws.com ` )
29
- * ` bucketRegionalDomainName ` - the regional URL of the bucket (i.e.
30
- ` bucket_name.s3.eu-west-1.amazonaws.com ` )
31
- * ` arnForObjects(pattern) ` - the ARN of an object or objects within the bucket (i.e.
32
- ` arn:aws:s3:::bucket_name/exampleobject.png ` or
33
- ` arn:aws:s3:::bucket_name/Development/* ` )
34
- * ` urlForObject(key) ` - the HTTP URL of an object within the bucket (i.e.
35
- ` https://s3.cn-north-1.amazonaws.com.cn/china-bucket/mykey ` )
36
- * ` virtualHostedUrlForObject(key) ` - the virtual-hosted style HTTP URL of an object
37
- within the bucket (i.e. ` https://china-bucket-s3.cn-north-1.amazonaws.com.cn/mykey ` )
38
- * ` s3UrlForObject(key) ` - the S3 URL of an object within the bucket (i.e.
39
- ` s3://bucket/mykey ` )
23
+ - ` bucketArn ` - the ARN of the bucket (i.e. ` arn:aws:s3:::bucket_name ` )
24
+ - ` bucketName ` - the name of the bucket (i.e. ` bucket_name ` )
25
+ - ` bucketWebsiteUrl ` - the Website URL of the bucket (i.e.
26
+ ` http://bucket_name.s3-website-us-west-1.amazonaws.com ` )
27
+ - ` bucketDomainName ` - the URL of the bucket (i.e. ` bucket_name.s3.amazonaws.com ` )
28
+ - ` bucketDualStackDomainName ` - the dual-stack URL of the bucket (i.e.
29
+ ` bucket_name.s3.dualstack.eu-west-1.amazonaws.com ` )
30
+ - ` bucketRegionalDomainName ` - the regional URL of the bucket (i.e.
31
+ ` bucket_name.s3.eu-west-1.amazonaws.com ` )
32
+ - ` arnForObjects(pattern) ` - the ARN of an object or objects within the bucket (i.e.
33
+ ` arn:aws:s3:::bucket_name/exampleobject.png ` or
34
+ ` arn:aws:s3:::bucket_name/Development/* ` )
35
+ - ` urlForObject(key) ` - the HTTP URL of an object within the bucket (i.e.
36
+ ` https://s3.cn-north-1.amazonaws.com.cn/china-bucket/mykey ` )
37
+ - ` virtualHostedUrlForObject(key) ` - the virtual-hosted style HTTP URL of an object
38
+ within the bucket (i.e. ` https://china-bucket-s3.cn-north-1.amazonaws.com.cn/mykey ` )
39
+ - ` s3UrlForObject(key) ` - the S3 URL of an object within the bucket (i.e.
40
+ ` s3://bucket/mykey ` )
40
41
41
42
## Encryption
42
43
@@ -90,11 +91,13 @@ A bucket policy will be automatically created for the bucket upon the first call
90
91
91
92
``` ts
92
93
const bucket = new s3 .Bucket (this , ' MyBucket' );
93
- const result = bucket .addToResourcePolicy (new iam .PolicyStatement ({
94
- actions: [' s3:GetObject' ],
95
- resources: [bucket .arnForObjects (' file.txt' )],
96
- principals: [new iam .AccountRootPrincipal ()],
97
- }));
94
+ const result = bucket .addToResourcePolicy (
95
+ new iam .PolicyStatement ({
96
+ actions: [' s3:GetObject' ],
97
+ resources: [bucket .arnForObjects (' file.txt' )],
98
+ principals: [new iam .AccountRootPrincipal ()],
99
+ })
100
+ );
98
101
```
99
102
100
103
If you try to add a policy statement to an existing bucket, this method will
@@ -104,11 +107,13 @@ not do anything:
104
107
const bucket = s3 .Bucket .fromBucketName (this , ' existingBucket' , ' bucket-name' );
105
108
106
109
// No policy statement will be added to the resource
107
- const result = bucket .addToResourcePolicy (new iam .PolicyStatement ({
108
- actions: [' s3:GetObject' ],
109
- resources: [bucket .arnForObjects (' file.txt' )],
110
- principals: [new iam .AccountRootPrincipal ()],
111
- }));
110
+ const result = bucket .addToResourcePolicy (
111
+ new iam .PolicyStatement ({
112
+ actions: [' s3:GetObject' ],
113
+ resources: [bucket .arnForObjects (' file.txt' )],
114
+ principals: [new iam .AccountRootPrincipal ()],
115
+ })
116
+ );
112
117
```
113
118
114
119
That's because it's not possible to tell whether the bucket
@@ -117,11 +122,13 @@ statements to it. We recommend that you always check the result of the call:
117
122
118
123
``` ts
119
124
const bucket = new s3 .Bucket (this , ' MyBucket' );
120
- const result = bucket .addToResourcePolicy (new iam .PolicyStatement ({
121
- actions: [' s3:GetObject' ],
122
- resources: [bucket .arnForObjects (' file.txt' )],
123
- principals: [new iam .AccountRootPrincipal ()],
124
- }));
125
+ const result = bucket .addToResourcePolicy (
126
+ new iam .PolicyStatement ({
127
+ actions: [' s3:GetObject' ],
128
+ resources: [bucket .arnForObjects (' file.txt' )],
129
+ principals: [new iam .AccountRootPrincipal ()],
130
+ })
131
+ );
125
132
126
133
if (! result .statementAdded ) {
127
134
// Uh-oh! Someone probably made a mistake here.
@@ -166,7 +173,42 @@ const bucket = new s3.Bucket(this, 'Bucket', {
166
173
167
174
To use a bucket in a different stack in the same CDK application, pass the object to the other stack:
168
175
169
- [ sharing bucket between stacks] ( test/integ.bucket-sharing.lit.ts )
176
+ ``` ts
177
+ /**
178
+ * Stack that defines the bucket
179
+ */
180
+ class Producer extends cdk .Stack {
181
+ public readonly myBucket: s3 .Bucket ;
182
+
183
+ constructor (scope : cdk .App , id : string , props ? : cdk .StackProps ) {
184
+ super (scope , id , props );
185
+
186
+ const bucket = new s3 .Bucket (this , ' MyBucket' , {
187
+ removalPolicy: cdk .RemovalPolicy .DESTROY ,
188
+ });
189
+ this .myBucket = bucket ;
190
+ }
191
+ }
192
+
193
+ interface ConsumerProps extends cdk .StackProps {
194
+ userBucket: s3 .IBucket ;
195
+ }
196
+
197
+ /**
198
+ * Stack that consumes the bucket
199
+ */
200
+ class Consumer extends cdk .Stack {
201
+ constructor (scope : cdk .App , id : string , props : ConsumerProps ) {
202
+ super (scope , id , props );
203
+
204
+ const user = new iam .User (this , ' MyUser' );
205
+ props .userBucket .grantReadWrite (user );
206
+ }
207
+ }
208
+
209
+ const producer = new Producer (app , ' ProducerStack' );
210
+ new Consumer (app , ' ConsumerStack' , { userBucket: producer .myBucket });
211
+ ```
170
212
171
213
## Importing existing buckets
172
214
@@ -181,7 +223,9 @@ const bucket = s3.Bucket.fromBucketAttributes(this, 'ImportedBucket', {
181
223
});
182
224
183
225
// now you can just call methods on the bucket
184
- bucket .addEventNotification (s3 .EventType .OBJECT_CREATED , new s3n .LambdaDestination (myLambda ), {prefix: ' home/myusername/*' });
226
+ bucket .addEventNotification (s3 .EventType .OBJECT_CREATED , new s3n .LambdaDestination (myLambda ), {
227
+ prefix: ' home/myusername/*' ,
228
+ });
185
229
```
186
230
187
231
Alternatively, short-hand factories are available as ` Bucket.fromBucketName ` and
@@ -190,7 +234,7 @@ name or ARN respectively:
190
234
191
235
``` ts
192
236
const byName = s3 .Bucket .fromBucketName (this , ' BucketByName' , ' my-bucket' );
193
- const byArn = s3 .Bucket .fromBucketArn (this , ' BucketByArn' , ' arn:aws:s3:::my-bucket' );
237
+ const byArn = s3 .Bucket .fromBucketArn (this , ' BucketByArn' , ' arn:aws:s3:::my-bucket' );
194
238
```
195
239
196
240
The bucket's region defaults to the current stack's region, but can also be explicitly set in cases where one of the bucket's
@@ -234,9 +278,10 @@ have the `.jpg` suffix are removed from the bucket.
234
278
``` ts
235
279
declare const myQueue: sqs .Queue ;
236
280
const bucket = new s3 .Bucket (this , ' MyBucket' );
237
- bucket .addEventNotification (s3 .EventType .OBJECT_REMOVED ,
238
- new s3n .SqsDestination (myQueue ),
239
- { prefix: ' foo/' , suffix: ' .jpg' });
281
+ bucket .addEventNotification (s3 .EventType .OBJECT_REMOVED , new s3n .SqsDestination (myQueue ), {
282
+ prefix: ' foo/' ,
283
+ suffix: ' .jpg' ,
284
+ });
240
285
```
241
286
242
287
Adding notifications on existing buckets:
@@ -249,7 +294,7 @@ const bucket = s3.Bucket.fromBucketAttributes(this, 'ImportedBucket', {
249
294
bucket .addEventNotification (s3 .EventType .OBJECT_CREATED , new s3n .SnsDestination (topic ));
250
295
```
251
296
252
- When you add an event notification to a bucket, a custom resource is created to
297
+ When you add an event notification to a bucket, a custom resource is created to
253
298
manage the notifications. By default, a new role is created for the Lambda
254
299
function that implements this feature. If you want to use your own role instead,
255
300
you should provide it in the ` Bucket ` constructor:
@@ -261,10 +306,10 @@ const bucket = new s3.Bucket(this, 'MyBucket', {
261
306
});
262
307
```
263
308
264
- Whatever role you provide, the CDK will try to modify it by adding the
265
- permissions from ` AWSLambdaBasicExecutionRole ` (an AWS managed policy) as well
266
- as the permissions ` s3:PutBucketNotification ` and ` s3:GetBucketNotification ` .
267
- If you’re passing an imported role, and you don’t want this to happen, configure
309
+ Whatever role you provide, the CDK will try to modify it by adding the
310
+ permissions from ` AWSLambdaBasicExecutionRole ` (an AWS managed policy) as well
311
+ as the permissions ` s3:PutBucketNotification ` and ` s3:GetBucketNotification ` .
312
+ If you’re passing an imported role, and you don’t want this to happen, configure
268
313
it to be immutable:
269
314
270
315
``` ts
@@ -273,11 +318,10 @@ const importedRole = iam.Role.fromRoleArn(this, 'role', 'arn:aws:iam::1234567890
273
318
});
274
319
```
275
320
276
- > If you provide an imported immutable role, make sure that it has at least all
321
+ > If you provide an imported immutable role, make sure that it has at least all
277
322
> the permissions mentioned above. Otherwise, the deployment will fail!
278
323
279
- [ S3 Bucket Notifications ] : https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html
280
-
324
+ [ s3 bucket notifications ] : https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html
281
325
282
326
### EventBridge notifications
283
327
@@ -292,7 +336,7 @@ const bucket = new s3.Bucket(this, 'MyEventBridgeBucket', {
292
336
});
293
337
```
294
338
295
- [ S3 EventBridge notifications] : https://docs.aws.amazon.com/AmazonS3/latest/userguide/EventBridge.html
339
+ [ s3 eventbridge notifications] : https://docs.aws.amazon.com/AmazonS3/latest/userguide/EventBridge.html
296
340
297
341
## Block Public Access
298
342
@@ -439,16 +483,18 @@ Alternatively, you can also define multiple `websiteRoutingRules`, to define com
439
483
440
484
``` ts
441
485
const bucket = new s3 .Bucket (this , ' MyRedirectedBucket' , {
442
- websiteRoutingRules: [{
443
- hostName: ' www.example.com' ,
444
- httpRedirectCode: ' 302' ,
445
- protocol: s3 .RedirectProtocol .HTTPS ,
446
- replaceKey: s3 .ReplaceKey .prefixWith (' test/' ),
447
- condition: {
448
- httpErrorCodeReturnedEquals: ' 200' ,
449
- keyPrefixEquals: ' prefix' ,
486
+ websiteRoutingRules: [
487
+ {
488
+ hostName: ' www.example.com' ,
489
+ httpRedirectCode: ' 302' ,
490
+ protocol: s3 .RedirectProtocol .HTTPS ,
491
+ replaceKey: s3 .ReplaceKey .prefixWith (' test/' ),
492
+ condition: {
493
+ httpErrorCodeReturnedEquals: ' 200' ,
494
+ keyPrefixEquals: ' prefix' ,
495
+ },
450
496
},
451
- } ],
497
+ ],
452
498
});
453
499
```
454
500
@@ -479,7 +525,7 @@ bucket.virtualHostedUrlForObject('objectname', { regional: false }); // Virtual
479
525
480
526
You can use one of following properties to specify the bucket [ object Ownership] .
481
527
482
- [ object Ownership ] : https://docs.aws.amazon.com/AmazonS3/latest/dev/about-object-ownership.html
528
+ [ object ownership ] : https://docs.aws.amazon.com/AmazonS3/latest/dev/about-object-ownership.html
483
529
484
530
### Object writer
485
531
@@ -516,9 +562,9 @@ new s3.Bucket(this, 'MyBucket', {
516
562
Some services may not not support log delivery to buckets that have object ownership
517
563
set to bucket owner enforced, such as
518
564
[ S3 buckets using ACLs] ( #allowing-access-log-delivery-using-a-bucket-policy-recommended )
519
- or [ CloudFront Distributions] [ CloudFront S3 Bucket ] .
565
+ or [ CloudFront Distributions] [ cloudfront s3 bucket ] .
520
566
521
- [ CloudFront S3 Bucket ] : https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html#AccessLogsBucketAndFileOwnership
567
+ [ cloudfront s3 bucket ] : https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html#AccessLogsBucketAndFileOwnership
522
568
523
569
## Bucket deletion
524
570
@@ -539,7 +585,7 @@ const bucket = new s3.Bucket(this, 'MyTempFileBucket', {
539
585
```
540
586
541
587
** Warning** if you have deployed a bucket with ` autoDeleteObjects: true ` ,
542
- switching this to ` false ` in a CDK version * before * ` 1.126.0 ` will lead to
588
+ switching this to ` false ` in a CDK version _ before _ ` 1.126.0 ` will lead to
543
589
all objects in the bucket being deleted. Be sure to update your bucket resources
544
590
by deploying with CDK version ` 1.126.0 ` or later ** before** switching this value to ` false ` .
545
591
@@ -568,15 +614,16 @@ bucket.transferAccelerationUrlForObject('objectname');
568
614
569
615
``` ts
570
616
new s3 .Bucket (this , ' MyBucket' , {
571
- intelligentTieringConfigurations: [{
572
- name: ' foo' ,
573
- prefix: ' folder/name' ,
574
- archiveAccessTierTime: cdk .Duration .days (90 ),
575
- deepArchiveAccessTierTime: cdk .Duration .days (180 ),
576
- tags: [{key: ' tagname' , value: ' tagvalue' }]
577
- }],
617
+ intelligentTieringConfigurations: [
618
+ {
619
+ name: ' foo' ,
620
+ prefix: ' folder/name' ,
621
+ archiveAccessTierTime: cdk .Duration .days (90 ),
622
+ deepArchiveAccessTierTime: cdk .Duration .days (180 ),
623
+ tags: [{ key: ' tagname' , value: ' tagvalue' }],
624
+ },
625
+ ],
578
626
});
579
-
580
627
```
581
628
582
629
## Lifecycle Rule
@@ -585,35 +632,41 @@ new s3.Bucket(this, 'MyBucket', {
585
632
586
633
``` ts
587
634
const bucket = new s3 .Bucket (this , ' MyBucket' , {
588
- lifecycleRules: [{
589
- abortIncompleteMultipartUploadAfter: cdk .Duration .minutes (30 ),
590
- enabled: false ,
591
- expiration: cdk .Duration .days (30 ),
592
- expirationDate: new Date (),
593
- expiredObjectDeleteMarker: false ,
594
- id: ' id' ,
595
- noncurrentVersionExpiration: cdk .Duration .days (30 ),
596
-
597
- // the properties below are optional
598
- noncurrentVersionsToRetain: 123 ,
599
- noncurrentVersionTransitions: [{
600
- storageClass: s3 .StorageClass .GLACIER ,
601
- transitionAfter: cdk .Duration .days (30 ),
635
+ lifecycleRules: [
636
+ {
637
+ abortIncompleteMultipartUploadAfter: cdk .Duration .minutes (30 ),
638
+ enabled: false ,
639
+ expiration: cdk .Duration .days (30 ),
640
+ expirationDate: new Date (),
641
+ expiredObjectDeleteMarker: false ,
642
+ id: ' id' ,
643
+ noncurrentVersionExpiration: cdk .Duration .days (30 ),
602
644
603
645
// the properties below are optional
604
646
noncurrentVersionsToRetain: 123 ,
605
- }],
606
- objectSizeGreaterThan: 500 ,
607
- prefix: ' prefix' ,
608
- objectSizeLessThan: 10000 ,
609
- transitions: [{
610
- storageClass: s3 .StorageClass .GLACIER ,
611
-
612
- // the properties below are optional
613
- transitionAfter: cdk .Duration .days (30 ),
614
- transitionDate: new Date (),
615
- }],
616
- }]
647
+ noncurrentVersionTransitions: [
648
+ {
649
+ storageClass: s3 .StorageClass .GLACIER ,
650
+ transitionAfter: cdk .Duration .days (30 ),
651
+
652
+ // the properties below are optional
653
+ noncurrentVersionsToRetain: 123 ,
654
+ },
655
+ ],
656
+ objectSizeGreaterThan: 500 ,
657
+ prefix: ' prefix' ,
658
+ objectSizeLessThan: 10000 ,
659
+ transitions: [
660
+ {
661
+ storageClass: s3 .StorageClass .GLACIER ,
662
+
663
+ // the properties below are optional
664
+ transitionAfter: cdk .Duration .days (30 ),
665
+ transitionDate: new Date (),
666
+ },
667
+ ],
668
+ },
669
+ ],
617
670
});
618
671
```
619
672
@@ -628,7 +681,7 @@ Object Lock can be enabled on an S3 bucket by specifying:
628
681
629
682
``` ts
630
683
const bucket = new s3 .Bucket (this , ' MyBucket' , {
631
- objectLockEnabled: true
684
+ objectLockEnabled: true ,
632
685
});
633
686
```
634
687
@@ -647,5 +700,4 @@ new s3.Bucket(this, 'Bucket1', {
647
700
new s3 .Bucket (this , ' Bucket2' , {
648
701
objectLockDefaultRetention: s3 .ObjectLockRetention .compliance (cdk .Duration .days (365 )),
649
702
});
650
-
651
703
```
0 commit comments