コンテンツへスキップ

環境設定リファレンス(AWS)

AWS デプロイの環境(dev / prd 等)は infra/config/environments.ts で定義します (environments.example.ts をコピーして作成し、フォークがコミットします)。 設定の優先順位は CLI -c フラグ > env エントリ > スケール既定 > 組込み既定です。 ただし -c が効くのは環境エントリのフィールド(scale / dbEngine / enableOpenSearch 等)だけで、サイトスコープのフィールド(domainName / allowedIpRanges / basicAuth 等)への -c はマルチサイト環境では無視されます (1 つの -c が全サイトへ一括適用される事故の防止)。

ファイルのトップレベルには CodeConnections の接続 ARN(全 env 共通)と、 パイプラインを置く想定アカウント(任意)を export します:

export const connectionArn = 'arn:aws:codeconnections:...:connection/...'
export const pipelineAccount = '000000000000' // 任意。認証情報のアカウントとの一致を検証する

環境はマルチサイト形状(sites 宣言)で作成するのが標準です。フィールドは 「環境エントリに書くもの」(共有リソース + CI/CD)と「サイトエントリに書くもの」 (サイト固有設定)に分かれます。

本番(prd)は開発(dev)と別の AWS アカウントに分けることを推奨します(障害・権限・ 課金の分離、blast radius の局所化)。account に別 ID を指定すればアカウント境界で分離 されます。

同一アカウントでの複数環境運用もサポートします(評価・小規模・コスト優先)が、1 点だけ 注意があります: 同じコミットを dev と prd へほぼ同時にデプロイすると、両環境が共有する CDK bootstrap のイメージ用 ECR リポジトリへ同一タグを push して競合し得ます(イメージタグは ビルド内容のハッシュのため、同一コミットは同一タグになります)。この競合は一過性で、失敗した 側を再実行すれば解消します(既に push 済みのイメージはスキップされます)。恒久的に避けたい場合は、 当該 ECR リポジトリのタグを MUTABLE にするか、dev と prd のデプロイをずらして実行してください。 手順はリポジトリの docs/specs/jp/phase4-deploy.md を参照してください。

パイプラインを別アカウントに置く

Section titled “パイプラインを別アカウントに置く”

CI/CD(CodePipeline)を置くアカウントは、デプロイ先アカウントとは独立に選べます。 パイプラインはデプロイ先アカウントの bootstrap ロールを引き受けてデプロイするため、 パイプラインだけを CI/CD 専用アカウントに置き、dev / prd をそれぞれ別アカウントへ配る 構成が可能です。デプロイ先アカウントの bootstrap やコネクションの置き場所など、必要な準備は リポジトリの docs/specs/jp/phase4-deploy.md を参照してください。

トップレベルの pipelineAccount は省略できますが、分離運用では設定を推奨します。 未設定だと cdk deploy KukanPipeline を実行したときの認証情報のアカウントにパイプラインが 作られるため、たとえば prd の認証情報のまま実行すると prd 側にもう 1 本パイプラインが できてしまいます。設定しておくと、認証情報のアカウントと一致しない場合に synth が停止します。

なお別アカウント運用では、パイプラインの成果物バケットが KMS カスタマーマネージドキーで 暗号化されます(自動判定)。キー 1 本あたり月 $1 程度の費用が加わります。

共有リソース(データベース・OpenSearch・VPC・ECS クラスタ)と CI/CD の設定です。

フィールド 型 デフォルト 説明
account string 必須 対象 AWS アカウント ID。誤デプロイ防止(認証情報のアカウントと不一致なら CDK が拒否)
region string ap-northeast-1 対象リージョン
scale small | medium | large small デプロイ規模(リソースサイズを一括制御)
dbEngine rds | aurora スケール依存(small=rds、medium/large=aurora) DB エンジン
enableOpenSearch boolean true false → PostgreSQL 全文検索フォールバック
cpuArchitecture arm64 | x86_64 arm64 web と worker のタスクの CPU(既定は Graviton)。イメージもこのアーキテクチャ向けにビルドする(下記「CPU アーキテクチャ」)
rdsCaCertificate rds-ca-rsa2048-g1 | rds-ca-rsa4096-g1 | rds-ca-ecc384-g1 rds-ca-rsa2048-g1 データベースのサーバー証明書を発行する CA。web と worker はこの証明書を検証して接続する(下記「データベースの証明書」)
bedrock object | false 有効(Titan v2) セマンティック検索・AI メタデータ提案・AI による説明(抄録)。false で無効(AI_TYPE=none)。フィールドは下記「bedrock のフィールド」
githubRepo string なし CodeConnections ソースリポジトリ(owner/repo)。未設定の env はパイプライン対象外
deployBranch string main この env を pipeline でデプロイするブランチ
deployNotification boolean なし デプロイの成否を Slack に投稿する(パイプラインモードのみ)。webhook URL はスタックが作るシークレットに貼る
overrides 部分指定 なし スケール preset の個別上書き(下記「overrides」)
sites SiteConfig[] なし(過去互換のシングルサイト形状) この環境が運用するサイトの一覧。新規構築では必ず宣言する(1 件でも可)
deployConcurrency number 2 カナリア後に同時デプロイするサイト数。同時更新分の DB 接続数がバジェットに計上され、収まらなければ synth エラー
ecrImageRetention number 100 CDK bootstrap の ECR リポジトリに残すイメージ数(新しい順)。同一アカウントの環境はリポジトリを共有するため同じ値にする(違えば synth エラー)
cdnLogRetentionDays number 90 CloudFront のアクセスログを残す日数(環境内の全サイトに適用)
waf object 数えるだけ・ログ有効 共有 WebACL のレートベースルール(rateLimit.mode / limit / authLimit / exemptIpRanges)と、数えた・止めた分のログ(logging)。下記「WAF のレート制限」
enableExecuteCommand boolean false 全サイトの既定の ECS Exec。サイトの enableExecuteCommand が優先(下記「ECS Exec」)
フィールド 型 デフォルト 説明
region string デプロイ先リージョン Bedrock API のリージョン
embeddingModel string amazon.titan-embed-text-v2:0 埋め込みモデル ID。変えたら再デプロイのうえ埋め込みベクトルの再生成が要る
embeddingDimensions number アダプター既定(1024) 埋め込みの次元数
vectorMinSimilarity number モデルごとの実測推奨値 意味検索に含める類似度の下限の上書き
completionModels string[] ['jp.anthropic.claude-haiku-5-5'] タスクロールに InvokeModel を許可する生成モデル。管理画面のモデル選択肢も兼ね、先頭が AI メタデータ提案の既定。変更には再デプロイ
summaryModel string なし(AI による説明を生成しない) AI による説明(抄録)を書くモデル。completionModels に含まれないと synth エラー

web と worker のタスクは、既定で arm64(Graviton)で動きます。Fargate の料金は x86_64 より 2 割ほど安くなります。x86_64 で動かしたい環境は cpuArchitecture: 'x86_64' を指定します。 環境単位の設定で、サイトごとには変えられません。-c でも上書きできません。

  • パイプラインは、タスクと同じアーキテクチャの CodeBuild でイメージをビルドします。ARM の CodeBuild(ARM_CONTAINER)は東京・大阪にはありますが、ないリージョンにパイプラインを置くなら x86_64 を指定してください
  • standalone でデプロイするとき、手元のマシンと違うアーキテクチャのイメージも作れます。 Docker Desktop(Windows / Mac)はそのままで構いません。Docker Engine だけの Linux では、 一度だけ docker run --privileged --rm tonistiigi/binfmt --install arm64 を実行してください
  • 既存の環境の切り替えは、通常のデプロイ(タスクの入れ替え)で行われます

web と worker は、RDS / Aurora への TLS 接続でサーバーの証明書を検証します (POSTGRES_SSLMODE=verify-full)。検証に使う CA の束はイメージに入っています。 マルチサイト構成でサイトごとのデータベースを作る Lambda も、同じく証明書を検証して接続します (Lambda ランタイムに同梱の CA を使います)。

  • サーバーの証明書を発行する CA は rdsCaCertificate で固定します。指定しないと、アカウントの 既定(modify-certificates で変えられる)に従ってしまうためです。既定の rds-ca-rsa2048-g1 は全リージョンで使えます。ほかの 2 つは、ムンバイ・チューリッヒなど一部のリージョンでは使えません
  • イメージの束は、商用パーティションの全リージョン共通の束です。GovCloud・中国のリージョンは 束の配布元が別で、この束では検証できません(未対応)
  • 既存の環境で、インスタンスの今の CA が rdsCaCertificate と違うときは、デプロイで CA が 切り替わり、データベースが再起動します
  • 環境単位の設定です(データベースは環境内のサイトで共有するため)。-c では上書きできません

WAF を有効にしたサイトが共有する WebACL には、マネージドルールのほかに、閲覧者の IP ごとに 5 分間のリクエスト数を数えるルールが 2 つ入ります。全リクエスト(キャッシュされる静的 アセットは除く、既定 2000 件)と、サインイン API /api/auth/(既定 100 件)です。

waf: {
rateLimit: {
mode: 'count', // 'count'(省略時: 数えるだけ)| 'block'(429 で止める)
limit: 2000, // 全リクエストの上限(10 以上の整数)
authLimit: 100, // サインイン API の上限(10 以上の整数)
exemptIpRanges: ['203.0.113.0/24', '2001:db8::/32'], // 数えない CIDR(庁内の出口など)
},
logging: { retentionDays: 90 }, // 数えた・止めた分のログ。省略時は有効で cdnLogRetentionDays、false で無効
},
  • 既定は数えるだけ(count)です。1 つの出口の後ろに多くの人がいる組織では 1 人分の上限が 組織全体の上限になるため、まず誰が超えているかを確かめてから block にします。手順は システム管理ガイドの「WAF のレート制限」
  • ログは WebACL と同じ us-east-1 のバケット aws-waf-logs-kukan-<env>-<account>(スタック出力 WafLogBucketName)に残ります。ルールが数えた・止めたリクエストだけで、Cookie は伏せます。 全リクエストのログは CloudFront のアクセスログのほうです
  • 環境単位の設定です(WebACL は環境内のサイトで共有するため)。-c では上書きできません。 変更は global スタックの standalone デプロイで反映します(pipeline は us-east-1 を持ちません)

サイトエントリのフィールド(sites[])

Section titled “サイトエントリのフィールド(sites[])”

サイト固有の設定です。環境エントリには書けません(synth 時にエラー)。例外は bedrock / overrides / enableExecuteCommand で、環境エントリの値が全サイトの既定になり、サイトの値が その上に重なります。

フィールド 型 デフォルト 説明
name string 必須 サイトキー(^[a-z][a-z0-9]{1,15}$)。リソース名 kukan-<env>-<site>-* と DB 名 kukan_<site>
brand string default(既定ブランド brands/default) web イメージのブランド(KUKAN_BRAND)。既定値は default で、未指定と brand: 'default' は等価(既定ブランド brands/default)。それ以外を設定する場合は対応する apps/web/brands/<brand>/ が必要です(未知のブランドはイメージビルドが失敗します)
albPriority number サイト名から自動採番 共有 ALB のリスナールール優先度(ADR-049)。省略時はサイト名の安定ハッシュ(1000〜49999)。synth が衝突を報告したときだけ、追加したサイトに 1〜999 で明示する
domainName string なし カスタムドメイン(未設定時は CloudFront デフォルトドメイン)
hostedZoneId string なし Route53 Hosted Zone ID(domainName 設定時に必要)
hostedZoneName string なし Route53 Hosted Zone 名(同上)
certificateArn string standalone は自動作成 us-east-1 ACM 証明書 ARN。pipeline モードで domainName 設定時は必須
webAclArn string standalone は自動作成 us-east-1 WAF WebACL ARN(複数サイトで共有可)。pipeline モードで WAF 有効なら必須
enableWaf boolean ON(allowedIpRanges / basicAuth 設定時は OFF) CloudFront の WAF マネージドルール + レートベースルール(~$12/月)
allowedIpRanges string[] なし IP 制限(CloudFront Function、IPv4 CIDR + IPv6 対応)
basicAuth { username, password } なし Basic 認証ゲート(allowedIpRanges と OR 結合の軽量ゲート)
enableIpv6Dns boolean ON(allowedIpRanges 設定時は OFF) ドメインに AAAA のエイリアスを置き、IPv6 でも受ける。allowedIpRanges のあるサイトで ON にするのは、許可するすべての拠点の IPv6 をリストに入れてから(IPv4 で許可した端末も IPv6 で来て 403 になるため)
bucketName string 自動命名 S3 バケット名(未設定でグローバル一意な自動命名)
enableGa4DataApi boolean false GA4 アクセス統計ダッシュボード
nameSiteInUserAgent boolean false worker の User-Agent にサイトの URL を載せる(USER_AGENT_URL)。取得先のサーバー管理者が連絡できるように、誰でも閲覧でき検索エンジンに載せてよいサイトでだけ true にする。allowedIpRanges / basicAuth と同時に指定すると synth が拒否します
generatorMeta boolean true ページに <meta name="generator" content="KUKAN"> を出す(GENERATOR_META_ENABLED)。製品名だけでバージョンは出さない。false で出さない。CDN がキャッシュしたページには期限切れか invalidation まで残る(ADR-070)
officePreviewViewer string ibis-office Office 文書の原本を描くもの(OFFICE_PREVIEW_VIEWER)。ibis-office は閲覧者のブラウザの中で描く。office-online は Microsoft の Office Online Viewer
cspMode string report-only ページの Content-Security-Policy の出し方(CSP_MODE)。report-only は違反をブラウザのコンソールに出すだけで止めない。enforce は止める(ADR-071)
hstsIncludeSubDomains boolean false CloudFront が出す Strict-Transport-Security に includeSubDomains を付ける。ドメイン配下のすべてのホストを HTTPS に縛るので、そうなっているサイトだけ true にする(ADR-071)
enableExecuteCommand boolean 環境の設定(なければ false) このサイトの web と worker のタスクに ECS Exec で入れるようにする。環境エントリにも書け、そこに書いた値が全サイトの既定になる(下記「ECS Exec」)
timeZone string Asia/Tokyo 日時を事前描画するタイムゾーン(IANA 名)。ブラウザ側で閲覧者のゾーンに置き換わる
bedrock object | false 環境の設定 環境の bedrock への上書き(deep-merge、配列は置換)。false でこのサイトだけ AI 無効。環境側が bedrock: false だと synth エラー
overrides 部分指定 なし サイト所有セクションのみ(下記「overrides」)

certificateArn / webAclArn を後から外部の ARN に切り替えても、それまで 自動作成されていた証明書 / WebACL は削除されず残ります(CloudFront が参照中の リソースを削除してデプロイが失敗するのを防ぐため、RETAIN=削除時保持を付けています)。 切り替え後の後片付けは、残る managed リソースの有無で異なります:

  • 証明書・WAF の片方だけを外部 ARN にした場合(もう片方は自動作成のまま): GlobalStack は残り、切り替えた側だけがテンプレートから外れて RETAIN で 切り離されます。不要なら手動で削除してください
  • 両方(=最後の managed リソース)を外部 ARN にした場合: needsGlobalStack=false となり GlobalStack ごと合成対象から消えるため、「リソースを外す更新」は 送られず、物理 GlobalStack がリソースを管理したまま残ります。この状態で 証明書 / WebACL を直接削除するとスタックが drift します。RETAIN が保存済み であることを get-template で確認したうえで、GlobalStack を物理スタック名で 削除してください(RETAIN によりリソースはスタック削除後も残ります)。その後、 本当に不要なら証明書 / WebACL を手動削除します(WebACL は残っている間も課金)

この RETAIN 保持ポリシーは「リソースがテンプレートに存在する状態でのデプロイ」で 初めて CloudFormation に保存されます。そのため、RETAIN に対応していない古い バージョンからアップグレードしつつ同じデプロイで ARN 切替まで行うと、リソースが 旧ポリシー(削除)のまま除去され、CloudFront が参照中だとデプロイが失敗します。 既存環境では次の二段階で行ってください(最新版で新規作成した環境は初回から RETAIN が付くため、一度のデプロイで切り替えられます):

  1. まず最新版をデプロイして GlobalStack に RETAIN を保存する。反映されたことを aws cloudformation get-template(us-east-1)で確認する — 証明書 / WebACL に DeletionPolicy: Retain が付いていれば OK
  2. その後、別のデプロイで ARN を切り替える

aws ecs execute-command で web と worker のコンテナにシェルで入る機能は、既定で off です。 調査するサイトのエントリに enableExecuteCommand: true を書いてデプロイします。

  • サイト単位の設定で、そのサイトの web と worker の両方に効きます。ECS Exec 用の権限が付くのも、 そのサイトのタスクロールだけです
  • 環境エントリに書くと、その値が全サイトの既定になります。サイトのエントリに書いた値が優先します。 sites のないシングルサイト形状では、環境エントリに書きます
  • -c では上書きできません(パイプラインは -c を見ないため、on のサイトは設定ファイルに残します)
  • デプロイで変わるのはサービスの設定とタスクロールの権限だけで、タスク定義は変わらないため、 タスクは入れ替わりません。ECS Exec を使えるかはタスクの起動時に決まります
    • on にしたとき: デプロイ後に起動したタスクから入れます。すぐに使うときは aws ecs update-service --cluster <クラスタ> --service <サービス> --force-new-deployment でタスクを入れ替えます(次のイメージのデプロイを待ってもかまいません)
    • off にしたとき: タスクロールから ECS Exec 用の権限が外れるので、新しいセッションは開けなくなります
  • コンテナに入ると、環境変数に注入された秘密の値も読めます
  • 「誰が、いつ、どのタスクに入ったか」は、CloudTrail のイベント履歴(管理イベントの ExecuteCommand、90 日)で追えます。セッションの中の入出力は記録しません

スケール preset の個別上書きです。適用順は スケール既定 ← env の overrides ← サイトの overrides の deep-merge で、書ける範囲がレベルごとに異なります。

  • 環境エントリ: 全セクション(web / worker / db / opensearch / dbPool / backup)。共有リソースのサイズと DB 保持期間・AWS Backup スケジュールは環境レベルでのみ設定できます
  • サイトエントリ: サイト所有分のみ(web / worker(healthPort を除く)/ dbPool と、 backup のうち S3 バージョニング関連)。db / opensearch / backup.awsBackup / backup.dbBackupRetentionDays の上書きは synth 時に 拒否されます

スケール別のデフォルト値はリポジトリの docs/specs/jp/phase4-deploy.md 「スケール別デフォルト値」を参照してください。

サイトエントリのフィールドのうち name / brand / albPriority を除くものは、sites を 宣言しない環境に限り env 直下にも書けます。これは sites 導入前の シングルサイト形状(全部入り単一スタック)との過去互換で、デプロイ済みの 既存環境のために残されています。

  • 新規構築ではこの形状は使わず、サイトが 1 つでも sites 1 件で作成してください
  • 両形状の混在(sites + env 直下のサイトフィールド)は synth 時に拒否されます (bedrock / overrides / enableExecuteCommand は除く。上記の例外)
  • デプロイ済みのシングルサイト形状の環境に sites を後付けすることはできません (リソース置換が発生するため。移行はマルチサイト運用 のブルーグリーン手順を参照)