SST × お名前.comのAWSフロントエンド環境構築(Basic認証付き)
はじめに
こんにちは、株式会社ゼンビット所属のゆうとです。
IaCの選択肢のひとつとしてSSTというものを知りました。
Basic認証と、ドメイン設定を行いつつ、爆速でNext.jsをデプロイしていきます!!
対象読者
- なるべく早くAWS環境構築を進めたい人
- SST興味を持っている方
- 説明する内容:
- SSTのデプロイ
- 認証導入
- お名前.comのドメイン設定
- 説明しない内容:
- Next.jsのアプリ開発部分
- AWS認証、GitHub ActionsやSSTに関する説明
背景
もともと Next.js + CDKTF で AWS インフラ構築を進めていたプロジェクトについて、
- 構成がだんだん複雑化してメンテしづらい。
- 小規模なのにIAMなどの複雑化が煩わしい。
といった課題がありました。
そこで「SST を使った構成ならシンプルになるのでは?」と社内で提案を受けました。
調べてみたところかなりシンプルにまとまりそうだったため、検証してみます。
本題
構成など
- Node.js v20
- pnpm v8 系
- Next.js v15(standalone output mode) フロントエンド
- SST (v3.x)
まずは通常の環境構築
まずは自分のプロジェクトにSST公式のモノレポひな形を取得します。
自分のプロジェクト配下に所定のリポジトリをクローン
git clone https://github.com/sst/monorepo-template.git
公式記載の通りアプリの名前を変更
npx replace-in-file /monorepo-template/g trainings **/*.* --verbose
npmインストールして
npm install
生成されたsst.config.tsを更新する
/// <reference path="./.sst/platform/config.d.ts" />
export default $config({
app(input) {
return {
name: "trainings",
removal: input?.stage === "production" ? "retain" : "remove",
protect: ["production"].includes(input?.stage),
home: "aws",
};
},
async run() {
- const storage = await import("./infra/storage");
- await import("./infra/api");
+ const stage = $app.stage;
+ const site = new sst.aws.Nextjs(`${stage}-site`,{
+ path: "apps/web" // Next.js プロジェクトのパス
+ });
return {
- MyBucket: storage.bucket.name,
+ site: site.url,
};
},
});
Basic認証を設定
SST公式でBasicAuthで検索。
sst.Secretの利用を推奨されている。
本プロジェクトのデプロイはGitHub Actions。
sst.Secretを使わず、GitHubのsecretsをenv設定すれば問題ないかと判断しました。
どなたかsst.Secretの魅力教えてください。
公式にある通りBasic認証を追記。
/// <reference path="./.sst/platform/config.d.ts" />
export default $config({
app(input) {
return {
name: "trainings",
removal: input?.stage === "production" ? "retain" : "remove",
protect: ["production"].includes(input?.stage),
home: "aws",
};
},
async run() {
const stage = $app.stage;
+ const isProduction = stage === "production";
+ const username = process.env.BASIC_AUTH_USER;
+ const password = process.env.BASIC_AUTH_PASS;
+ const basicAuth = $resolve([username, password]).apply(
+ ([username, password]) =>
+ Buffer.from(`${username}:${password}`).toString("base64")
+ );
const site = new sst.aws.Nextjs(`${stage}-site`,{
path: "apps/web", // Next.js プロジェクトのパス
+ edge: !isProduction
+ ? {
+ viewerRequest: {
+ injection: $interpolate`
+ if (
+ !event.request.headers.authorization
+ || event.request.headers.authorization.value !== "Basic ${basicAuth}"
+ ) {
+ return {
+ statusCode: 401,
+ headers: {
+ "www-authenticate": { value: "Basic" }
+ }
+ };
+ }`,
+ },
+ }
+ : undefined,
});
return {
site: site.url,
};
},
});
envを設定
BASIC_AUTH_USER=trainings
BASIC_AUTH_PASS=tests
AWS認証して
aws sso login --profile XXXXX
デプロイ
sst deploy --stage staging
追加できた。
ドメイン設定
SST公式でDomainで検索。
ACM証明書やdns設定はRoute 53、Cloudflare、Vercel のみサポートみたいですね。
仕方なしなのでACM証明書を作成⇒お名前.com側のDNSレコード設定を手動で行います。
まずはAWSコンソール画面からACM作成しました。
ARNは設定必要なので控えときます。
お名前.com側でACM証明書のドメインに応じたDNSレコード作成。
ついでにドメインからCloudFront発行の配信URLに転送するDNSレコードも作成しまいます。
公式にある通りドメイン設定を追記。
/// <reference path="./.sst/platform/config.d.ts" />
export default $config({
app(input) {
return {
name: "trainings",
removal: input?.stage === "production" ? "retain" : "remove",
protect: ["production"].includes(input?.stage),
home: "aws",
};
},
async run() {
const stage = $app.stage; // 環境分けたいのでstageを設定
const isProduction = stage === "production";
const username = process.env.BASIC_AUTH_USER;
const password = process.env.BASIC_AUTH_PASS;
+ const domainName = process.env.DOMAIN_NAME;
+ const certificateArn = process.env.CERTIFICATE_ARN;
const basicAuth = $resolve([username, password]).apply(
([username, password]) =>
Buffer.from(`${username}:${password}`).toString("base64")
);
const site = new sst.aws.Nextjs(`${stage}-site`,{
path: "apps/web", // Next.js プロジェクトのパス
edge: !isProduction
? {
viewerRequest: {
injection: $interpolate`
if (
!event.request.headers.authorization
|| event.request.headers.authorization.value !== "Basic ${basicAuth}"
) {
return {
statusCode: 401,
headers: {
"www-authenticate": { value: "Basic" }
}
};
}`,
},
}
: undefined,
+ domain:
+ domainName && certificateArn ?
+ { name:domainName,
+ dns: false,
+ cert: certificateArn
+ } : undefined,
});
return {
site: site.url,
};
},
});
envも更新して
BASIC_AUTH_USER=trainings
BASIC_AUTH_PASS=tests
DOMAIN_NAME=www.XXXXXX.com
CERTIFICATE_ARN=arn:aws:acm:us-east-1:XXXXXXX:certificate/XXXXXXXXXXXXXXXX
デプロイ
sst deploy --stage staging
デプロイ成功!
outputの部分が重複しているので、不要ですね。。。
結論・まとめ
結果
- とんでもない速さとシンプルな構成でデプロイできました。
更新したファイルは「sst.config.ts」のみ。
課題
- ACM 証明書の作成は手作業が必要でした。
→ ここだけAWS CDKで作成するか、サポート対象のDNSを使うのが現実的かもしれません。 - 細かい設定はプロパティ不足でハマりやすく、調整が難しい部分があります。
全体を通しての感想
- とにかく素早く環境構築したい人には SST はかなりおすすめ!
Discussion