diff --git a/packages/@aws-cdk/aws-s3/lib/bucket.ts b/packages/@aws-cdk/aws-s3/lib/bucket.ts index f8f4f2cf1952d..6fdcfc1d25294 100644 --- a/packages/@aws-cdk/aws-s3/lib/bucket.ts +++ b/packages/@aws-cdk/aws-s3/lib/bucket.ts @@ -180,7 +180,7 @@ export interface IBucket extends cdk.IConstruct { */ export interface BucketImportProps { /** - * The ARN fo the bucket. At least one of bucketArn or bucketName must be + * The ARN of the bucket. At least one of bucketArn or bucketName must be * defined in order to initialize a bucket ref. */ bucketArn?: string; @@ -199,6 +199,13 @@ export interface BucketImportProps { * @default Inferred from bucket name */ bucketDomainName?: string; + + /** + * The website URL of the bucket (if static web hosting is enabled). + * + * @default Inferred from bucket name + */ + bucketWebsiteUrl?: string; } /** @@ -571,6 +578,7 @@ export class Bucket extends BucketBase { public readonly bucketArn: string; public readonly bucketName: string; public readonly domainName: string; + public readonly bucketWebsiteUrl: string; public readonly dualstackDomainName: string; public readonly encryptionKey?: kms.IEncryptionKey; public policy?: BucketPolicy; @@ -599,6 +607,7 @@ export class Bucket extends BucketBase { this.bucketArn = resource.bucketArn; this.bucketName = resource.bucketName; this.domainName = resource.bucketDomainName; + this.bucketWebsiteUrl = resource.bucketWebsiteUrl; this.dualstackDomainName = resource.bucketDualStackDomainName; // Add all lifecycle rules @@ -621,6 +630,7 @@ export class Bucket extends BucketBase { bucketArn: new cdk.Output(this, 'BucketArn', { value: this.bucketArn }).makeImportValue().toString(), bucketName: new cdk.Output(this, 'BucketName', { value: this.bucketName }).makeImportValue().toString(), bucketDomainName: new cdk.Output(this, 'DomainName', { value: this.domainName }).makeImportValue().toString(), + bucketWebsiteUrl: new cdk.Output(this, 'WebsiteURL', { value: this.bucketWebsiteUrl }).makeImportValue().toString() }; } @@ -956,6 +966,7 @@ class ImportedBucket extends BucketBase { public readonly bucketArn: string; public readonly bucketName: string; public readonly domainName: string; + public readonly bucketWebsiteUrl: string; public readonly encryptionKey?: kms.EncryptionKey; public policy?: BucketPolicy; @@ -972,6 +983,7 @@ class ImportedBucket extends BucketBase { this.bucketArn = parseBucketArn(this, props); this.bucketName = bucketName; this.domainName = props.bucketDomainName || this.generateDomainName(); + this.bucketWebsiteUrl = props.bucketWebsiteUrl || this.generateBucketWebsiteUrl(); this.autoCreatePolicy = false; this.policy = undefined; } @@ -986,4 +998,8 @@ class ImportedBucket extends BucketBase { private generateDomainName() { return `${this.bucketName}.s3.amazonaws.com`; } + + private generateBucketWebsiteUrl() { + return `${this.bucketName}.s3-website-${new cdk.Aws().region}.amazonaws.com`; + } } diff --git a/packages/@aws-cdk/aws-s3/test/test.bucket.ts b/packages/@aws-cdk/aws-s3/test/test.bucket.ts index cd368c0232005..19c10b0840951 100644 --- a/packages/@aws-cdk/aws-s3/test/test.bucket.ts +++ b/packages/@aws-cdk/aws-s3/test/test.bucket.ts @@ -334,7 +334,8 @@ export = { test.deepEqual(bucket.node.resolve(bucketRef), { bucketArn: { 'Fn::ImportValue': 'MyStack:MyBucketBucketArnE260558C' }, bucketName: { 'Fn::ImportValue': 'MyStack:MyBucketBucketName8A027014' }, - bucketDomainName: { 'Fn::ImportValue': 'MyStack:MyBucketDomainNameF76B9A7A' } + bucketDomainName: { 'Fn::ImportValue': 'MyStack:MyBucketDomainNameF76B9A7A' }, + bucketWebsiteUrl: { 'Fn::ImportValue': 'MyStack:MyBucketWebsiteURL9C222788' } }); test.done(); }, @@ -346,7 +347,8 @@ export = { test.deepEqual(bucket.node.resolve(bucketRef), { bucketArn: { 'Fn::ImportValue': 'MyStack:MyBucketBucketArnE260558C' }, bucketName: { 'Fn::ImportValue': 'MyStack:MyBucketBucketName8A027014' }, - bucketDomainName: { 'Fn::ImportValue': 'MyStack:MyBucketDomainNameF76B9A7A' } + bucketDomainName: { 'Fn::ImportValue': 'MyStack:MyBucketDomainNameF76B9A7A' }, + bucketWebsiteUrl: { 'Fn::ImportValue': 'MyStack:MyBucketWebsiteURL9C222788' } }); test.done(); }, @@ -465,6 +467,17 @@ export = { "Export": { "Name": "S1:MyBucketDomainNameF76B9A7A" } + }, + "MyBucketWebsiteURL9C222788": { + "Value": { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "WebsiteURL" + ] + }, + "Export": { + "Name": "S1:MyBucketWebsiteURL9C222788" + } } } }); @@ -898,6 +911,17 @@ export = { "Export": { "Name": "MyBucketDomainNameF76B9A7A" } + }, + "MyBucketWebsiteURL9C222788": { + "Value": { + "Fn::GetAtt": [ + "MyBucketF68F3FF0", + "WebsiteURL" + ] + }, + "Export": { + "Name": "MyBucketWebsiteURL9C222788" + } } } }); @@ -1190,6 +1214,14 @@ export = { } })); test.done(); + }, + 'exports the WebsiteURL'(test: Test) { + const stack = new cdk.Stack(); + const bucket = new s3.Bucket(stack, 'Website', { + websiteIndexDocument: 'index.html' + }); + test.deepEqual(bucket.node.resolve(bucket.bucketWebsiteUrl), { 'Fn::GetAtt': [ 'Website32962D0B', 'WebsiteURL' ] }); + test.done(); } } };