Astro×SSTでAWSにさくっとデプロイ
こんにちは!
satto workspaceでエンジニアをしている伊藤(@ryo_ito)です。
TL;DR
はじめに
Astroは「ゼロJS前提×アイランドアーキテクチャ」で、軽くて速いサイトを作れます。SSTは、そのAstroをAWSに迷わず載せるための道具です。
本記事は「最短でデプロイする方法」と「SST採用のメリット/デメリット」を、できるだけ短くまとめます。詳しくはサンプルと参考リンクをご覧ください。
対象読者 / 前提
- Astroの基本操作(作成/ビルド)を理解している
- AWS(S3/CloudFront/IAM)の基礎概念を把握している
- パッケージマネージャは
npm
想定(pnpm
/yarn
でも可) - SST v3を使用する人(v2は触れません)
用語メモ(さっと確認)
- アイランドアーキテクチャ:必要なUIのみをクライアントでハイドレーション
- CWV:Core Web Vitals(特にLCP/INP)
なぜAstro×SSTか
AstroとSSTを組み合わせる「なぜ」を理解するために、両者のコンセプトを押さえます。
Astroのコンセプト(アイランドアーキテクチャ/CWV)
Astroの中核は「デフォルトでゼロJavaScript」。ページの大半は静的HTMLとして配信し、必要なUIのみを「島(アイランド)」として個別ハイドレーションします。
- コード送信量が減り、Core Web Vitals(LCP/INP)が大幅改善
- SEO・直帰率・CVRなどビジネス指標の改善に直結
- React/Vue/Svelteなど複数UIフレームワークを併用可能
SSTの進化(CDK/CFn→Pulumi/Terraform)
従来のSST v2はCDK/CloudFormationを基盤としていましたが、v3はPulumi/Terraformへ移行。CFnの制約(上限・速度・ロールバック)を回避し、より堅牢でDXに優れたモデルへ進化しました。
SSTのコンセプト
- Live:変更がミリ秒で反映される開発体験。ブレークポイントも利用可。
SST_DEV
でローカルのサービス/データに切替え可能。(docs) - State:設定・状態・クラウドのズレを自動でそろえる仕組み。必要に応じて
sst refresh
で実態と同期。(docs) - Linking:
link
で接続情報やIAM権限を型安全にアプリへ注入。コードからはimport { Resource } from "sst"
で参照。(docs) - Console:ステージ/スタックを見える化。ログ閲覧・関数実行・環境変数/シークレット管理ができる。(docs)
- Providers:AWSやCloudflareなどを共通の書き方で扱える抽象化。マルチクラウドや将来の拡張に強い。(docs)
- Components:
Function
/Api
/Bucket
/Dynamo
/Auth
などの高レベル部品で、必要最小の記述で構成できる。(docs)
クイック手順(最短でSSTデプロイ)
- Astro作成:
npm create astro@latest your-project-name
- 依存導入:
cd your-project-name && npm install
- SST初期化:
npx sst@latest init
(awsを選択→home: "aws"
が自動設定) - SSGなら:
sst.config.ts
にnew sst.aws.StaticSite("Web", {})
を追加 - SSRなら:
npx astro add astro-sst
→sst.config.ts
にnew sst.aws.Astro("WebSsr", {})
を追加 - 独自ドメインを使うなら:
domain: "example.com"
を設定 - デプロイ:
npx sst deploy
(プレビューでURL確認)
実装ガイド(SST × Astro)
Astroのセットアップ
- コマンド
# 'your-project-name' という名前でAstroプロジェクトを作成
npm create astro@latest your-project-name
# 依存インストールと動作確認
cd your-project-name
npm install
npm run dev
- ディレクトリ構成
your-project-name/
├── public/
├── src/
│ └── pages/
├── .sst/ # sst init 後に生成
├── astro.config.mjs
├── package.json
└── sst.config.ts # sst init 後に生成(インフラ定義)
-
説明
-
public/
は静的アセット、src/pages/
はルーティングの基点である。 -
sst init
後に.sst/
とsst.config.ts
が追加され、アプリとインフラ定義が同一プロジェクトに共存する。
-
SSTのセットアップ
- コマンド
# プロジェクトルートでSSTを初期化
npx sst@latest init
-
説明
-
sst init
でsst.config.ts
と.sst/
が生成され、home: "aws"
が設定される(awsを選択した場合)。 - 追加のプロバイダ導入コマンドは不要で、
sst.aws.*
コンポーネントが利用可能になる。
-
上記コマンド実行後にできる実際のフォルダ構成
SSTのコード
sst.config.ts
の最小例
/// <reference path="./.sst/platform/config.d.ts" />
export default $config({
app(input) {
return {
name: "astro-on-aws",
removal: input?.stage === "production" ? "retain" : "remove",
home: "aws",
};
},
async run() {
// --- SSG(静的サイト: S3 + CloudFront) ---
new sst.aws.StaticSite("Web", {
// path は省略可(デフォルトはカレントディレクトリ)
build: {
command: "npm run build",
output: "dist",
}
domain: "ssg.com",
});
// --- SSR(必要になったら有効化): CloudFront + Lambda + S3 ---
// 事前に `npx astro add astro-sst` を実行してください。
new sst.aws.Astro("WebSsr", {
// path は省略可(デフォルトはカレントディレクトリ)
// buildCommandは、Default “npm run build”。省略可。
domain: "ssr.com",
});
},
});
-
説明
- SSGはビルド成果物(
dist/
)をS3へ配信し、CloudFront経由でCDN配信する。 - SSRはCloudFrontのオリジンでLambdaを実行し、Astroのサーバーサイドレンダリングを提供する。
- SSGはビルド成果物(
-
出来上がるインフラ構成図
SSG(StaticSite):
SSR(Astro):
デプロイ方法(2段階:まずはローカル → 次に GitHub Actions + OIDC)
まずはローカルで最短デプロイして手応えを得てから、実践編としてGitHub Actions + OIDCによる安全な本番運用フローへ移行します。
- ステップ1:ローカルでサクッとデプロイ
# リポジトリ直下
npm install
npx sst deploy
- 実行後、SSTが
sst.config.ts
を読み取り、SSG/SSRに応じて自動構築し、アクセスURLが表示される。
- ステップ2:実践編 GitHub Actions + OIDC
このステップでは、GitHub ActionsとOIDC(OpenID Connect)を使用して、Astroで作成されたアプリをSSTでAWSに安全に継続デプロイします。管理者権限は避け、最小権限の原則に沿ってIAMロールを設計します。
-
OIDC用IAMロール作成(概要)
- GitHub OIDCと信頼関係を持つロールを作成(
main
とv*
タグに限定) - CloudFormation / S3 / CloudFront / Lambda への必要最小権限を付与
- 既存環境がある場合はロールを分離し、影響範囲を最小化して段階適用
- GitHub OIDCと信頼関係を持つロールを作成(
-
GitHub Secretsにロール情報を登録
# gh CLIを使用
gh secret set AWS_ROLE_ARN --body "arn:aws:iam::${AWS_ACCOUNT_ID}:role/${ROLE_NAME}"
gh secret set AWS_REGION --body "${REGION}"
- ワークフロー例(
.github/workflows/deploy.yml
)
name: Deploy (SST)
on:
push:
branches:
- main
tags:
- 'v*'
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
env:
SST_TELEMETRY_DISABLED: "1"
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- name: Install dependencies
run: npm ci
- name: Configure AWS credentials (OIDC)
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Deploy to Production
run: npx sst deploy --stage prod
-
説明
-
configure-aws-credentials
より作成したOIDC用IAMロールから一時的な認証情報を取得し、workflowがAWSリソースへアクセスできるようになる。 -
npx sst deploy
はsst.config.ts
を読み、定義どおりにAWSリソースを作成・更新する。
-
高度なトピックと戦略的トレードオフ
パフォーマンス:コールドスタート対策とキャッシュ戦略
- Provisioned Concurrency:超低レイテンシが必要な場面で有効(コスト増と引き換え)
- ウォーミング:低コストで一定のウォーム状態を維持
- キャッシュ:SSGはCDNキャッシュがデフォルト、SSRは
Cache-Control
でCloudFront制御
new sst.aws.Astro("AstroWeb", {
path: "apps/your-project",
// パフォーマンス最適化設定
server: {
concurrency: {
provisioned: 5, // コールドスタート対策
},
},
warm: 5, // ウォーミング設定
// キャッシュ設定
invalidation: {
paths: ["/*"],
},
});
シークレット管理
.env
のコミットは厳禁。sst.Secret
で安全に管理し、link
で注入します。
// シークレット定義
const databaseUrl = new sst.Secret("DATABASE_URL");
const apiKey = new sst.Secret("API_KEY");
// アプリにリンク
new sst.aws.Astro("AstroWeb", {
link: [databaseUrl, apiKey]
});
CLIで値を設定。
npx sst secret set DATABASE_URL <your-database-url> --stage dev
npx sst secret set API_KEY <your-api-key> --stage dev
サーバーサイドから参照。
import { Resource } from "sst";
const databaseUrl = Resource.DATABASE_URL.value;
const apiKey = Resource.API_KEY.value;
おわりに
最後まで読んでいただきありがとうございます!
まずは「最小構成→即デプロイ」で体験してみてください。
VercelやCloudflareと同じ感覚でサクッとデプロイできます。
- 最小構成:
StaticSite
(SSG)orAstro
(SSR)を1つだけ定義 - 開発:
sst dev
でLiveを活用(Webhook検証やブレークポイントを即時に利用可能) - 秘密情報:
sst.Secret
をlink
して、アプリはResource
から参照
Discussion
ありがとうございます!
参考になりました!