DEV Community

Cover image for Fast Static Website Deployment with Angular and Pulumi
Pranav jana
Pranav jana Subscriber

Posted on

3 1

Fast Static Website Deployment with Angular and Pulumi

This is a submission for the Pulumi Deploy and Document Challenge: Fast Static Website Deployment

What I Built

I deployed an Angular application (SkillSwap) to AWS using infrastructure as code with Pulumi. The solution includes:

  • S3 bucket for static website hosting
  • CloudFront CDN for global content delivery with HTTPS
  • SPA routing support for Angular's client-side routing
  • Automated deployment process with a single command

SkillSwap is a skill-sharing platform where users can exchange services based on their skills. The Angular application features user profiles, messaging, skill search, and ratings.

Live Demo Link

SkillSwap Application (Example CloudFront URL - actual URL will be available after deployment)

Project Repo

The project repository contains both the Angular application and the infrastructure code:

skillswap/          # Angular application
skillswap-infra/    # Pulumi infrastructure code
Enter fullscreen mode Exit fullscreen mode

Repository Structure

The infrastructure portion includes:

  • index.ts - Main Pulumi infrastructure definition
  • deploy.js - Automated deployment script
  • README.md - Setup and usage instructions
  • architecture.puml - Architecture diagram source

My Journey

Choosing Technologies

For this challenge, I selected:

  • Angular as my static website framework for its robust TypeScript support and component architecture
  • AWS (S3 + CloudFront) as my cloud provider for its reliability and global presence
  • Pulumi as my IaC tool for its use of familiar programming languages (TypeScript)

Setup & Planning

I started by setting up a dedicated infrastructure directory separate from the Angular application code. This separation of concerns helps maintain clean architecture and allows the infrastructure to evolve independently.

mkdir skillswap-infra
cd skillswap-infra
npm init -y
npm install @pulumi/pulumi @pulumi/aws typescript @types/node mime @types/mime
npx tsc --init
Enter fullscreen mode Exit fullscreen mode

Infrastructure Definition

The core infrastructure is defined in index.ts, where I created:

  1. S3 Bucket configured for static website hosting:
const siteBucket = new aws.s3.Bucket("skillswap-website-bucket", {
    website: {
        indexDocument: "index.html",
        errorDocument: "index.html",
    },
});
Enter fullscreen mode Exit fullscreen mode
  1. Public access policy to allow website visitors to access content:
const bucketPolicy = new aws.s3.BucketPolicy("bucketPolicy", {
    bucket: siteBucket.id,
    policy: siteBucket.id.apply(bucketId => JSON.stringify({
        Version: "2012-10-17",
        Statement: [{
            Effect: "Allow",
            Principal: "*",
            Action: ["s3:GetObject"],
            Resource: [`arn:aws:s3:::${bucketId}/*`]
        }]
    }))
});
Enter fullscreen mode Exit fullscreen mode
  1. CloudFront distribution for global content delivery and HTTPS:
const cdn = new aws.cloudfront.Distribution("skillswap-cdn", {
    enabled: true,
    origins: [{
        originId: siteBucket.arn,
        domainName: siteBucket.websiteEndpoint,
        customOriginConfig: {
            originProtocolPolicy: "http-only",
            httpPort: 80,
            httpsPort: 443,
            originSslProtocols: ["TLSv1.2"],
        },
    }],
    // ... additional configuration ...
});
Enter fullscreen mode Exit fullscreen mode
  1. SPA routing support for Angular's client-side routing:
customErrorResponses: [
    {
        errorCode: 404,
        responseCode: 200,
        responsePagePath: "/index.html",
    },
],
Enter fullscreen mode Exit fullscreen mode

Challenges Faced

  1. SPA Routing Configuration

One of the main challenges was configuring CloudFront to properly handle Angular's client-side routing. When users navigate to a route directly (e.g., /profile/123), the server would typically return a 404 since there's no physical file at that path.

Solution: I configured CloudFront to redirect 404 errors to index.html, allowing Angular's router to handle the navigation:

   customErrorResponses: [
       {
           errorCode: 404,
           responseCode: 200,
           responsePagePath: "/index.html",
       },
   ],
Enter fullscreen mode Exit fullscreen mode
  1. File Upload Mechanism

Another challenge was efficiently syncing the Angular build files to S3 while preserving the correct content types.

Solution: I created a recursive directory walking function that:

  • Discovers all files in the build directory
  • Determines the correct MIME type for each file
  • Creates S3 bucket objects with appropriate metadata
  • Handles Windows path separators by converting to URL-compatible format
  1. Deployment Automation

To simplify the deployment process, I wanted a single command that would build the Angular app if needed and deploy the infrastructure.

Solution: I created a deploy.js script that:

  • Checks if the Angular app is already built
  • Builds the app if necessary
  • Dynamically updates the Pulumi code to enable file uploads
  • Runs the Pulumi deployment

Performance Optimizations

I implemented several performance optimizations:

  1. CloudFront Caching: Configured TTLs for different content types to optimize caching behavior
  2. Compression: Enabled gzip/Brotli compression for text-based assets
  3. Region Selection: CloudFront automatically uses edge locations closest to users

Using Pulumi

Pulumi provided several key advantages for this project:

  1. Familiar Language: Using TypeScript meant I could leverage the same language for both my application and infrastructure, reducing context switching.

  2. Programmatic Abstractions: I could create reusable functions for tasks like file uploading, making the code more maintainable.

  3. Resource Relationships: Pulumi's programming model made it easy to define relationships between resources (like the S3 bucket and CloudFront distribution).

  4. State Management: Pulumi handles the state management, tracking what resources are created and their properties, making updates safer.

  5. Preview Capabilities: The pulumi preview command let me see what changes would be made before applying them.

Key Benefits Over Traditional Methods

Compared to manual deployment or using CloudFormation/Terraform, Pulumi offered:

  • Easier Debugging: Using a full programming language made debugging more straightforward
  • Richer Abstractions: I could use loops, conditionals, and functions to generate resources
  • Better Developer Experience: IntelliSense and type checking helped prevent errors
  • Easier Integration: Working with the Angular build process was seamless

Architecture Diagram

The following diagram illustrates the architecture of the deployed solution:

[User] --> [CloudFront CDN] --> [S3 Bucket]
  ^                               ^
  |                               |
  +---------- [Pulumi] -----------+
Enter fullscreen mode Exit fullscreen mode

Next Steps

Future improvements could include:

  • Custom domain configuration with SSL certificates
  • CI/CD pipeline integration
  • Environment-specific configurations
  • Performance monitoring and analytics

Conclusion

This project demonstrates how Pulumi can be used to deploy a static website to AWS efficiently. The infrastructure-as-code approach provides repeatability, maintainability, and automation, while leveraging familiar programming languages and tools.

Heroku

Amplify your impact where it matters most — building exceptional apps.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (0)

Image of Datadog

The Essential Toolkit for Front-end Developers

Take a user-centric approach to front-end monitoring that evolves alongside increasingly complex frameworks and single-page applications.

Get The Kit

AWS GenAI LIVE!

GenAI LIVE! is a dynamic live-streamed show exploring how AWS and our partners are helping organizations unlock real value with generative AI.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️