運用要件定義 - 国際貨物輸送管理システム¶
1. 概要¶
1.1 目的¶
本ドキュメントは、国際貨物輸送管理システムの本番稼働後における運用手順・方針を定義する。運用設計の目標は以下のとおりである。
- 自動化優先: 繰り返し発生する運用タスクはすべてスクリプト化・自動化し、人的ミスを排除する
- IaC 管理: インフラリソースはすべて Terraform で管理し、手動操作による構成ドリフトを防止する
- 観測可能性(Observability)の確保: CloudWatch によるメトリクス・ログ・アラートを統合し、問題を早期に検知する
- SLA/SLO 遵守: 合意した SLA(99.9%)および内部 SLO(99.95%)を常に満たす状態を維持する
1.2 SLA / SLO¶
| 区分 | SLA(外部合意) | SLO(内部目標) | 月間許容停止時間 |
|---|---|---|---|
| システム全体稼働率 | 99.9% | 99.95% | SLA: 43.8 分 / SLO: 21.9 分 |
| 貨物追跡機能稼働率 | 99.99% | 99.995% | SLA: 4.4 分 / SLO: 2.2 分 |
1.3 RTO / RPO¶
| 障害種別 | RTO | RPO |
|---|---|---|
| ECS タスク異常終了 | 5 分(Auto Recovery) | 0(ステートレス) |
| RDS フェイルオーバー(Multi-AZ) | 60〜120 秒 | 数秒(同期レプリケーション) |
| AZ 全体障害 | 30 分 | 1 時間(Point-in-Time Recovery 基準) |
| リージョン全体障害 | 4 時間(手動フェイルオーバー) | 24 時間(日次スナップショット基準) |
1.4 運用基盤¶
| コンポーネント | 構成 |
|---|---|
| ECS クラスター | cargo-tracker-cluster(Fargate、CPU 512 / メモリ 1024 MB、min 2 / max 10) |
| RDS | PostgreSQL 16 Multi-AZ(db.t3.medium、自動バックアップ 7 日) |
| ALB | HTTPS:443 → ECS:8080 |
| 監視 | CloudWatch Logs・Metrics・Alarms・Dashboard |
| ネットワーク | VPC 10.0.0.0/16(ap-northeast-1a / ap-northeast-1c) |
2. 運用フロー¶
2.1 定常運用カレンダー¶
2.2 日次運用¶
毎日 09:00 JST に以下の確認を実施する(所要時間: 15 分以内)。
確認項目:
- CloudWatch ダッシュボード(
cargo-tracker-dashboard)で全メトリクスが正常範囲内であることを確認 - ECS サービスの HealthyHostCount が min 値(2)以上であることを確認
- 前夜の RDS 自動バックアップが正常完了していることを確認
- Alarm 状態のアラートがないことを確認(存在する場合は障害対応フローへ)
# ECS サービス状態確認
aws ecs describe-services \
--cluster cargo-tracker-cluster \
--services cargo-tracker-service \
--query 'services[0].{Status:status,Running:runningCount,Desired:desiredCount}'
# CloudWatch アラーム確認
aws cloudwatch describe-alarms \
--alarm-name-prefix "cargo-tracker" \
--state-value ALARM
# RDS バックアップ確認(直近 1 件)
aws rds describe-db-snapshots \
--db-instance-identifier cargo-tracker-db \
--snapshot-type automated \
--query 'sort_by(DBSnapshots, &SnapshotCreateTime)[-1].{Time:SnapshotCreateTime,Status:Status}'
2.3 週次運用¶
毎週月曜日 10:00 JST に実施する(所要時間: 30 分以内)。
確認・作業項目:
- セキュリティグループのインバウンドルールに不審な変更がないか確認
- AWS Cost Explorer でコストが予算範囲内(前週比 ±20% 以内)であることを確認
- ECR の未使用イメージを確認し、30 日以上前のイメージをクリーンアップ
- ECS タスク定義の最新バージョンに不審なリビジョンがないか確認
# 未使用 ECR イメージ一覧(30 日以上前)
aws ecr describe-images \
--repository-name cargo-tracker-app \
--query 'imageDetails[?imagePushedAt<=`'$(date -d "30 days ago" +%Y-%m-%dT%H:%M:%S)'`].[imageDigest,imagePushedAt]' \
--output table
2.4 月次運用¶
毎月第 1 営業日の午前中に実施する(所要時間: 2 時間以内)。
作業項目:
- OS・ミドルウェアのセキュリティパッチ確認と適用計画策定(→ 変更管理フローへ)
- RDS Point-in-Time Recovery のリストアテスト(→ バックアップ設計参照)
- SLA/SLO 達成状況レポートを作成し関係者へ共有
- ECS Auto Scaling の実績確認とスケーリング閾値の調整検討
- IAM ユーザー・ロールのアクセス権限棚卸
# 月次 SLA レポート用: 過去 30 日の 5xx エラー率取得
aws cloudwatch get-metric-statistics \
--namespace AWS/ApplicationELB \
--metric-name HTTPCode_Target_5XX_Count \
--dimensions Name=LoadBalancer,Value=<ALB-ARN> \
--start-time $(date -d "30 days ago" --iso-8601=seconds) \
--end-time $(date --iso-8601=seconds) \
--period 2592000 \
--statistics Sum
2.5 年次運用¶
毎年 1 月(年度初め)に実施する。
作業項目:
- DR 訓練: リージョン全体障害を想定したフェイルオーバー手順の実動演習(4 時間枠確保)
- AWS ライセンス・サポートプランの更新確認
- 監査ログ(
/ecs/cargo-tracker/audit)の 1 年分をアーカイブして S3 に保存 - 非機能要件(SLA/SLO/RTO/RPO)の見直しと関係者合意
3. 監視設計¶
3.1 監視・アラートフロー¶
3.2 監視項目とアラート閾値¶
3.2.1 アプリケーションメトリクス¶
| メトリクス | ソース | Warning | Critical | 対応 |
|---|---|---|---|---|
| HTTP 5xx エラー率 | ALB | 1% | 5% | 障害対応フロー |
| HTTP レスポンスタイム p95 | ALB | 500ms | 1,000ms | アプリ調査 |
| ECS HealthyHostCount | ECS | 1 | 0 | 即時 ECS 復旧 |
| ECS CPU 使用率 | ECS | 70% | 90% | スケールアウト確認 |
| ECS メモリ使用率 | ECS | 80% | 95% | スケールアウト確認 |
3.2.2 インフラメトリクス¶
| メトリクス | ソース | Warning | Critical | 対応 |
|---|---|---|---|---|
| RDS CPU 使用率 | RDS | 70% | 90% | クエリ最適化 |
| RDS 接続数 | RDS | 上限の 70% | 上限の 90% | 接続プール調整 |
| RDS 空きストレージ | RDS | 20% 以下 | 10% 以下 | ストレージ拡張 |
| RDS レプリカラグ | RDS | 30 秒 | 120 秒 | フェイルオーバー検討 |
3.2.3 性能 SLO メトリクス¶
| 操作 | p95 目標 | 計測ポイント |
|---|---|---|
| 貨物追跡検索 | 200ms | ALB アクセスログ + APM |
| 荷役作業登録 | 500ms | ALB アクセスログ + APM |
| 請求書生成 | 1,500ms | ALB アクセスログ + APM |
3.3 CloudWatch アラーム設定¶
# HTTP 5xx エラー率 Critical アラーム作成
aws cloudwatch put-metric-alarm \
--alarm-name "cargo-tracker-5xx-critical" \
--alarm-description "HTTP 5xx エラー率が 5% を超過" \
--namespace "AWS/ApplicationELB" \
--metric-name "HTTPCode_Target_5XX_Count" \
--dimensions Name=LoadBalancer,Value=<ALB-ARN> \
--statistic Sum \
--period 60 \
--evaluation-periods 3 \
--threshold 5 \
--comparison-operator GreaterThanThreshold \
--alarm-actions <SNS-ARN> \
--treat-missing-data notBreaching
# ECS HealthyHostCount Critical アラーム作成
aws cloudwatch put-metric-alarm \
--alarm-name "cargo-tracker-healthy-host-critical" \
--alarm-description "ECS HealthyHostCount が 0 になった" \
--namespace "AWS/ApplicationELB" \
--metric-name "HealthyHostCount" \
--dimensions Name=TargetGroup,Value=<TG-ARN> \
--statistic Minimum \
--period 60 \
--evaluation-periods 1 \
--threshold 1 \
--comparison-operator LessThanThreshold \
--alarm-actions <SNS-ARN>
3.4 ログ設計¶
| ログ種別 | CloudWatch ロググループ | 保持期間 | 用途 |
|---|---|---|---|
| アプリケーション | /ecs/cargo-tracker |
30 日 | デバッグ・障害調査 |
| 監査 | /ecs/cargo-tracker/audit |
1 年 | コンプライアンス対応 |
| ALB アクセスログ | S3 バケット(cargo-tracker-alb-logs) |
90 日 | 性能分析・セキュリティ |
| RDS 低速クエリ | RDS → CloudWatch | 14 日 | クエリ最適化 |
ログ検索例¶
# 直近 1 時間の ERROR ログを抽出
aws logs filter-log-events \
--log-group-name "/ecs/cargo-tracker" \
--start-time $(($(date +%s%3N) - 3600000)) \
--filter-pattern "ERROR" \
--query 'events[*].{Time:timestamp,Message:message}' \
--output table
# 特定トレース ID のログ追跡
aws logs filter-log-events \
--log-group-name "/ecs/cargo-tracker" \
--filter-pattern '{ $.traceId = "abc-123" }' \
--start-time $(($(date +%s%3N) - 86400000))
# 低速クエリ(1 秒以上)の確認
aws logs filter-log-events \
--log-group-name "/aws/rds/instance/cargo-tracker-db/slowquery" \
--filter-pattern "Query_time: [qt>=1, ...]" \
--start-time $(($(date +%s%3N) - 86400000))
3.5 CloudWatch ダッシュボード¶
ダッシュボード名: cargo-tracker-dashboard
ウィジェット構成:
- SLA ステータス: 直近 30 日の稼働率(5 分粒度)
- HTTP メトリクス: 2xx / 4xx / 5xx の時系列グラフ
- ECS リソース: CPU / メモリ使用率(タスクごと)
- RDS ステータス: CPU / 接続数 / レプリカラグ
- レスポンスタイム: p50 / p95 / p99 の時系列グラフ
4. バックアップ・リカバリ設計¶
4.1 バックアップ方式¶
| 対象 | 方式 | スケジュール | 保持期間 | 担当 |
|---|---|---|---|---|
| RDS(自動) | スナップショット(フル) | 毎日 02:00 JST | 7 日間 | AWS 自動 |
| RDS(手動) | スナップショット(フル) | 月次リリース前 | 無期限(手動管理) | 運用担当 |
| ECS タスク定義 | IaC(Terraform State) | Git push 時 | Git 履歴で管理 | CI/CD |
| アプリケーションログ | CloudWatch → S3 Export | 月次 | 1 年 | Lambda 自動 |
| 監査ログ | CloudWatch → S3 Export | 月次 | 7 年 | Lambda 自動 |
4.2 RDS バックアップ手順¶
手動スナップショット作成¶
# リリース前など任意タイミングで手動スナップショット作成
aws rds create-db-snapshot \
--db-instance-identifier cargo-tracker-db \
--db-snapshot-identifier manual-snapshot-$(date +%Y%m%d-%H%M%S)
# スナップショット作成完了待ち(最大 30 分)
aws rds wait db-snapshot-available \
--db-snapshot-identifier manual-snapshot-$(date +%Y%m%d)
# スナップショット一覧確認
aws rds describe-db-snapshots \
--db-instance-identifier cargo-tracker-db \
--query 'DBSnapshots[*].{ID:DBSnapshotIdentifier,Time:SnapshotCreateTime,Status:Status}' \
--output table
4.3 リストア手順¶
4.3.1 Point-in-Time Recovery(AZ 障害時)¶
RTO 目標: 30 分以内
# Step 1: リストア先の DB インスタンスを新規作成(既存は残す)
aws rds restore-db-instance-to-point-in-time \
--source-db-instance-identifier cargo-tracker-db \
--target-db-instance-identifier cargo-tracker-db-restore \
--restore-time 2026-04-01T01:00:00Z # 復旧したい時点の UTC 時刻
# Step 2: 復旧 DB が利用可能になるまで待機(最大 30 分)
aws rds wait db-instance-available \
--db-instance-identifier cargo-tracker-db-restore
# Step 3: エンドポイント確認
aws rds describe-db-instances \
--db-instance-identifier cargo-tracker-db-restore \
--query 'DBInstances[0].Endpoint.Address'
# Step 4: Secrets Manager の接続情報を新エンドポイントに更新
aws secretsmanager update-secret \
--secret-id cargo-tracker/db-credentials \
--secret-string '{"host":"<new-endpoint>","port":5432,"dbname":"cargotracker","username":"<user>","password":"<pass>"}'
# Step 5: ECS サービスを再デプロイして新 DB に接続切り替え
aws ecs update-service \
--cluster cargo-tracker-cluster \
--service cargo-tracker-service \
--force-new-deployment
4.3.2 スナップショットからのリストア(完全復旧)¶
# Step 1: 利用可能なスナップショット一覧を確認
aws rds describe-db-snapshots \
--db-instance-identifier cargo-tracker-db \
--query 'sort_by(DBSnapshots, &SnapshotCreateTime)[-5:].{ID:DBSnapshotIdentifier,Time:SnapshotCreateTime}' \
--output table
# Step 2: スナップショットから新 DB インスタンスを復元
aws rds restore-db-instance-from-db-snapshot \
--db-instance-identifier cargo-tracker-db-restored \
--db-snapshot-identifier <snapshot-id> \
--db-instance-class db.t3.medium \
--multi-az \
--vpc-security-group-ids <sg-id>
# Step 3 以降: Point-in-Time Recovery の Step 2〜5 と同様
4.4 月次リストアテスト¶
毎月第 1 営業日にリストアテストを実施し、RTO が目標内(30 分)で達成できることを確認する。
テスト手順:
- 自動スナップショットの最新版を確認する
- ステージング環境でスナップショットからリストアを実行する
- リストア完了後、基本的な動作確認(貨物追跡・ログイン)を行う
- 所要時間を記録し、RTO 目標(30 分)内であることを確認する
- テスト結果を月次運用レポートに記録する
5. 障害対応設計¶
5.1 障害対応フロー¶
5.2 ECS タスク障害対応¶
検知条件¶
- ECS HealthyHostCount が 1 以下(Warning)または 0(Critical)
- ALB ヘルスチェック失敗率が 50% を超過
対応手順¶
# Step 1: 障害タスクの特定
aws ecs list-tasks \
--cluster cargo-tracker-cluster \
--service-name cargo-tracker-service \
--desired-status STOPPED
# Step 2: タスク停止理由の確認
aws ecs describe-tasks \
--cluster cargo-tracker-cluster \
--tasks <TASK-ARN> \
--query 'tasks[0].{StopCode:stopCode,Reason:stoppedReason,ContainerReason:containers[0].reason}'
# Step 3: アプリケーションログ確認(直近 100 行)
aws logs get-log-events \
--log-group-name "/ecs/cargo-tracker" \
--log-stream-name "ecs/cargo-tracker-app/<TASK-ID>" \
--limit 100
# Step 4: 自動復旧しない場合、強制再デプロイ
aws ecs update-service \
--cluster cargo-tracker-cluster \
--service cargo-tracker-service \
--force-new-deployment
# Step 5: 新タスクが正常起動するまで待機(最大 5 分)
aws ecs wait services-stable \
--cluster cargo-tracker-cluster \
--services cargo-tracker-service
5.3 RDS フェイルオーバー対応¶
検知条件¶
- RDS のステータスが
available以外 - RDS レプリカラグが 120 秒を超過
対応手順¶
# Step 1: RDS 現在の状態確認
aws rds describe-db-instances \
--db-instance-identifier cargo-tracker-db \
--query 'DBInstances[0].{Status:DBInstanceStatus,AZ:AvailabilityZone,MultiAZ:MultiAZ}'
# Step 2: 自動フェイルオーバーが発生していない場合、手動で実行
aws rds reboot-db-instance \
--db-instance-identifier cargo-tracker-db \
--force-failover
# Step 3: フェイルオーバー完了確認(120 秒程度)
aws rds wait db-instance-available \
--db-instance-identifier cargo-tracker-db
# Step 4: 新エンドポイントに接続できることを確認
ENDPOINT=$(aws rds describe-db-instances \
--db-instance-identifier cargo-tracker-db \
--query 'DBInstances[0].Endpoint.Address' --output text)
echo "新エンドポイント: ${ENDPOINT}"
# Step 5: ECS タスクが新エンドポイントに接続できているか確認
aws ecs describe-services \
--cluster cargo-tracker-cluster \
--services cargo-tracker-service \
--query 'services[0].{Running:runningCount,Desired:desiredCount}'
5.4 連絡体制とエスカレーション¶
| レベル | 担当 | 対応時間 | 連絡方法 |
|---|---|---|---|
| L1: 初期対応 | オンコール担当(輪番) | 5 分以内に応答 | PagerDuty + Slack |
| L2: エスカレーション | インフラリード / 開発リード | 30 分以内 | 電話 + Slack |
| L3: 経営報告 | システムマネージャー | SLA 違反リスク時 | メール + 電話 |
| 顧客通知 | 営業担当 | SLA 違反確定時 | メール・電話 |
エスカレーション基準:
- L1 → L2: 初期対応開始から 30 分以内に解決の見込みがない場合
- L2 → L3: SLA 違反(月間停止時間 43.8 分の 80% = 35 分を超える場合)
- 顧客通知: SLA 違反が確定した場合(確定後 2 時間以内に通知)
5.5 インシデントレポート¶
インシデント発生後 24 時間以内に以下の形式でレポートを作成し、関係者へ共有する。
インシデントレポートテンプレート:
## インシデントレポート
- **インシデント ID**: INC-YYYYMMDD-NNN
- **発生日時**: YYYY-MM-DD HH:MM JST
- **検知日時**: YYYY-MM-DD HH:MM JST
- **解消日時**: YYYY-MM-DD HH:MM JST
- **停止時間**: X 分 Y 秒
- **影響範囲**: [貨物追跡 / 全機能 / 特定機能]
- **SLA への影響**: [なし / あり(月次累積: XX 分)]
### 障害の経緯
1. HH:MM - [事象]
2. HH:MM - [対応内容]
3. HH:MM - [復旧確認]
### 根本原因
[根本原因の詳細]
### 再発防止策
| 対策 | 担当 | 期限 |
|---|---|---|
| [対策内容] | [担当者] | [YYYY-MM-DD] |
6. 変更管理設計¶
6.1 リリースフロー¶
6.2 デプロイコマンド¶
ステージングデプロイ(自動 / main push)¶
# GitHub Actions から自動実行される(手動実行する場合)
aws ecs update-service \
--cluster cargo-tracker-cluster-staging \
--service cargo-tracker-service \
--task-definition cargo-tracker-app:latest \
--force-new-deployment
# デプロイ完了待機
aws ecs wait services-stable \
--cluster cargo-tracker-cluster-staging \
--services cargo-tracker-service
本番デプロイ(手動承認後)¶
# Step 1: ECR の最新イメージ SHA 確認
IMAGE_SHA=$(aws ecr describe-images \
--repository-name cargo-tracker-app \
--query 'sort_by(imageDetails, &imagePushedAt)[-1].imageDigest' \
--output text)
echo "デプロイするイメージ: ${IMAGE_SHA}"
# Step 2: 本番デプロイ前の手動スナップショット取得
aws rds create-db-snapshot \
--db-instance-identifier cargo-tracker-db \
--db-snapshot-identifier pre-deploy-$(date +%Y%m%d-%H%M%S)
# Step 3: 本番 ECS Rolling Update
aws ecs update-service \
--cluster cargo-tracker-cluster \
--service cargo-tracker-service \
--task-definition cargo-tracker-app:<NEW-REVISION> \
--force-new-deployment
# Step 4: デプロイ完了を確認(最大 10 分)
aws ecs wait services-stable \
--cluster cargo-tracker-cluster \
--services cargo-tracker-service
# Step 5: デプロイ後 5 分間のエラー率確認
aws cloudwatch get-metric-statistics \
--namespace AWS/ApplicationELB \
--metric-name HTTPCode_Target_5XX_Count \
--dimensions Name=LoadBalancer,Value=<ALB-ARN> \
--start-time $(date -d "5 minutes ago" --iso-8601=seconds) \
--end-time $(date --iso-8601=seconds) \
--period 300 \
--statistics Sum
6.3 ロールバック手順¶
アプリケーションのロールバック(ECS)¶
# Step 1: 前バージョンのタスク定義リビジョンを確認
aws ecs list-task-definitions \
--family-prefix cargo-tracker-app \
--status ACTIVE \
--sort DESC \
--query 'taskDefinitionArns[:5]' \
--output table
# Step 2: 前バージョンの ECR イメージ SHA を確認
aws ecr describe-images \
--repository-name cargo-tracker-app \
--query 'sort_by(imageDetails, &imagePushedAt)[-2:].{Digest:imageDigest,PushedAt:imagePushedAt}' \
--output table
# Step 3: 前バージョンのタスク定義でサービスを更新
aws ecs update-service \
--cluster cargo-tracker-cluster \
--service cargo-tracker-service \
--task-definition cargo-tracker-app:<前バージョン番号> \
--force-new-deployment
# Step 4: ロールバック完了確認
aws ecs wait services-stable \
--cluster cargo-tracker-cluster \
--services cargo-tracker-service
# Step 5: ロールバック後の動作確認
curl -f https://<ALB-DOMAIN>/actuator/health
DB マイグレーションのロールバック(Forward マイグレーション方式)¶
注記: Flyway の
undoコマンド(U{n}__{説明}.sql)は Flyway Teams / Enterprise ライセンスが必要であり、Community 版では動作しない。本プロジェクトでは Community 版を前提とし、以下の Forward マイグレーション方式 を採用する。
Forward マイグレーション方式:
スキーマ変更のロールバックは「新しいマイグレーションファイルで元の状態に戻す」ことで実現する。
-- 例: カラム追加のロールバックは新しいファイルでカラムを削除する
-- V3__add_cargo_status_column.sql (本番反映済み)
ALTER TABLE cargos ADD COLUMN status VARCHAR(50) NOT NULL DEFAULT 'PRELIMINARY';
-- V4__remove_cargo_status_column.sql (ロールバック相当の forward マイグレーション)
ALTER TABLE cargos DROP COLUMN status;
スキーマ変更を含むリリースの推奨パターン(Expand-Contract):
| フェーズ | 内容 | マイグレーション |
|---|---|---|
| Expand | 新しいカラム・テーブルを追加(旧コードと共存可能な形で) | V{n}__expand_*.sql |
| Migrate | データ移行・新コードへの切り替え | アプリケーションコードの更新 |
| Contract | 旧カラム・テーブルを削除(新コード完全切り替え後) | V{n}__contract_*.sql |
このパターンにより、ECS タスクのロールバック時でも旧コードが新スキーマと共存できる。
# スキーマ変更を含むリリースのロールバック手順
# Step 1: ECS タスクを旧バージョンイメージに戻す(アプリのみ)
aws ecs update-service \
--cluster cargo-tracker-cluster \
--service cargo-tracker-service \
--task-definition cargo-tracker:<旧リビジョン番号>
# Step 2: DB スキーマは旧コードと共存可能であることを確認
# (Expand フェーズのマイグレーションが適用済みなら旧コードも動作する)
# Step 3: Contract フェーズのマイグレーションはロールバック完了を確認後に実施
# ※ Contract 前であれば旧コードで動作継続が可能
# Step 4: 動作確認
curl -f https://<ALB-DOMAIN>/actuator/health
6.4 変更承認フロー¶
| 変更種別 | 影響範囲 | 承認者 | 申請方法 |
|---|---|---|---|
| ホットフィックス(緊急) | 限定的 | 開発リード 1 名 | Slack 承認 + PR |
| 通常リリース | 機能追加・変更 | 開発リード + QA 担当 | GitHub PR レビュー |
| インフラ変更(軽微) | 設定値変更 | インフラリード 1 名 | GitHub PR(Terraform) |
| インフラ変更(重大) | VPC・スキーマ変更 | インフラリード + システムマネージャー | 変更管理チケット + PR |
| DB マイグレーション | スキーマ変更 | 開発リード + DBA | GitHub PR + 手動確認 |
7. セキュリティ運用¶
7.1 アクセス管理¶
IAM 最小権限原則¶
- ECS タスクロール: 必要なサービス(S3 / Secrets Manager / CloudWatch)のみ許可
- 開発者: 本番環境への直接アクセス不可(ステージング環境は可)
- 本番アクセス: 承認制(緊急時 Break Glass 手順を別途定義)
# 本番環境の ECS Exec(緊急デバッグ時のみ。承認必須)
aws ecs execute-command \
--cluster cargo-tracker-cluster \
--task <TASK-ARN> \
--container cargo-tracker-app \
--interactive \
--command "/bin/sh"
# 実行後は必ず監査ログに記録すること
Secrets Manager 管理¶
# シークレット一覧確認
aws secretsmanager list-secrets \
--filters Key=name,Values=cargo-tracker \
--query 'SecretList[*].{Name:Name,LastChanged:LastChangedDate}' \
--output table
# 本番シークレットのローテーション(90 日ごとに手動実行)
aws secretsmanager rotate-secret \
--secret-id cargo-tracker/db-credentials
7.2 パッチ管理¶
| 対象 | 頻度 | 方法 | 承認フロー |
|---|---|---|---|
| アプリケーション依存ライブラリ | 月次(Critical は即時) | Dependabot PR + CI | 通常リリースフロー |
| Docker ベースイメージ | 月次 | ECR 再ビルド + デプロイ | 通常リリースフロー |
| RDS マイナーバージョン | 四半期 | AWS コンソール / CLI | インフラ変更フロー |
| RDS メジャーバージョン | 年次(EOL 前) | Blue/Green デプロイ | 重大インフラ変更フロー |
# RDS エンジンバージョン確認(アップデート対象がないか確認)
aws rds describe-db-instances \
--db-instance-identifier cargo-tracker-db \
--query 'DBInstances[0].{Engine:Engine,Version:EngineVersion,PendingModification:PendingModifiedValues}'
7.3 セキュリティインシデント対応¶
| インシデント種別 | 初期対応 | エスカレーション |
|---|---|---|
| 不正アクセス検知 | 対象 IAM ユーザー・ロールを即時無効化 | セキュリティ担当 + システムマネージャー |
| データ漏洩疑い | ECS サービス停止 + 通信遮断 | CISO + 法務 |
| DDoS 攻撃 | AWS WAF ルール追加 + AWS Shield 確認 | インフラリード |
| 脆弱性発覚(Critical) | 24 時間以内にパッチ適用計画を策定 | 開発リード + セキュリティ担当 |
8. キャパシティ管理¶
8.1 ECS Auto Scaling 設定¶
| メトリクス | スケールアウト条件 | スケールイン条件 | クールダウン |
|---|---|---|---|
| CPU 使用率 | 70% 以上・3 分継続 | 30% 以下・5 分継続 | 300 秒 |
| メモリ使用率 | 80% 以上・3 分継続 | 40% 以下・5 分継続 | 300 秒 |
| ALB リクエスト数/タスク | 1,000 req/min を超過 | 300 req/min 以下 | 300 秒 |
スケーリング範囲: min 2 タスク / max 10 タスク
# Auto Scaling 設定確認
aws application-autoscaling describe-scaling-policies \
--service-namespace ecs \
--resource-id service/cargo-tracker-cluster/cargo-tracker-service
# 手動スケールアウト(緊急時)
aws ecs update-service \
--cluster cargo-tracker-cluster \
--service cargo-tracker-service \
--desired-count 5
8.2 容量計画¶
月次レビュー観点:
- ECS タスク数のピーク・平均の推移(max 10 の 70% = 7 タスクを超えたら増枠検討)
- RDS 接続数の推移(上限の 70% を超えたら接続プール設定を見直し)
- RDS ストレージ使用量(80% を超えたらストレージ拡張を計画)
- CloudWatch Logs のストレージコスト(保持期間の見直し)
# ECS タスク数の推移(過去 7 日)
aws cloudwatch get-metric-statistics \
--namespace ECS/ContainerInsights \
--metric-name RunningTaskCount \
--dimensions Name=ClusterName,Value=cargo-tracker-cluster \
--start-time $(date -d "7 days ago" --iso-8601=seconds) \
--end-time $(date --iso-8601=seconds) \
--period 3600 \
--statistics Maximum Average \
--output table
# RDS ストレージ使用量確認
aws cloudwatch get-metric-statistics \
--namespace AWS/RDS \
--metric-name FreeStorageSpace \
--dimensions Name=DBInstanceIdentifier,Value=cargo-tracker-db \
--start-time $(date -d "1 day ago" --iso-8601=seconds) \
--end-time $(date --iso-8601=seconds) \
--period 3600 \
--statistics Minimum \
--output table
8.3 コスト最適化¶
| 施策 | 効果 | 実施タイミング |
|---|---|---|
| ECS Spot インスタンス(ステージング) | ~70% コスト削減 | ステージング構築時 |
| RDS 本番外は夜間停止 | ~60% コスト削減 | ステージング適用済み |
| ECR ライフサイクルポリシー(30 日超古いイメージ削除) | ストレージコスト削減 | 設定済み |
| CloudWatch Logs 保持期間最適化 | 不要なログコスト削減 | 月次レビュー時 |
9. 付録¶
9.1 運用チェックリスト¶
日次チェックリスト¶
## 日次運用チェック(YYYY-MM-DD)
### システム状態
- [ ] ECS HealthyHostCount: min 2 以上
- [ ] CloudWatch アラーム: ALARM 状態なし
- [ ] HTTP 5xx エラー率: 1% 未満
- [ ] RDS 自動バックアップ: 完了
### 確認コマンド実行済み
- [ ] aws ecs describe-services(ECS 状態)
- [ ] aws cloudwatch describe-alarms(アラーム状態)
- [ ] aws rds describe-db-snapshots(バックアップ状態)
### 異常・特記事項
(なし / 詳細を記載)
### 確認者
氏名: 確認時刻:
月次チェックリスト¶
## 月次運用チェック(YYYY-MM)
### セキュリティ
- [ ] セキュリティパッチ適用完了(または適用計画策定済み)
- [ ] IAM アクセス権限棚卸完了
- [ ] Secrets Manager ローテーション確認
### バックアップ
- [ ] RDS リストアテスト完了(所要時間: XX 分)
- [ ] テスト結果: RTO 目標(30 分)内 / 超過
### 容量・性能
- [ ] ECS タスク数ピーク確認(最大: X タスク)
- [ ] RDS ストレージ使用率確認(使用率: XX%)
- [ ] SLA/SLO 達成状況確認(稼働率: XX.XX%)
### コスト
- [ ] AWS コスト確認(予算比: +/-XX%)
### 作成者・確認者
作成者: 確認者: 実施日:
9.2 連絡先テンプレート¶
## 障害連絡先一覧(機密情報のため別途管理)
### オンコール担当(輪番)
| 週 | 担当者 | 連絡先 |
|---|---|---|
| 第 1 週 | 担当 A | [電話番号] |
| 第 2 週 | 担当 B | [電話番号] |
| 第 3 週 | 担当 C | [電話番号] |
| 第 4 週 | 担当 D | [電話番号] |
### エスカレーション先
| レベル | 担当 | 連絡方法 |
|---|---|---|
| L2: インフラリード | [氏名] | [電話 / Slack] |
| L2: 開発リード | [氏名] | [電話 / Slack] |
| L3: システムマネージャー | [氏名] | [電話] |
| セキュリティ担当 | [氏名] | [電話 / メール] |
### 外部連絡先
| 対象 | 連絡先 | 備考 |
|---|---|---|
| AWS サポート | https://console.aws.amazon.com/support | Business サポートプラン |
| PagerDuty | https://[テナント].pagerduty.com | サービス: cargo-tracker |
9.3 Terraform 管理リソース一覧¶
| リソース | Terraform モジュール | State ファイル |
|---|---|---|
| VPC / サブネット / SG | ops/terraform/modules/network |
S3: cargo-tracker-tfstate/network |
| ECS クラスター / サービス | ops/terraform/modules/ecs |
S3: cargo-tracker-tfstate/ecs |
| RDS インスタンス | ops/terraform/modules/rds |
S3: cargo-tracker-tfstate/rds |
| ALB / ターゲットグループ | ops/terraform/modules/alb |
S3: cargo-tracker-tfstate/alb |
| CloudWatch アラーム / ダッシュボード | ops/terraform/modules/monitoring |
S3: cargo-tracker-tfstate/monitoring |
| IAM ロール / ポリシー | ops/terraform/modules/iam |
S3: cargo-tracker-tfstate/iam |
# Terraform State の確認
aws s3 ls s3://cargo-tracker-tfstate/ --recursive
# Terraform でのドリフト検出
cd ops/terraform
terraform plan -out=tfplan
terraform show -json tfplan | jq '.resource_changes[] | select(.change.actions != ["no-op"])'
9.4 用語集¶
| 用語 | 定義 |
|---|---|
| SLA | Service Level Agreement。顧客と合意した稼働率(99.9%) |
| SLO | Service Level Objective。内部目標稼働率(99.95%) |
| RTO | Recovery Time Objective。障害発生から復旧までの目標時間 |
| RPO | Recovery Point Objective。障害発生時に許容できるデータ損失範囲 |
| HealthyHostCount | ALB が正常と判断しているターゲット(ECS タスク)数 |
| Rolling Update | 旧バージョンのタスクを順次新バージョンに置き換えるデプロイ方式 |
| Break Glass | 緊急時に通常アクセス制限を超えた操作を行う手順(証跡必須) |
| PITR | Point-in-Time Recovery。任意の時点への RDS データ復元機能 |