Deploy Astro on AWS S3 and CloudFront
Deploy your Astro site to AWS with S3 and CloudFront for fast, reliable performance. This guide walks you through configuration and setup to get your site live with Thunder.
There are two ways to deploy your Astro static output on AWS:
-
Using the AWS Cloud Development Kit (CDK) with the CDK-SPA package. Note that CDK-SPA does not support SSR.
-
Using the Thunder console to deploy your app with a few clicks.
The build artifacts (HTML, CSS and JavaScript) will be stored in an S3 bucket and served using CloudFront CDN.
View code in StackBlitz
Deploy Astro using AWS CDK
CDK-SPA is a package that simplifies the deployment of static sites to AWS using the AWS Cloud Development Kit (CDK). It provides a straightforward way to deploy your Astro app to AWS S3 and CloudFront.
1. Create a project
You can create a new Astro project using the following commands:
npm create astro@latest my-astro-appcd my-astro-app
pnpm create astro my-astro-appcd my-astro-app
bun create astro my-astro-appcd my-astro-app
2. Configure Astro
Update your astro.config.mjs
to generate static files:
import { defineConfig } from 'astro/config';
export default defineConfig({ output: 'static',});
3. Initialize your project
Install the necessary dependencies and initialize your project:
npm i tsx aws-cdk-lib @thunderso/cdk-spa --save-dev
pnpm add -D tsx aws-cdk-lib @thunderso/cdk-spa
bun add -d tsx aws-cdk-lib @thunderso/cdk-spa
Create a stack/index.ts
file. Edit it to match your project:
import { App } from "aws-cdk-lib";import { SPAStack, type SPAProps } from "@thunderso/cdk-spa";
const myApp: SPAProps = { env: { account: 'your-account-id', region: 'us-east-1' }, application: 'your-application-id', service: 'your-service-id', environment: 'production',
rootDir: '', // e.g. 'frontend/' for monorepos outputDir: 'dist/',};
new SPAStack( new App(), `${myApp.application}-${myApp.service}-${myApp.environment}-stack`, myApp);
4. Deploy
Before you deploy, run your build script to generate artifacts in the dist
directory.
npm run astro check && npm run astro build
pnpm run astro check && pnpm run astro build
bun run astro check && bun run astro build
By running the following script, the CDK stack will be deployed to AWS.
npx cdk deploy --all --app="npx tsx stack/index.ts"
pnpm exec cdk deploy --all --app="pnpm exec tsx stack/index.ts"
npx cdk deploy --all --app="bunx tsx stack/index.ts"
When the deployment is complete, you will see the CloudFront URL in the output. You can access your Astro app at that URL.
For complete documentation on how to use CDK-SPA, refer to the CDK-SPA documentation.
Deploy using Thunder console
You can also deploy your Astro app on AWS using the Thunder console.
Build Settings
Use the following commands in the build step settings:
npm install
npm run astro check && npm run astro build
dist
npx pnpm install
npx pnpm run astro check && npx pnpm run astro build
dist
npx bun install
npx bun run astro check && npx bun run astro build
dist
That’s it! Your app will be live on your CloudFront URL as soon as the stack is installed.
Environment Variables
Astro allows you to define and use environment variables during the build step in a type-safe manner as a string, number, enum, or boolean using the envField helper.
Define your environment variables in the Thunder console under the Environment Variables section of your project settings.
Context: Since you’re building an SPA, set the context to client
, as these variables will be used in the browser.
Access: Use public
access for these variables. Never store secret keys or sensitive information in public variables, as they will be exposed in the browser and accessible to anyone.
Additional Properties: You can specify properties like optional or default in the object, but always ensure sensitive information is not included.
import { defineConfig, envField } from 'astro/config';
export default defineConfig({ env: { schema: { CLIENT_API_URL: envField.string({ context: "client", access: "public", default: "my-api-url" }), CLIENT_SECRET: envField.string({ context: "client", access: "public", optional: false }), } }
/** */});
To access these in your Astro components:
---import { CLIENT_API_URL, CLIENT_SECRET } from "astro:env/client";
const data = await fetch(`${CLIENT_API_URL}/api`, { headers: { Authorization: `Bearer ${CLIENT_SECRET}` }})---