cdk-spa
v2.0.0
Published
This CDK Construct deploy a Single Page Application (ReactJS / VueJS / Angular) websites to AWS S3 behind CloudFront-CDN, Route53-DNS, ACM-SSL.
Downloads
6
Maintainers
Readme
[CDK Construct] cdk-spa
Deploying Single Page Application (SPA) Website
💎 This CDK TypeScript Construct Library cdk-spa
includes a construct CdkSpa
and an interface CdkSpaProps
to make deploying a Single Page Application (SPA) Website (React.js / Vue.js / Angular) to AWS S3 behind CloudFront CDN, Route53 DNS, AWS Certificate Manager SSL as easy as 5 lines of code.
The Architecture for CDK-SPA Websites supporting customer-specific subdomains:
- Customers access your application through a browser by entering their personal subdomain (for example, https://chatbot.job4u.io).
Amazon Route53
receives the request for the customer-specific subdomain and routes it to theAmazon CloudFront
Distribution.CloudFront
caches your web application from theAmazon S3
Bucket where it is stored. Note that theCloudFront Distribution
is configured with read-only permissions to access files inAmazon S3
.CloudFront
uses a TLS certificate provisioned inACM
to deliver the content from the nearest edge location.
Installation and Usage
✅ Typescript
npm install --save cdk-spa
import * as cdk from '@aws-cdk/core';
import { CdkSpa } from 'cdk-spa';
export class CdkStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
/** Deploying a Website to AWS S3 */
new CdkSpa(this, 'CDK-SPA Website')
.createSiteS3({
indexDoc: 'index.html',
websiteFolder: 'website'
});
/** Deploying a SPA-Website to AWS S3 behind CloudFront CDN */
new CdkSpa(this, 'CDK-SPA Website behind Cloudfront CDN')
.createSiteWithCloudfront({
indexDoc: 'index.html',
websiteFolder: '../frontend'
});
}
}
☑️ Python
pip install cdk-spa
from aws_cdk import core
from cdk-spa import CdkSpa
class PythonStack(core.Stack):
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
CdkSpa(self, 'CDK-SPA Website').create_site_s3(
index_doc='index.html',
website_folder='website'
)
CdkSpa(self, 'CDK-SPA Website behind Cloudfront CDN').create_site_with_cloudfront(
index_doc='index.html',
website_folder='../frontend'
)
Advanced Usage
Auto Deploy From Hosted Zone Name
If you purchased your domain through Route 53 and already have a Hosted Zone then just use the name to deploy your site behind Cloudfront. This handles the SSL cert and everything for you.
new CdkSpa(this, 'spaDeploy', { encryptBucket: true })
.createSiteFromHostedZone({
zoneName: 'dashboard.aws.oceansoft.io',
indexDoc: 'index.html',
websiteFolder: '../frontend/dist'
});
Custom Domain and SSL Certificates
You can also pass the ARN for an SSL certification and your alias routes to Cloudfront
import cdk = require('@aws-cdk/core');
import { CdkSpa } from 'cdk-spa';
export class CdkStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
new CdkSpa(this, 'cfDeploy')
.createSiteWithCloudfront({
indexDoc: '../frontend/dist',
certificateARN: 'arn:...',
cfAliases: ['cdn.aws.oceansoft.io']
});
}
}
Encrypted S3 Bucket
Pass in one boolean to tell SPA Deploy to encrypt your website bucket
new CdkSpa(this, 'cfDeploy', {encryptBucket: true}).createBasicSite({
indexDoc: 'index.html',
websiteFolder: 'website'
});
Custom Origin Behaviors
Pass in an array of CloudFront Behaviors
new CdkSpa(this, 'cfDeploy').createSiteWithCloudfront({
indexDoc: 'index.html',
websiteFolder: 'website',
cfBehaviors: [
{
isDefaultBehavior: true,
allowedMethods: cf.CloudFrontAllowedMethods.ALL,
forwardedValues: {
queryString: true,
cookies: { forward: 'all' },
headers: ['*'],
},
},
{
pathPattern: '/virtual-path',
allowedMethods: cf.CloudFrontAllowedMethods.GET_HEAD,
cachedMethods: cf.CloudFrontAllowedCachedMethods.GET_HEAD,
},
],
});
Restrict Access to Known IPs
Pass in a boolean and an array of IP addresses and your site is locked down!
new CdkSpa(stack, 'spaDeploy', {
encryptBucket: true,
ipFilter: true,
ipList: ['1.1.1.1']
}).createBasicSite({
indexDoc: 'index.html',
websiteFolder: 'website'
})
Modifying S3 Bucket Created in Construct
An object is now returned containing relevant artifacts created if you need to make any further modifications:
- The S3 bucket is present for all of the methods
- When a CloudFront Web distribution is created it will be present in the return object
export interface CdkSpaProps {
readonly websiteBucket: s3.Bucket,
}
export interface CdkSpaPropsWithCloudFront extends CdkSpaProps {
readonly distribution: CloudFrontWebDistribution,
}
Project Directory
$CDK-Patterns/cdk/constructs/cdk-spa
├── lib
| └── index.ts
├── package.json
├── test
| └── cdk-spa.test.ts
├── README.md
├── jest.config.js
├── tsconfig.json
├── tsconfig.json.origin
└── website
└── index.html
💪 [Manually] Roll-Your-Own CDK-Construct
You may skip
Projen
and start your own CDK-Construct project.[x] Default TypeScript project:
# npm install -g aws-cdk # cdk --version cdk init lib --language=typescript
[x] Make sure your
package.json
has author, repository, and description filled out correctly[x] Initialize jsii by running
npx jsii-config
[x] Use jsii-config to add all language targets
[x] Add jsii and jsii-pacmak as dependencies
npm i --save-dev jsii jsii-pacmak
[x] Create a build and a package script that call jsii and jsii-pacmak respectively
[ ]
npm publish
to make your template available on the npm package registry.
npm login npm init --scope=oceansoft # npm publish npm publish --access public * [x] Build and Package JSII modules, then Release to NPM --> `CI-cdk-spa.yml`
npm run package npx -p jsii-release jsii-release-npm
Despite the fact that this is perfectly possible, we still strongly recommend that you use
Projen
as it handles all setup, configuration, and release scripting for you.
Useful commands
npm run build
compile typescript to jsnpm run watch
watch for changes and compilenpm run test
perform the jest unit tests
✅ NPM Package:
https://www.npmjs.com/package/cdk-spa
💰
https://github.com/OceanSoftIO/Serverless/cdk