AKS 上のクラウドデリバリー
概要
Kubernetes/Azure 向けのデリバリーメカニズムです。AKS 上でデプロイの安全性と検証ゲートを実装します。スタック固有の設計:このスキルは k8s/AKS に関わるタスクでのみ読み込まれるため、クラウドデプロイを使用しないプロジェクト(ローカル専用の Docker Compose など)ではこの内容は表示されません。
デリバリールール
- ローカル開発はフルスタックを Docker Compose で一つのコマンドで実行します。包括的であることが第一級の要件です。
- イメージは CI でビルド → GHCR にコンテンツダイジェストで格納され、プレビュー → ステージング → 本番で変更されずプロモーションされます。環境ごとに再ビルドは行いません。
- PR ごとのエフェメラルプレビュー環境。 各 PR はレビュー用に AKS 上の独立した名前空間にデプロイされ、マージまたはクローズ時に破棄されます。統合テストの場であり、作成と破棄が低コストです。
- Kubernetes ヘルスゲーティング。 すべてのワークロードは liveness、readiness、startup プローブ(
observability-and-slosのエンドポイントに配線)、maxUnavailable/maxSurgeを制限したローリングアップデート戦略、および PodDisruptionBudget を定義します。負荷に応じて HPA を使用します。 - 本番環境への段階的デリバリー。 Argo Rollouts / Flagger によるカナリアまたはブルーグリーンデプロイを、SLO に連動した自動メトリクス分析とともに行います。失敗したカナリアは自動的に中断されます。
- ロールバックは第一級で事前に練習します。 不変でダイジェスト指定されたイメージにより、ロールバックは以前の正常なダイジェストを再デプロイするだけです(
kubectl rollout undo/ ロールアウトの中断)。リスクのある変更をリリースする前に検証します。 - マイグレーションは独立した順序付けられたパイプラインステップとし、拡張安全(
zero-downtime-migrations参照)にし、依存するコードの前に実行します。新しいスキーマを必要とする Pod にバンドルすることは決してありません。 - CI がゲート: lint、型チェック、コントラクトチェック、テスト、セキュリティスキャンをすべての変更に対して実行し、
enforcedモードではマージをブロックします。CI はイメージをビルドし、その来歴証明を公開し、そのダイジェストを変更せずにプロモーションします。 - 開発/本番のパリティと環境からの設定。 Azure Key Vault からのシークレット(Secrets Store CSI ドライバーまたは sealed secrets 経由)— イメージやコミット済み
.envには決して含めません。ポート/設定は環境変数から取得します。開発専用ツール(pgTAP、テストランナー)は本番イメージには決して含めません。
パイプライン
| 層 | トリガー | 環境 | ダイジェスト |
|---|---|---|---|
| preview | PR 作成 / 同期 | エフェメラル名前空間 preview-<app>-pr-<N> | ここでビルド、sha-<pr-head> でタグ付け |
| staging | main へのマージ | 永続名前空間 staging | preview ダイジェストを sha-<merge> として再タグ付け |
| production | リリース公開 + 承認 | 名前空間 production | リリースコミットの親のダイジェスト |
なぜ親コミットか。 release-please のリリースコミットは CHANGELOG.md とマニフェストのみを変更するため、そのツリーはステージングで浸されたものではありません。リリース PR 自体のためにプレビューでビルドされたものは、プレビューを超えてプロモーションされることはありません。その親は最後の機能マージであり、release-please がリリースブランチを main の先端に保つ限り(デフォルトの動作)、ステージングが検証してきたものと正確に一致します。ライブクラスターの状態ではなく git からダイジェストを導出することで、プロモーションを再現可能に保ちます。
再タグ付けの安全性。 スカッシュマージは異なるコミット SHA を生成し、PR がオープン中に main が進んでいた場合は異なるツリーを生成します。二つの防御策:
- 「マージ前にブランチを最新にする」 を必須とします。これは必須ステータスチェックルールの一部であり、スカッシュツリーが PR ヘッドツリーと構造的に一致することを保証します。この防御策はブランチ保護が必要なため、
enforcedモードでのみ存在します。advisoryモードのプロジェクトは、以下のツリー比較を唯一の防御策とし、再ビルドパスが例外的ではなく日常的に発生することを想定する必要があります。 - 仮定せずに検証:
git rev-parse <merge>^{tree}と PR ヘッドツリーを比較します。等しい → 再タグ付け。異なる → マージ SHA で再ビルド。これはデリバリールールが禁止する環境ごとの再ビルドではありません。ツリーが異なるということは、コンテンツ自体がプレビューで検証されたものと異なることを意味するため、プロモーション可能なアーティファクトは存在せず、再ビルドされたイメージはプロモーションではなく新しい候補としてステージングに入ります。このパスを取った場合に失われるものに注意してください。そのイメージはプレビュー環境でレビューされたことがないため、「出荷されたイメージはレビューされたイメージである」という原則は成立しません。ステージングはそのイメージにとって初めての検証環境となり、二度目の検証ではありません。
再タグ付けはポインタ操作であり、再ビルドもプルも行いません。
docker buildx imagetools create -t "$REPO:sha-$MERGE_SHA" "$REPO@sha256:$DIGEST"
来歴証明は PR ヘッド SHA にバインドされたままのため、ヘッド→マージのマッピングをデプロイメント記録に記録します。イメージ設定は再ビルドなしでは編集できません。
承認ゲート — 1 つのプロパティ、2 つのメカニズム:
| モード | メカニズム |
|---|---|
enforced | GitHub Environment production、必須レビューア |
advisory | workflow_dispatch プロモーションジョブ。実行すること自体が意思決定 |
クイックリファレンス
| 対象 | メカニズム |
|---|---|
| シークレット | Key Vault → CSI ドライバー、ローテーション、イメージに含めない |
| ヘルスチェック | liveness + readiness + startup プローブ。readiness は実際の依存関係をチェック |
| 安全なロールアウト | カナリア/ブルーグリーン、SLO ゲート、失敗時に自動中断 |
| ロールバック | 以前の正常なダイジェストを再デプロイ。リスクのあるリリース前に練習 |
| PR ごとの環境 | 隔離された名前空間、マージ時に破棄 |
| スキーママイグレーション | 独立した順序付けられたステップ、拡張安全、コードの前に実行 |
| プロモーション | ダイジェストを再タグ付け、環境ごとに再ビルドしない |
| 承認 | 環境レビューア(enforced)または手動ディスパッチ(advisory) |
なぜ分離されているか: Azure/k8s 固有の詳細はすべてスタック固有のトリガーの背後にあります。ローカル専用や別のクラウドのプロジェクトは、独自のデリバリースキルに置き換えます。原則(不変アーティファクト、リバーシブルかつ段階的なデプロイ、疎結合なマイグレーション)は resilience-and-deploy-safety に由来します。
完全な根拠は、憲法第 XIX 条「engineering-constitution/references/engineering-constitution.md」にバンドルされています。