-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add alternate domain names to cdn site host construct (#84)
- Loading branch information
Showing
18 changed files
with
8,169 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -104,6 +104,19 @@ jobs: | |
- run: | ||
name: Build and deploy authenticated api example code | ||
command: cd examples/simple-authenticated-api && npm install && npm run build && npx cdk --require-approval never deploy | ||
deploy-cdn-site-hosting: | ||
executor: default_executor | ||
steps: | ||
- add_ssh_keys: | ||
fingerprints: | ||
- "ee:b4:00:e6:23:5b:55:bb:fd:07:bc:73:9e:f7:89:9c" # [email protected] 'talis-cdk-constructs Deploy Key' | ||
- restore_root_build_number | ||
- set_aws_prefix | ||
- checkout | ||
- node_install_packages | ||
- run: | ||
name: Build and deploy cdn site hosting example code | ||
command: cd examples/simple-cdn-site-hosting-construct && npm install && npm run build && npx cdk --require-approval never deploy | ||
test: | ||
executor: default_executor | ||
steps: | ||
|
@@ -146,6 +159,19 @@ jobs: | |
- run: | ||
name: Destroy authenticated api example code | ||
command: cd examples/simple-authenticated-api && npm install && npm run build && npx cdk --require-approval never destroy --force | ||
destroy-cdn-site-hosting: | ||
executor: default_executor | ||
steps: | ||
- add_ssh_keys: | ||
fingerprints: | ||
- "ee:b4:00:e6:23:5b:55:bb:fd:07:bc:73:9e:f7:89:9c" # [email protected] 'talis-cdk-constructs Deploy Key' | ||
- restore_root_build_number | ||
- set_aws_prefix | ||
- checkout | ||
- node_install_packages | ||
- run: | ||
name: Destroy cdn site hosting example code | ||
command: cd examples/simple-cdn-site-hosting-construct && npm install && npm run build && npx cdk --require-approval never destroy --force | ||
semantic-release: | ||
executor: default_executor | ||
steps: | ||
|
@@ -197,10 +223,18 @@ workflows: | |
- cdk-deploy-to-shared-aspire-20211202 | ||
- aws-region-eu | ||
- talis-cdk-constructs-build | ||
- deploy-cdn-site-hosting: | ||
requires: | ||
- build | ||
context: | ||
- cdk-deploy-to-shared-aspire-20211202 | ||
- aws-region-eu | ||
- talis-cdk-constructs-build | ||
- test: | ||
requires: | ||
- deploy-lambda-worker | ||
- deploy-authenticated-api | ||
- deploy-cdn-site-hosting | ||
context: | ||
- cdk-deploy-to-shared-aspire-20211202 | ||
- aws-region-eu | ||
|
@@ -219,10 +253,18 @@ workflows: | |
- cdk-deploy-to-shared-aspire-20211202 | ||
- aws-region-eu | ||
- talis-cdk-constructs-build | ||
- destroy-cdn-site-hosting: | ||
requires: | ||
- test | ||
context: | ||
- cdk-deploy-to-shared-aspire-20211202 | ||
- aws-region-eu | ||
- talis-cdk-constructs-build | ||
- semantic-release: | ||
requires: | ||
- destroy-lambda-worker | ||
- destroy-authenticated-api | ||
- destroy-cdn-site-hosting | ||
context: | ||
- cdk-deploy-to-shared-aspire-20211202 | ||
- aws-region-eu | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
*.js | ||
!jest.config.js | ||
*.d.ts | ||
node_modules | ||
|
||
# CDK asset staging directory | ||
.cdk.staging | ||
cdk.out |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
*.ts | ||
!*.d.ts | ||
|
||
# CDK asset staging directory | ||
.cdk.staging | ||
cdk.out |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
# CdnSiteHostingConstruct Example: SimpleCdnSiteHostingConstructStack | ||
|
||
This is an example of using the CdnSiteHostingConstruct and the CdnSiteHostingWithDnsConstruct in a simple stack to host a static website. | ||
|
||
The CdnSiteHostingConstruct: | ||
|
||
- creates a bucket to host the static html | ||
- creates a cloudfront distribution to server the website | ||
|
||
Optionionally, the CdnSiteHostingWithDnsConstruct: | ||
|
||
- sets up a DNS entry int Route 53 pointing at the cloudfront distribution | ||
|
||
## This Example | ||
|
||
To build and deploy this example: | ||
|
||
- `export AWS_PREFIX=development-XX-` where XX are your initials | ||
- This is used in the name of the stack and resources created, so that they do not clash with anyone elses stack in AWS | ||
- `source awsenv <profile>` to set your credentials to the shared account | ||
- `npm install` | ||
- `npm run build` | ||
- `cdk deploy` | ||
|
||
After you have finished with the example, remove your stack in AWS using: | ||
|
||
- `cdk destroy` | ||
|
||
## Best Practice Using this Construct | ||
|
||
It's best practice NOT to create a DNS entry for a production website within a cloud formation stack. In production | ||
best practice is to be bring up a cloud formation stack and manually point a route 53 entry to the cloud front distribution. | ||
|
||
Why? We want the ability, if necessary, to bring up a new cloud formation stack and when we are happy that it is working | ||
as expected, switch the DNS manually to point to the new stack. | ||
|
||
Therefore, production deployments should use the CdnSiteHostingConstruct and set a watermarked sub domain name. For example: | ||
|
||
```typescript | ||
new CdnSiteHostingConstruct( | ||
this, | ||
`TalisAppCdnSiteHostingConstruct`, | ||
{ | ||
domainName: "talis.io", | ||
siteSubDomain: `production-eu-20231025-talis-app`, | ||
aliasSubDomains: ['talis-app'], | ||
... | ||
}, | ||
); | ||
``` | ||
|
||
The above will create a cloud front distribution with two aliases: | ||
|
||
- `production-eu-20231025-talis-app.talis.io` | ||
- `talis-app.talis.io` | ||
|
||
Outside of the cloud formation stack, DNS entries can be manually created for both the aliases and either can be used to access the website. | ||
|
||
Unfortunately, cloud front can NOT have the same alias on two different distributions. This means we can not always set the `talis-app` alias from | ||
the above example on a new cloud front distribution. i.e. Attempting to create: | ||
|
||
```typescript | ||
new CdnSiteHostingConstruct( | ||
this, | ||
`TalisAppCdnSiteHostingConstruct`, | ||
{ | ||
domainName: "talis.io", | ||
siteSubDomain: `production-eu-20231026-talis-app`, | ||
aliasSubDomains: ['talis-app'], | ||
... | ||
}, | ||
); | ||
``` | ||
|
||
will fail. Despite the cloud formation stack having a different watermark, 20231026 instead of 20231025, and the siteSubDomain being `production-eu-20231026-talis-app.talis.io` instead of `production-eu-20231025-talis-app.talis.io` - the creation of the stack will fail due to the duplicate alias `talis-app.talis.io`. | ||
|
||
Therefore - when bringing up a new watermarked stack alongside an already live production stack, the alias sub domain must not initially be set: | ||
|
||
```typescript | ||
new CdnSiteHostingConstruct( | ||
this, | ||
`TalisAppCdnSiteHostingConstruct`, | ||
{ | ||
domainName: "talis.io", | ||
siteSubDomain: `production-eu-20231026-talis-app`, | ||
aliasSubDomains: [], | ||
... | ||
}, | ||
); | ||
``` | ||
|
||
This will mean the new stack can be deployed and tested at the watermarked DNS name, e.g. `production-eu-20231026-talis-app.talis.io`. | ||
|
||
When ready to switch the stacks in production, the `talis-app.talis.io` alias needs to be deleted from the old stack and added to the new stack manually. | ||
The DNS is then switched from the old cloud front distribution to the new one. | ||
|
||
If this was a simple DNS change, there would be no downtime. But due to the need to delete and recreate the alias on the cloud front distribution, there is a small | ||
period where the website is in accessible. Therefore, for a production site, ONLY when switching to a new cloud formation stack, NOT on every release, a maintenance | ||
window is required for the switch over. | ||
|
||
Subsequent deployments after the stack switch over DO need to add in the `talis-app` alias to the aliasSubDomains property of the construct. If they do not, | ||
the alias will be deleted and an outage will occur. | ||
|
||
This process should be managed via the hercules deployment script - setting up the `aliasSubDomain` for a standard deploy to the live watermark to include the | ||
additional alias. When a different watermark is specified, to bring up a new none live stack, hercules should ensure the `aliasSubDomain` property does not | ||
contain the additional alias. | ||
|
||
This will require logic in both the hercules script and the projects CDK deployment code to ensure this property is set correctly. | ||
|
||
LINK TO EXAMPLE HERE WHEN WE HAVE ONE | ||
|
||
## Useful commands | ||
|
||
- `npm run build` compile typescript to js | ||
- `npm run watch` watch for changes and compile | ||
- `npm run test` perform the jest unit tests | ||
- `cdk deploy` deploy this stack to your default AWS account/region | ||
- `cdk diff` compare deployed stack with current state | ||
- `cdk synth` emits the synthesized CloudFormation template |
16 changes: 16 additions & 0 deletions
16
examples/simple-cdn-site-hosting-construct/bin/simple-cdn-site-hosting-construct.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#!/usr/bin/env node | ||
import "source-map-support/register"; | ||
import * as cdk from "aws-cdk-lib"; | ||
import { SimpleCdnSiteHostingConstructStack } from "../lib/simple-cdn-site-hosting-construct-stack"; | ||
|
||
const app = new cdk.App(); | ||
new SimpleCdnSiteHostingConstructStack( | ||
app, | ||
`${process.env.AWS_PREFIX}simple-cdn-site-hosting-construct-stack`, | ||
{ | ||
env: { | ||
account: process.env.CDK_DEFAULT_ACCOUNT, | ||
region: process.env.CDK_DEFAULT_REGION, | ||
}, | ||
}, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"hosted-zone:account=302477901552:domainName=talis.io:region=eu-west-1": { | ||
"Id": "/hostedzone/ZQLU3GTNLTUB", | ||
"Name": "talis.io." | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
{ | ||
"app": "npx ts-node --prefer-ts-exts bin/simple-cdn-site-hosting-construct.ts", | ||
"watch": { | ||
"include": ["**"], | ||
"exclude": [ | ||
"README.md", | ||
"cdk*.json", | ||
"**/*.d.ts", | ||
"**/*.js", | ||
"tsconfig.json", | ||
"package*.json", | ||
"yarn.lock", | ||
"node_modules", | ||
"test" | ||
] | ||
}, | ||
"context": { | ||
"@aws-cdk/aws-lambda:recognizeLayerVersion": true, | ||
"@aws-cdk/core:checkSecretUsage": true, | ||
"@aws-cdk/core:target-partitions": ["aws", "aws-cn"], | ||
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, | ||
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, | ||
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, | ||
"@aws-cdk/aws-iam:minimizePolicies": true, | ||
"@aws-cdk/core:validateSnapshotRemovalPolicy": true, | ||
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, | ||
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, | ||
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, | ||
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true, | ||
"@aws-cdk/core:enablePartitionLiterals": true, | ||
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, | ||
"@aws-cdk/aws-iam:standardizedServicePrincipals": true, | ||
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, | ||
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, | ||
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, | ||
"@aws-cdk/aws-route53-patters:useCertificate": true, | ||
"@aws-cdk/customresources:installLatestAwsSdkDefault": false, | ||
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, | ||
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, | ||
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, | ||
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, | ||
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, | ||
"@aws-cdk/aws-redshift:columnId": true, | ||
"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true, | ||
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, | ||
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, | ||
"@aws-cdk/aws-kms:aliasNameRef": true, | ||
"@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true, | ||
"@aws-cdk/core:includePrefixInUniqueNameGeneration": true, | ||
"@aws-cdk/aws-efs:denyAnonymousAccess": true, | ||
"@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true, | ||
"@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true, | ||
"@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
module.exports = { | ||
testEnvironment: 'node', | ||
roots: ['<rootDir>/test'], | ||
testMatch: ['**/*.test.ts'], | ||
transform: { | ||
'^.+\\.tsx?$': 'ts-jest' | ||
} | ||
}; |
64 changes: 64 additions & 0 deletions
64
examples/simple-cdn-site-hosting-construct/lib/simple-cdn-site-hosting-construct-stack.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import * as cdk from "aws-cdk-lib"; | ||
import { aws_s3_deployment as s3deploy } from "aws-cdk-lib"; | ||
import { Construct } from "constructs"; | ||
import * as path from "path"; | ||
|
||
import { | ||
CdnSiteHostingConstruct, | ||
CdnSiteHostingWithDnsConstruct, | ||
} from "../../../lib"; | ||
|
||
export const STAGING_TALIS_IO_TLS_CERT_ARN = | ||
"arn:aws:acm:us-east-1:302477901552:certificate/7973186a-2f4f-4d4e-92c7-d50f92f32718"; | ||
|
||
export class SimpleCdnSiteHostingConstructStack extends cdk.Stack { | ||
constructor(scope: Construct, id: string, props?: cdk.StackProps) { | ||
super(scope, id, props); | ||
|
||
// Use AWS_PREFIX to give all resources in this sample | ||
// a unique name. This is usually `development-xx` where xx are your initials. | ||
// If you do not set AWS_PREFIX, when you deploy this stack, it may conflict | ||
// with someone elses stack who has also not set AWS_PREFIX | ||
const prefix = process.env.AWS_PREFIX | ||
? process.env.AWS_PREFIX | ||
: "development-xx-"; | ||
|
||
// Create a site without setting DNS | ||
/* const cdnSiteHostingConstruct = */ new CdnSiteHostingConstruct( | ||
this, | ||
`${prefix}CdnSiteHostingConstruct`, | ||
{ | ||
domainName: "talis.io", | ||
removalPolicy: cdk.RemovalPolicy.DESTROY, | ||
// siteDomain: This would be the watermarked domain name e.g. elevate-20231025 from https://elevate-20231025.talis.com | ||
siteSubDomain: `${prefix}cdn-site-hosting-construct`, | ||
// aliasSubDomains: The production stack would supply this alias, e.g. elevate.talis.com | ||
aliasSubDomains: [`${prefix}cdn-site-hosting-construct-alias`], | ||
sources: [ | ||
s3deploy.Source.asset(path.resolve(__dirname, "./static-site")), | ||
], | ||
websiteIndexDocument: "index.html", | ||
certificateArn: STAGING_TALIS_IO_TLS_CERT_ARN, | ||
}, | ||
); | ||
|
||
// Create a site with DNS | ||
/* const cdnSiteHostingWithDnsConstruct = */ new CdnSiteHostingWithDnsConstruct( | ||
this, | ||
`${prefix}CdnSiteHostingWithDnsConstruct`, | ||
{ | ||
domainName: "talis.io", | ||
removalPolicy: cdk.RemovalPolicy.DESTROY, | ||
// siteSubDomain: This would be the watermarked domain name e.g. elevate-20231025 from https://elevate-20231025.talis.com | ||
siteSubDomain: `${prefix}cdn-site-hosting-with-dns-construct`, | ||
// aliasSubDomains: The production stack would supply this alias, e.g. elevate.talis.com | ||
aliasSubDomains: [`${prefix}cdn-site-hosting-with-dns-construct-alias`], | ||
sources: [ | ||
s3deploy.Source.asset(path.resolve(__dirname, "./static-site")), | ||
], | ||
websiteIndexDocument: "index.html", | ||
certificateArn: STAGING_TALIS_IO_TLS_CERT_ARN, | ||
}, | ||
); | ||
} | ||
} |
1 change: 1 addition & 0 deletions
1
examples/simple-cdn-site-hosting-construct/lib/static-site/index.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<h1>Test Deployment</h1> |
Oops, something went wrong.