-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(s3): export bucket websiteURL (#1521) #1522
Changes from 4 commits
497620d
f6a3bfa
c2aeebd
a36ac08
7bafbff
1724161
a4645f2
b22cf0c
19c9392
5096201
9bae09b
be19cc5
81a5a07
ed5a38b
ccd01e2
b1f5b2e
9cb842f
f393a26
6ad8c5e
0fb62c8
3961ad7
01d72cf
948b5df
4443d5c
582c8b1
c79d234
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
} | ||
|
||
/** | ||
|
@@ -570,6 +577,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; | ||
|
@@ -598,6 +606,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 | ||
|
@@ -620,6 +629,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() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens if bucketWebsiteUrl is undefined? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As in from a consumer's point of view? Currently it would just result in the property being I've had a go at creating separate test cases (for cases where a bucket does and doesn't have a website configuration) but I'm not 100% sure how to proceed. Looking at the other cases it seems the usual way of testing this stuff is to generate the CloudFormation and then assert against that. In this case, however, the value is just an 'exports the WebsiteURL is website configuration is enabled'(test: Test) {
const stack = new cdk.Stack();
const bucket = new s3.Bucket(stack, 'Website', {
bucketName: 'my-bucket',
websiteIndexDocument: 'index.html'
});
test.deepEqual(cdk.resolve(bucket.bucketWebsiteUrl), 'my-bucket-<REGION>.s3-website.amazonaws.com');
test.done();
} The are two problems I've ran into when attempting to create test cases like the above:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
why? if the user sets up website hosting for the bucket, I'd expect this to return the URL, no?
You can't. The "end result" of a CDK synth is a CloudFormation template. I'd expect the test to assert that the resulting template (or template part) is the right one (i.e. includes the GetAtt).
What I usually do is print out the output of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Ah, I thought you were asking what would happen if the user hadn't set up website hosting for the bucket. In the case where they have set up website hosting for the bucket,
Gotcha, I'll give this a go. Thanks! |
||
}; | ||
} | ||
|
||
|
@@ -955,6 +965,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; | ||
|
@@ -971,6 +982,7 @@ class ImportedBucket extends BucketBase { | |
this.bucketArn = parseBucketArn(props); | ||
this.bucketName = bucketName; | ||
this.domainName = props.bucketDomainName || this.generateDomainName(); | ||
this.bucketWebsiteUrl = props.bucketWebsiteUrl || this.generateBucketWebsiteUrl(); | ||
this.autoCreatePolicy = false; | ||
this.policy = undefined; | ||
} | ||
|
@@ -985,4 +997,8 @@ class ImportedBucket extends BucketBase { | |
private generateDomainName() { | ||
return `${this.bucketName}.s3.amazonaws.com`; | ||
} | ||
|
||
private generateBucketWebsiteUrl() { | ||
return `${this.bucketName}.s3-website-${new cdk.AwsRegion()}.amazonaws.com`; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how does this look in a different partition? (i.e. china) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's a.. good question. I wasn't aware (until I found these docs) that the domain name was different in regions such as China. Happy to take a look at making sure this works in regions such as China, would you want me to take a look at doing the same for the |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -334,7 +334,8 @@ export = { | |
test.deepEqual(cdk.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(cdk.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": { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I found the logical ID here (i.e. I'm not sure if I was meant to have determined the output from somewhere else? |
||
"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" | ||
} | ||
} | ||
} | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how useful this description is, I tried a couple of different variations but couldn't come up with anything better than this.
Suggestions welcome!