HARDENED S(MUTABLE:現行互換)から IMMUTABLEへ
| 観点 | HARDENED S(MUTABLE:現行互換) | HARDENED 最終形(IMMUTABLE:本番💯) | 補足(運用の考え方) |
|---|---|---|---|
| ①何が違う?(機能差) | – ScanOnPush: true(push時スキャン)- LifecyclePolicy(untagged自動削除)- Encryption: AES256– ImageTagMutability: MUTABLE(タグ上書き可) | – Step-Aの全てに加えて- ImageTagMutability: IMMUTABLE(タグ上書き禁止) | 2つの差はほぼ 「タグ上書きを許すか禁止するか」 です(スキャン/掃除/暗号化は両方に入れられる) |
| ②メリット | – 既存の latest/prod 上書き運用でも止まりにくい- スキャン導入で脆弱性把握が進む- untagged(-)が溜まり続けるのを自動掃除できる | – タグすり替え事故を構造的に防止(同じタグで再push不可)- “本番で動いたイメージ”の追跡が強い(再現性/監査)- ロールバックが明確(前のタグへ戻すだけ) | IMMUTABLEは ユニークタグ運用(Git SHA / releaseタグ)とセットで真価が出ます |
| ②デメリット | – 固定タグ(latest/prod)が上書き可能=すり替え事故が起き得る(例:誤って古いイメージを prod でpush) | – latest/prod を上書きしていると 次回pushが失敗しやすい- ユニークタグでイメージが増えるので LifecyclePolicy が必須 | あなたのECR画面(latest + -)は「付け替え運用」なので、いきなりIMMUTABLEは危険寄り |
| ③環境別:dev | ✅ Step-AでOK(止めずに導入)(余裕があればユニークタグ移行の練習台) | ◯ CI/CD整っていればIMMUTABLEでも良い | UntaggedExpireDays 推奨:7日 |
| ③環境別:stg | ✅ Step-AでもOK(ただし本番に寄せるならユニークタグ移行推奨) | ✅ おすすめ(本番前の最終リハに最適) | UntaggedExpireDays 推奨:14日 |
| ③環境別:demo | ✅ 動けばOKならStep-A | ◯ 本番同等検証したいならIMMUTABLE | UntaggedExpireDays 推奨:7〜14日 |
| ③環境別:prod | ✅ まずStep-Aが安全(互換維持しつつ強化) | ✅ 最終的にこれ(本番💯) | 本番は段階導入が安全:Step-A → ユニークタグ化 → IMMUTABLE |
| ④ユニークタグ設計例(IMMUTABLEでも困らない) | – git-<短縮SHA>(例:git-a1b2c3d)- release-YYYYMMDD-n(例:release-20260224-1) | 同左(※必須に近い) | ECSは :latest 参照をやめ、ユニークタグ(またはdigest)を参照する |
| ⑤迷ったときの最終判断ルール | 「いま latest/prod を上書きしてる」→ ✅ Step-A | 「ユニークタグ運用ができてる」→ ✅ IMMUTABLE | 超短縮:上書き運用中はStep-A、ユニークタグ化できたらIMMUTABLE |
現状(ECRに latest が存在し、-=untagged が溜まっている=latest付け替え運用)を前提に、**本番を止めずに Step-A(MUTABLE)→ ユニークタグ運用 → IMMUTABLE(最終形)**へ移行する手順書
手順書:ECRタグ運用を「latest付け替え」→「ユニークタグ」→「IMMUTABLE」へ移行(本番停止なし)
ゴール
- まず Step-A(ScanOnPush + Lifecycle + MUTABLE)を本番に適用して安全強化
- 次に **ユニークタグ運用(Git SHA / releaseタグ)**へ移行
- 最後に IMMUTABLEを有効化して “タグすり替え事故ゼロ” の本番💯へ
0. 事前確認(5分でOK)
0-1. ECR側(現状確認)
- ECR → Repositories → 対象repo → Images
latestがあり、-(untagged)が存在する
→ ✅ 付け替え運用(あなたの状況)
0-2. ECS側(超重要:今なにを参照してるか)
ECS → Task definitions → 対象 → Revision → Container definitions → Image を確認
確認結果で分岐:
- A)
...:latestを参照している → 移行は必須(Step-BでECS参照を変える) - B) すでに
...:v1.2.3や...:git-xxxxを参照 → ECSはOK(ECR push側だけ直す)
1. Step-A(MUTABLE)適用:安全強化を先に入れる(本番に影響を出しにくい)
1-1. 使用テンプレ
04-Sok-Prd-Ecr-Stack-Hardened-StepA-Mutable.yml(あなたに渡したもの)- ScanOnPush: true
- Lifecycle(UntaggedExpireDays)
- TagMutability: MUTABLE(ここが重要:現行を壊さない)
1-2. CloudFormation更新(本番)
- CloudFormation → Stacks → 対象ECRスタック → Update
- “Use current template” ではなく Step-Aテンプレに差し替え(変更セット推奨)
- Parameters:
LowerCasePrefix:既存と同じ(repo名を変えない)UntaggedExpireDays:本番はまず 30日推奨(迷うなら14でもOK)
1-3. 適用後の確認
- ECR リポジトリ → 該当repo → “Scan on push” が有効になっている
- LifecyclePolicy が設定されている
latestpush が引き続き成功する(MUTABLEなのでOKのはず)
2. Step-A導入後の運用監視(軽くでOK)
2-1. 何を見る?
- ECR → Scans(またはイメージ詳細)で脆弱性が出ることを確認
- untagged(
-)が今後増え続けても、設定日数経過で自動削除されること(即消えるわけではない)
3. Step-B(ユニークタグ運用へ移行):本番を止めずに切り替える
ここが「アプリ側(CI/CD)」の作業になりますが、最小変更で進めます。
3-1. まず “新しいタグ” を追加して push する(latestも残す)
現行を壊さないため、最初は 二重 push でいきます。
例(Git SHAを使う場合):
:git-<短縮SHA>を追加して push- ただし当面は
:latestも継続(互換維持)
イメージ例:
.../repo:latest(既存).../repo:git-a1b2c3d(新規)
この時点では “ECSが何を参照しているか” を変えなくても、現行稼働は継続します。
3-2. ECSをユニークタグ参照に切替(ここが本番の山場)
3-2-1. タスク定義の更新
- ECS Task definition の Image を
:latest→:git-a1b2c3dに変更 - 新しい revision を作成
3-2-2. サービスをローリング更新
- ECS Service → Update → 新しいタスク定義 revision を指定
- デプロイ方式はローリング(minimumHealthyPercent を維持)
3-2-3. 確認
- TargetGroup が Healthy
- アプリが正常動作
- 稼働中タスクの Image がユニークタグになっている(ECS画面で確認)
3-3. ロールバック手順(必ず用意)
- ECS Service を 前のタスク定義 revision に戻すだけ
- ECR側は何も戻さなくてOK(ユニークタグは残る)
4. Step-C(最終形):IMMUTABLEへ切替(本番💯)
4-1. 事前条件(これが揃ったら実施)
- ECSが
:latestを参照していない(=ユニークタグ参照になった) - CI/CDが
:latestを上書きpushしない運用にできた(またはやめた)
4-2. CloudFormation更新
- ECRスタックを IMMUTABLE版(
04-Sok-Prd-Ecr-Stack-Hardened.yml)に切替ImageTagMutability: IMMUTABLEを有効化
4-3. 適用後の確認
- ECRで
latestを上書きpushしようとすると 失敗する(=防波堤が機能) - ユニークタグでのpushは問題なくできる
5. “latest” をどうするか(推奨)
推奨:latestは最終的に使わない
latestは「何が動くか」を曖昧にしやすく、事故原因になりやすいです。- IMMUTABLE最終形では “latest運用” をやめるのが王道です。
もし “見やすさ” が必要なら:
release-YYYYMMDD-nのような 人間が読めるユニークタグを追加運用するのが良いです。
チェックリスト(作業当日用)
- ECR:latest/untaggedの状況確認
- ECS:Image が
:latest参照か確認 - Step-A テンプレ適用(MUTABLE、ScanOnPush、Lifecycle)
- ユニークタグでのpushができる(latestは当面残す)
- ECSタスク定義をユニークタグ参照へ更新
- サービスローリング更新で切替
- 問題なければ Step-C(IMMUTABLE)へ更新
- ロールバック手順(前revisionへ戻す)を確認済み
コメント