Skip to content

Commit 2d3661c

Browse files
Elad Ben-IsraelRomainMuller
Elad Ben-Israel
authored andcommittedOct 17, 2018
feat(aws-s3): initial support for website hosting (#946)
Adds basic support for website hosting for S3 buckets. Users can specify `websiteIndexDocument` and optionally `websiteErrorDocument` to enable website hosting. The property `publicReadAccess` can be used to grant public read access to the bucket (similar to calling `grantPublicAccess`). No support for redirects yet.
1 parent 65190f9 commit 2d3661c

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed
 

‎packages/@aws-cdk/aws-s3/lib/bucket.ts

+38
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,24 @@ export interface BucketProps {
384384
* @default No lifecycle rules
385385
*/
386386
lifecycleRules?: LifecycleRule[];
387+
388+
/**
389+
* The name of the index document (e.g. "index.html") for the website. Enables static website
390+
* hosting for this bucket.
391+
*/
392+
websiteIndexDocument?: string;
393+
394+
/**
395+
* The name of the error document (e.g. "404.html") for the website.
396+
* `websiteIndexDocument` must also be set if this is set.
397+
*/
398+
websiteErrorDocument?: string;
399+
400+
/**
401+
* Grants public read access to all objects in the bucket.
402+
* Similar to calling `bucket.grantPublicAccess()`
403+
*/
404+
publicReadAccess?: boolean;
387405
}
388406

389407
/**
@@ -414,6 +432,7 @@ export class Bucket extends BucketRef {
414432
bucketEncryption,
415433
versioningConfiguration: props.versioned ? { status: 'Enabled' } : undefined,
416434
lifecycleConfiguration: new cdk.Token(() => this.parseLifecycleConfiguration()),
435+
websiteConfiguration: this.renderWebsiteConfiguration(props)
417436
});
418437

419438
cdk.applyRemovalPolicy(resource, props.removalPolicy);
@@ -431,6 +450,10 @@ export class Bucket extends BucketRef {
431450
// defines a BucketNotifications construct. Notice that an actual resource will only
432451
// be added if there are notifications added, so we don't need to condition this.
433452
this.notifications = new BucketNotifications(this, 'Notifications', { bucket: this });
453+
454+
if (props.publicReadAccess) {
455+
this.grantPublicAccess();
456+
}
434457
}
435458

436459
/**
@@ -598,6 +621,21 @@ export class Bucket extends BucketRef {
598621
}));
599622
}
600623
}
624+
625+
private renderWebsiteConfiguration(props: BucketProps): cloudformation.BucketResource.WebsiteConfigurationProperty | undefined {
626+
if (!props.websiteErrorDocument && !props.websiteIndexDocument) {
627+
return undefined;
628+
}
629+
630+
if (props.websiteErrorDocument && !props.websiteIndexDocument) {
631+
throw new Error(`"websiteIndexDocument" is required if "websiteErrorDocument" is set`);
632+
}
633+
634+
return {
635+
indexDocument: props.websiteIndexDocument,
636+
errorDocument: props.websiteErrorDocument
637+
};
638+
}
601639
}
602640

603641
/**

‎packages/@aws-cdk/aws-s3/test/test.bucket.ts

+38
Original file line numberDiff line numberDiff line change
@@ -1143,5 +1143,43 @@ export = {
11431143
}));
11441144
test.done();
11451145
}
1146+
},
1147+
1148+
'website configuration': {
1149+
'only index doc'(test: Test) {
1150+
const stack = new cdk.Stack();
1151+
new s3.Bucket(stack, 'Website', {
1152+
websiteIndexDocument: 'index2.html'
1153+
});
1154+
expect(stack).to(haveResource('AWS::S3::Bucket', {
1155+
WebsiteConfiguration: {
1156+
IndexDocument: "index2.html"
1157+
}
1158+
}));
1159+
test.done();
1160+
},
1161+
'fails if only error doc is specified'(test: Test) {
1162+
const stack = new cdk.Stack();
1163+
test.throws(() => {
1164+
new s3.Bucket(stack, 'Website', {
1165+
websiteErrorDocument: 'error.html'
1166+
});
1167+
}, /"websiteIndexDocument" is required if "websiteErrorDocument" is set/);
1168+
test.done();
1169+
},
1170+
'error and index docs'(test: Test) {
1171+
const stack = new cdk.Stack();
1172+
new s3.Bucket(stack, 'Website', {
1173+
websiteIndexDocument: 'index2.html',
1174+
websiteErrorDocument: 'error.html',
1175+
});
1176+
expect(stack).to(haveResource('AWS::S3::Bucket', {
1177+
WebsiteConfiguration: {
1178+
IndexDocument: "index2.html",
1179+
ErrorDocument: "error.html"
1180+
}
1181+
}));
1182+
test.done();
1183+
}
11461184
}
11471185
};

0 commit comments

Comments
 (0)