generated from amazon-archives/__template_MIT-0
-
Notifications
You must be signed in to change notification settings - Fork 38
Open
Labels
enhancementNew feature or requestNew feature or request
Milestone
Description
背景
現在の環境変数管理に以下の問題がある:
- typo・未設定の検出が遅い:
process.env.XXX!の直接参照が6ファイルに散在しており、typoや未設定を実行時まで検出できない - CDK Outputsの手動コピーが必要:
cdk deploy後にCLI出力から値を手動で.env.localにコピーする必要がある(README参照) .env.local.exampleが不完全: 現在のexampleファイルにはプレースホルダー値(dummy,"")が入っているが、どのCDK Outputに対応するかのコメントがない
提案
1. src/lib/env.ts — Zodバリデーション
環境変数をZodスキーマで一元管理し、トップレベルでバリデーションする。
// src/lib/env.ts
import { z } from "zod";
const envSchema = z.object({
// Cognito認証
COGNITO_DOMAIN: z.string().min(1),
USER_POOL_ID: z.string().min(1),
USER_POOL_CLIENT_ID: z.string().min(1),
// カスタムドメインありの場合は直接設定、なしの場合はSSMパラメータ経由で動的取得
AMPLIFY_APP_ORIGIN: z.string().min(1).optional(),
// AppSync Events
NEXT_PUBLIC_EVENT_HTTP_ENDPOINT: z.string().url(),
NEXT_PUBLIC_AWS_REGION: z.string().min(1),
// 非同期ジョブ
ASYNC_JOB_HANDLER_ARN: z.string().min(1),
});
export const env = envSchema.parse(process.env);各ファイルでは process.env の代わりに env.USER_POOL_ID のように参照する。
設計上の注意点:
- トップレベルparse: モジュール読み込み時にバリデーションが走る。Next.jsが
.env.localを読み込んだ後に実行されるため問題ない AMPLIFY_APP_ORIGINは.optional(): カスタムドメインなしの場合、Lambda実行環境ではSSMパラメータから動的取得するため、デプロイ時点では未設定- Lambda注入変数は含めない:
DATABASE_URL,EVENT_HTTP_ENDPOINT,AWS_REGION等はCDKがLambda環境変数として注入するため、ローカル開発用のenv.tsのスコープ外。DATABASE_URLはPrismaがprisma/.envから読み込む
2. ESLint no-restricted-syntax で process.env 直接参照を禁止
// eslint.config.mjs に追加
{
rules: {
"no-restricted-syntax": [
"error",
{
selector: "MemberExpression[object.object.name='process'][object.property.name='env']",
message: "process.env の直接参照は禁止です。src/lib/env.ts の env を使用してください。",
},
],
},
},
// 除外ファイル
{
files: ["src/lib/env.ts", "src/lib/amplifyServerUtils.ts", "next.config.ts"],
rules: { "no-restricted-syntax": "off" },
},
{
files: ["tests/**/*.ts", "**/*.test.ts"],
rules: { "no-restricted-syntax": "off" },
},amplifyServerUtils.tsはAmplify SDKの初期化でAMPLIFY_APP_ORIGIN_SOURCE_PARAMETERからSSM経由の動的取得を行う特殊なファイルのため除外。テストファイルも除外する。
3. scripts/sync-env.mjs — CDK Outputsから .env.local を自動生成
bashスクリプトではなくNode.jsスクリプトとする。理由:
- Node.js >= v20 はデプロイの前提条件に既にある(追加依存なし)
- Windows環境でも動作する(WSL/Git Bash不要)
jqへの依存が不要(JSON.parseで済む)
#!/usr/bin/env node
// scripts/sync-env.mjs
import { execSync } from "child_process";
import { writeFileSync } from "fs";
const stackName = "ServerlessWebappStarterKitStack";
const outputs = JSON.parse(
execSync(
`aws cloudformation describe-stacks --stack-name ${stackName} --query "Stacks[0].Outputs" --output json`,
).toString(),
);
const get = (prefix) =>
outputs.find((o) => o.OutputKey.startsWith(prefix))?.OutputValue ?? "";
const region = execSync("aws configure get region").toString().trim();
writeFileSync(
"webapp/.env.local",
`# DO NOT EDIT — generated by scripts/sync-env.mjs
COGNITO_DOMAIN=${get("AuthUserPoolDomainName")}
USER_POOL_ID=${get("AuthUserPoolId")}
USER_POOL_CLIENT_ID=${get("AuthUserPoolClientId")}
AMPLIFY_APP_ORIGIN=http://localhost:3010
NEXT_PUBLIC_EVENT_HTTP_ENDPOINT=${get("EventBusHttpEndpoint")}
NEXT_PUBLIC_AWS_REGION=${region}
ASYNC_JOB_HANDLER_ARN=${get("AsyncJobHandlerArn")}
`,
);CfnOutputのキーにはCDKが付与するハッシュサフィックス(例: AuthUserPoolIdC0605E59)があるため、startsWithで前方一致検索する。
4. .env.local.example の拡充
# CDK Outputsから取得(scripts/sync-env.mjs で自動生成可能)
COGNITO_DOMAIN= # CfnOutput: AuthUserPoolDomainName
USER_POOL_ID= # CfnOutput: AuthUserPoolId
USER_POOL_CLIENT_ID= # CfnOutput: AuthUserPoolClientId
NEXT_PUBLIC_EVENT_HTTP_ENDPOINT= # CfnOutput: EventBusHttpEndpoint
NEXT_PUBLIC_AWS_REGION=us-west-2
ASYNC_JOB_HANDLER_ARN= # CfnOutput: AsyncJobHandlerArn
# ローカル開発用(固定値)
AMPLIFY_APP_ORIGIN=http://localhost:3010
現在の process.env 直接参照箇所
| ファイル | 環境変数 |
|---|---|
src/lib/amplifyServerUtils.ts |
AMPLIFY_APP_ORIGIN, USER_POOL_ID, USER_POOL_CLIENT_ID, COGNITO_DOMAIN, AMPLIFY_APP_ORIGIN_SOURCE_PARAMETER |
src/hooks/use-event-bus.ts |
NEXT_PUBLIC_EVENT_HTTP_ENDPOINT, NEXT_PUBLIC_AWS_REGION |
src/lib/events.ts |
EVENT_HTTP_ENDPOINT, AWS_REGION |
src/lib/jobs.ts |
ASYNC_JOB_HANDLER_ARN |
src/lib/prisma.ts |
DATABASE_URL, NODE_ENV |
src/jobs/async-job/translate.ts |
AWS_REGION |
注: amplifyServerUtils.tsはESLint除外対象のため、process.env参照を維持する。それ以外のファイルはenv.ts経由に移行する。EVENT_HTTP_ENDPOINT, AWS_REGION, DATABASE_URL, NODE_ENVはLambda実行環境でCDKが注入する変数であり、ローカル開発時には使用しないためenv.tsのスキーマには含めない。
検証方法
-
scripts/sync-env.mjsでCDK Outputsからwebapp/.env.localが自動生成される - 環境変数の不足・型不正がアプリ起動時にZodエラーとして検出される
-
process.envの直接参照がESLintエラーになる(除外ファイル以外)
備考
- pnpm workspaces化(pnpm workspaces でモノレポ化 #98)後に実装する前提。モノレポ構成ではスクリプトの配置場所や
.env.localのパスが変わる可能性がある
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request