Skip to content

Commit 72d1c1c

Browse files
authored
Merge pull request #33 from awslabs/feature/expose-cloudfront-distribution
Feature/expose cloudfront distribution
2 parents 60a4b49 + a828dd6 commit 72d1c1c

File tree

2 files changed

+93
-51
lines changed

2 files changed

+93
-51
lines changed

lib/hosting.ts

Lines changed: 81 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,33 @@
11
/*
2-
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3-
4-
Licensed under the Apache License, Version 2.0 (the "License").
5-
You may not use this file except in compliance with the License.
6-
You may obtain a copy of the License at
7-
8-
http://www.apache.org/licenses/LICENSE-2.0
9-
10-
Unless required by applicable law or agreed to in writing, software
11-
distributed under the License is distributed on an "AS IS" BASIS,
12-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
See the License for the specific language governing permissions and
14-
limitations under the License.
2+
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
Licensed under the Apache License, Version 2.0 (the "License").
4+
You may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
1512
*/
16-
17-
import {
13+
import {
1814
Aws,
1915
aws_cloudfront as cloudfront,
16+
aws_s3 as s3
2017
} from "aws-cdk-lib";
2118
import * as path from "path";
2219
import * as fs from "fs";
23-
2420
import { Construct } from "constructs";
2521
import { HostingInfrastructure } from "./hosting_infrastructure";
2622
import { PipelineInfrastructure } from "./pipeline_infrastructure";
2723
import { HostingConfiguration } from "../bin/cli/shared/types";
2824
import { truncateString } from "./utility";
25+
2926
interface IParamProps {
3027
hostingConfiguration: HostingConfiguration;
3128
buildFilePath: string;
3229
cffSourceFilePath: string;
33-
connectionArn?: string ;
30+
connectionArn?: string;
3431
certificateArn?: string;
3532
}
3633

@@ -43,50 +40,94 @@ interface IParamProps {
4340
* @param scope - The Construct scope in which this construct is defined.
4441
* @param id - The identifier for this construct within the scope.
4542
* @param params - Parameters for configuring hosting resources.
46-
* - `configuration` (required): The IConfiguration object representing the hosting configuration.
47-
* - `buildFilePath` (required): The path to the build file for the hosting resources.
48-
* - `connectionArn` (optional): The ARN of the connection resource (if applicable).
49-
* - `certificateArn` (optional): The ARN of the certificate resource (if applicable).
5043
*/
5144
export class Hosting extends Construct {
45+
/**
46+
* The CloudFront Distribution created by this construct.
47+
*/
48+
public readonly distribution: cloudfront.Distribution;
49+
50+
/**
51+
* The S3 Bucket used for hosting the content.
52+
*/
53+
public readonly hostingBucket: s3.IBucket;
54+
55+
/**
56+
* The CloudFront Function used for URI manipulation.
57+
*/
58+
public readonly changeUriFunction: cloudfront.Function;
59+
60+
/**
61+
* The Key-Value Store used by CloudFront.
62+
*/
63+
public readonly uriStore: cloudfront.KeyValueStore;
64+
65+
/**
66+
* The distribution's domain name.
67+
*/
68+
public readonly distributionDomainName: string;
69+
70+
/**
71+
* The distribution's URL (https://{domainName}).
72+
*/
73+
public readonly distributionUrl: string;
74+
75+
/**
76+
* Reference to the hosting infrastructure construct.
77+
*/
78+
public readonly hostingInfrastructure: HostingInfrastructure;
79+
80+
/**
81+
* Reference to the pipeline infrastructure construct.
82+
*/
83+
public readonly pipelineInfrastructure: PipelineInfrastructure;
84+
5285
constructor(scope: Construct, id: string, params: IParamProps) {
5386
super(scope, id);
5487

55-
const uriStore = new cloudfront.KeyValueStore(this, 'UriStore', {
88+
// Create URI Store
89+
this.uriStore = new cloudfront.KeyValueStore(this, 'UriStore', {
5690
keyValueStoreName: truncateString(Aws.STACK_NAME + "-" + Aws.REGION, 65)
5791
});
5892

93+
// Setup CloudFront Function
5994
let cloudFrontFunctionCode = fs.readFileSync(params.cffSourceFilePath, 'utf-8');
95+
cloudFrontFunctionCode = cloudFrontFunctionCode.replace(/__KVS_ID__/g, this.uriStore.keyValueStoreId);
6096

61-
cloudFrontFunctionCode = cloudFrontFunctionCode.replace(/__KVS_ID__/g, uriStore.keyValueStoreId);
62-
63-
const changeUri = new cloudfront.Function(this, "ChangeUri", {
97+
this.changeUriFunction = new cloudfront.Function(this, "ChangeUri", {
6498
code: cloudfront.FunctionCode.fromInline(cloudFrontFunctionCode),
65-
runtime: cloudfront.FunctionRuntime.JS_2_0,
99+
runtime: cloudfront.FunctionRuntime.JS_2_0,
66100
comment: "Change uri",
67-
68101
});
69102

70-
71-
(changeUri.node.defaultChild as cloudfront.CfnFunction).addPropertyOverride("FunctionConfig.KeyValueStoreAssociations",
72-
[{
73-
"KeyValueStoreARN": uriStore.keyValueStoreArn
74-
}]);
75-
103+
(this.changeUriFunction.node.defaultChild as cloudfront.CfnFunction).addPropertyOverride(
104+
"FunctionConfig.KeyValueStoreAssociations",
105+
[{
106+
"KeyValueStoreARN": this.uriStore.keyValueStoreArn
107+
}]
108+
);
76109

77-
const hostingInfrastructure = new HostingInfrastructure(this, "HostingInfrastructure", {
78-
changeUri: changeUri,
110+
// Create Hosting Infrastructure
111+
this.hostingInfrastructure = new HostingInfrastructure(this, "HostingInfrastructure", {
112+
changeUri: this.changeUriFunction,
79113
certificateArn: params.certificateArn,
80114
hostingConfiguration: params.hostingConfiguration,
81115
});
82116

83-
new PipelineInfrastructure(this, "PipelineInfrastructure", {
117+
// Set properties from hosting infrastructure
118+
this.distribution = this.hostingInfrastructure.distribution;
119+
this.hostingBucket = this.hostingInfrastructure.hostingBucket;
120+
this.distributionDomainName = this.distribution.distributionDomainName;
121+
this.distributionUrl = `https://${this.distributionDomainName}`;
122+
123+
// Create Pipeline Infrastructure
124+
this.pipelineInfrastructure = new PipelineInfrastructure(this, "PipelineInfrastructure", {
84125
hostingConfiguration: params.hostingConfiguration,
85126
connectionArn: params.connectionArn,
86-
kvsArn: uriStore.keyValueStoreArn,
87-
hostingBucket: hostingInfrastructure.hostingBucket,
88-
changeUri: changeUri,
127+
kvsArn: this.uriStore.keyValueStoreArn,
128+
hostingBucket: this.hostingBucket,
129+
changeUri: this.changeUriFunction,
89130
buildFilePath: params.buildFilePath,
90131
});
91132
}
92-
}
133+
}

lib/hosting_infrastructure.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ interface IConfigProps {
4747

4848

4949
export class HostingInfrastructure extends Construct {
50+
5051
public readonly hostingBucket: IBucket;
52+
public readonly distribution: cloudfront.Distribution;
5153

5254

5355

@@ -77,7 +79,7 @@ export class HostingInfrastructure extends Construct {
7779
},
7880
]);
7981
*/
80-
const hostingBucket = new s3.Bucket(this, "HostingBucket", {
82+
this.hostingBucket = new s3.Bucket(this, "HostingBucket", {
8183
versioned: false,
8284
...(s3Logs ? { serverAccessLogsBucket: s3Logs } : {}),
8385
enforceSSL: true,
@@ -90,9 +92,8 @@ export class HostingInfrastructure extends Construct {
9092
}),
9193
});
9294

93-
this.hostingBucket = hostingBucket;
9495

95-
const s3origin = new origins.S3Origin(hostingBucket);
96+
const s3origin = new origins.S3Origin(this.hostingBucket);
9697

9798
const myResponseHeadersPolicy = new cloudfront.ResponseHeadersPolicy(
9899
this,
@@ -246,7 +247,7 @@ export class HostingInfrastructure extends Construct {
246247

247248

248249

249-
const distribution = new cloudfront.Distribution(this, "Distribution", {
250+
this.distribution = new cloudfront.Distribution(this, "Distribution", {
250251
comment: "Static hosting - " + Aws.STACK_NAME,
251252
defaultRootObject: "index.html",
252253
httpVersion: cloudfront.HttpVersion.HTTP2_AND_3,
@@ -279,7 +280,7 @@ export class HostingInfrastructure extends Construct {
279280
: {}),
280281
});
281282

282-
NagSuppressions.addResourceSuppressions(distribution, [
283+
NagSuppressions.addResourceSuppressions(this.distribution, [
283284
{
284285
id: "AwsSolutions-CFR4",
285286
reason:
@@ -290,7 +291,7 @@ export class HostingInfrastructure extends Construct {
290291
//OAC is not implemented in CDK so tweaking is required:eplace OAI par OAC
291292
//https://github.com/aws/aws-cdk/issues/21771
292293

293-
const cfnDistribution = distribution.node.defaultChild as CfnDistribution;
294+
const cfnDistribution = this.distribution.node.defaultChild as CfnDistribution;
294295
cfnDistribution.addOverride(
295296
"Properties.DistributionConfig.Origins.0.S3OriginConfig.OriginAccessIdentity",
296297
""
@@ -300,7 +301,7 @@ export class HostingInfrastructure extends Construct {
300301
oac.getAtt("Id")
301302
);
302303

303-
const comS3PolicyOverride = hostingBucket.node.findChild("Policy").node
304+
const comS3PolicyOverride = this.hostingBucket.node.findChild("Policy").node
304305
.defaultChild as CfnBucketPolicy;
305306
const statement = comS3PolicyOverride.policyDocument.statements[1];
306307
if (statement["_principal"] && statement["_principal"].CanonicalUser) {
@@ -318,30 +319,30 @@ export class HostingInfrastructure extends Construct {
318319
service: "cloudfront",
319320
region: "",
320321
resource: "distribution",
321-
resourceName: distribution.distributionId,
322+
resourceName: this.distribution.distributionId,
322323
arnFormat: ArnFormat.SLASH_RESOURCE_NAME,
323324
}),
324325
},
325326
}
326327
);
327328

328-
const s3OriginNode = distribution.node
329+
const s3OriginNode = this.distribution.node
329330
.findAll()
330331
//.filter((child) => child.node.id === "S3Origin");
331332
.filter((child) => child.node.id === "S3Origin");
332333
s3OriginNode[0].node.tryRemoveChild("Resource");
333334
//End of tweaking for OAC is not implemented in CDK so tweaking is required
334335

335336
new CfnOutput(this, "DomainName", {
336-
value: "https://" + distribution.domainName,
337+
value: "https://" + this.distribution.domainName,
337338
});
338339

339340
const stackName = calculateMainStackName(params.hostingConfiguration);
340341

341342

342343
new ssm.StringParameter(this, 'SSMConnectionRegion', {
343344
parameterName: '/' + stackName + '/' + SSM_DOMAIN_STR,
344-
stringValue: distribution.domainName,
345+
stringValue: this.distribution.domainName,
345346
});
346347

347348

0 commit comments

Comments
 (0)