DEV Community

Cover image for Deploying a Simple Static Website on AWS with CDK and TypeScript
Sri for AWS Community Builders

Posted on

Deploying a Simple Static Website on AWS with CDK and TypeScript

You may have come across several blogs on hosting static websites on S3. This guide demonstrates how to create and deploy a simple static website using AWS CDK with TypeScript. The project will cover:

  • Setting up a basic AWS CDK project structure.
  • Defining infrastructure as code (IaC) with TypeScript.
  • Creating AWS resources necessary for hosting a static website.
  • Deploying the website to AWS.

The website source code is hosted on GitHub: kasukur/cdk-s3-website.


Table of Contents

  1. Prerequisites
  2. Step 1: Initialize the Project
  3. Step 2: Create a Simple Website
  4. Step 3: Write CDK Code to Host the Website
  5. Step 4: Deploy the Website
  6. Full Command History
  7. Clean Up
  8. Conclusion
  9. Referrals

Prerequisites

Before starting, ensure you have the following installed:

  • Node.js (>= 14.x)
  • AWS CLI (configured with credentials)
  • AWS CDK (>= 2.x)

To install AWS CDK globally:

npm install -g aws-cdk
Enter fullscreen mode Exit fullscreen mode

Step 1: Initialize the Project

  1. Create a project directory and navigate to it:

     mkdir cdk-s3-website && cd cdk-s3-website
    
  2. Initialize a new CDK app:

     cdk init app --language typescript
    
  3. Install dependencies for the CDK constructs we'll use:

     npm install @aws-cdk/aws-s3 @aws-cdk/aws-s3-deployment
    
  4. Verify the setup by synthesizing the stack:

     cdk synth
    

This command generates the CloudFormation template for your stack.


Step 2: Create a Simple Website

  1. Download the website tempalte from html5up.net:

  2. unzip the file, navigate to the folder and copy all the files to the website folder.

cp -r ~/Downloads/html5up-dimension ~/Documents/cdk-s3-website/website/.
Enter fullscreen mode Exit fullscreen mode

Step 3: Write CDK Code to Host the Website

Edit the lib/cdk-s3-website-stack.ts file to define the resources:

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as s3deploy from 'aws-cdk-lib/aws-s3-deployment';

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

    // Create an S3 bucket for website hosting
    const websiteBucket = new s3.Bucket(this, 'WebsiteBucket', {
      websiteIndexDocument: 'index.html',
      publicReadAccess: true,
      removalPolicy: cdk.RemovalPolicy.DESTROY, // Allow deletion of non-empty bucket
      autoDeleteObjects: true, // Automatically delete objects when bucket is removed
    });

    // Deploy the website content to the S3 bucket
    new s3deploy.BucketDeployment(this, 'DeployWebsite', {
      sources: [s3deploy.Source.asset('./website')],
      destinationBucket: websiteBucket,
    });

    // Output the website URL
    new cdk.CfnOutput(this, 'WebsiteURL', {
      value: websiteBucket.bucketWebsiteUrl,
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Deploy the Website

Run the following commands to deploy your website:

  1. Bootstrap the environment:

     cdk bootstrap
    
  2. You might noticed the following error:

     Error: Cannot use 'publicReadAccess' property on a bucket           without allowing bucket-level public access through 'blockPublicAccess' property.
    at new Bucket (/Users/sridharkasukurthy/Documents/cdk-s3-website/node_modules/aws-cdk-lib/aws-s3/lib/bucket.js:1:24460)
         ...
    

    Troubleshooting: The error occurs because the publicReadAccess: true property is used without explicitly allowing public access by disabling the blockPublicAccess feature. AWS CDK enforces stricter controls to prevent unintended public access.

    Solution: To fix this, we need to configure the bucket to allow public access explicitly by setting the blockPublicAccess feature.

    Updated Code:

     import * as cdk from 'aws-cdk-lib';
     import { Construct } from 'constructs';
     import * as s3 from 'aws-cdk-lib/aws-s3';
     import * as s3Deploy from 'aws-cdk-lib/aws-s3-deployment';
    
     export class CdkS3WebsiteStack extends cdk.Stack {
       constructor(scope: Construct, id: string, props?: cdk.StackProps) {
         super(scope, id, props);
    
         // Create an S3 bucket for the website with public access explicitly allowed
         const websiteBucket = new s3.Bucket(this, 'SriSriWebsiteBucket', {
           websiteIndexDocument: 'index.html',
           publicReadAccess: true,
           removalPolicy: cdk.RemovalPolicy.DESTROY, // Optional: Remove the bucket on stack deletion
           blockPublicAccess: s3.BlockPublicAccess.BLOCK_ACLS, // Allows public access but blocks ACLs
         });
    
         // Deploy website contents to the bucket
         new s3Deploy.BucketDeployment(this, 'DeployWebsite', {
           sources: [s3Deploy.Source.asset('./website')],
           destinationBucket: websiteBucket,
         });
    
         // Output the website URL
         new cdk.CfnOutput(this, 'WebsiteURL', {
           value: websiteBucket.bucketWebsiteUrl,
         });
       }
     }
    
  3. Bootstrap the environment again:

     cdk bootstrap
    
  4. Deploy the stack:

     cdk deploy
    

    Do you wish to deploy these changes (y/n)? y

During deployment, the CDK will output the URL for the hosted website. You can access your site using this URL.


Full Command History

Hereโ€™s a reference of all commands used:

1  mkdir cdk-s3-website && cd cdk-s3-website
2  cdk init app --language typescript
3  npm install @aws-cdk/aws-s3 @aws-cdk/aws-s3-deployment
4  git clone https://github.com/kasukur/s3-website.git website
5  cdk synth
6  cdk bootstrap
7  cdk deploy
Enter fullscreen mode Exit fullscreen mode

Image description


Clean Up

To avoid incurring unnecessary charges, delete the stack. If the cdk destroy command fails due to non-empty buckets, empty the bucket manually or use the autoDeleteObjects property in your stack as shown above:

  1. Manually empty the bucket:
   aws s3 rm s3://<bucket-name> --recursive
Enter fullscreen mode Exit fullscreen mode
  1. Destroy the stack:
   cdk destroy
Enter fullscreen mode Exit fullscreen mode

Conclusion

This project demonstrated how to use AWS CDK with TypeScript to deploy a simple static website on AWS. The focus was on showcasing the CDKโ€™s capabilities for infrastructure provisioning and deployment automation. You can now customize and expand upon this setup for more complex use cases.


Referrals


Top comments (0)