@cloudcomponents/cdk-static-website

Cdk component that creates a static website using S3, configures CloudFront (CDN) and maps a custom domain via Route53 (DNS)

Usage no npm install needed!

<script type="module">
  import cloudcomponentsCdkStaticWebsite from 'https://cdn.skypack.dev/@cloudcomponents/cdk-static-website';
</script>

README

cloudcomponents Logo

@cloudcomponents/cdk-static-website

Build Status cdkdx typescript python Mentioned in Awesome CDK

Cdk component that creates a static website using S3, configures CloudFront (CDN) and maps a custom domain via Route53 (DNS)

Install

TypeScript/JavaScript:

npm i @cloudcomponents/cdk-static-website

Python:

pip install cloudcomponents.cdk-static-website

How to use

Example 1: With an existing certificate

import { Construct, RemovalPolicy, Stack, StackProps } from '@aws-cdk/core';
import { StringParameter } from '@aws-cdk/aws-ssm';
import { SecurityPolicyProtocol } from '@aws-cdk/aws-cloudfront';
import { StaticWebsite } from '@cloudcomponents/cdk-static-website';
import { HttpHeaders } from '@cloudcomponents/cdk-lambda-at-edge-pattern';

export class StaticWebsiteStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id, props);

    const certificateArn = StringParameter.valueFromLookup(
      this,
      '/certificate/cloudcomponents.org',
    );

    const website = new StaticWebsite(this, 'StaticWebsite', {
      bucketConfiguration: {
        removalPolicy: RemovalPolicy.DESTROY,
      },
      aliasConfiguration: {
        domainName: 'cloudcomponents.org',
        names: ['www.cloudcomponents.org', 'cloudcomponents.org'],
        acmCertRef: certificateArn,
      },
    });

    // A us-east-1 stack is generated under the hood
    const httpHeaders = new HttpHeaders(this, 'HttpHeaders', {
      httpHeaders: {
        'Content-Security-Policy':
          "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; object-src 'none'; connect-src 'self'",
        'Strict-Transport-Security':
          'max-age=31536000; includeSubdomains; preload',
        'Referrer-Policy': 'same-origin',
        'X-XSS-Protection': '1; mode=block',
        'X-Frame-Options': 'DENY',
        'X-Content-Type-Options': 'nosniff',
        'Cache-Control': 'no-cache',
      },
    });

    website.addLambdaFunctionAssociation(httpHeaders);
  }
}

Example 2: Cloudfront URL with existing sources and up to date Securitypolicy

import { Construct, RemovalPolicy, Stack, StackProps } from '@aws-cdk/core';
import { StringParameter } from '@aws-cdk/aws-ssm';
import { StaticWebsite } from '@cloudcomponents/cdk-static-website';
import { SecurityPolicyProtocol } from '@aws-cdk/aws-cloudfront';

export class StaticWebsiteWithExistingSourcesAndSecurityPolicyStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const certificateArn = StringParameter.valueFromLookup(
      this,
      '/certificate/cloudcomponents.org',
    );

    new StaticWebsite(this, 'StaticWebsite', {
      bucketConfiguration: {
        source: '../path/to/your/static/webpage',
        removalPolicy: RemovalPolicy.DESTROY,
      },
      aliasConfiguration: {
        domainName: 'cloudcomponents.org',
        names: ['www.cloudcomponents.org', 'cloudcomponents.org'],
        acmCertRef: certificateArn,
        securityPolicy: SecurityPolicyProtocol.TLS_V1_2_2018
      },
    });
  }
}

Lambda@Edge function

website.addLambdaFunctionAssociation({
  eventType: LambdaEdgeEventType.ORIGIN_REQUEST,
  lambdaFunction: Version.fromVersionArn(
    stack,
    'LambdaEdge',
    'arn:aws:lambda:us-east-1:123456789012:function:my-function:1',
  ),
});

API Reference

See API.md.

Example

See more complete examples.

License

MIT