第3章:仮想マシン(Compute)の活用
はじめに
仮想マシン(VM)は、クラウドコンピューティングの最も基本的かつ重要なサービスです。AWS EC2、Azure Virtual Machines、Google Compute Engine は、それぞれ実装の詳細は異なりますが、オンデマンドでスケーラブルなコンピューティングリソースを提供するという同じ目的を持っています。
本章では、仮想マシンの選択から設計、運用、最適化まで、実践的な知識とスキルを体系的に学びます。単にインスタンスを起動するだけでなく、ビジネス要件に最適化された、セキュアで費用対効果の高いコンピュート環境を構築する方法を習得します。
3.1 仮想マシンの種類と選び方(インスタンスタイプ、OS)
インスタンスタイプ選択の経済学と技術
クラウドにおける仮想マシンの選択は、単なる技術的な決定ではありません。それは、パフォーマンス、コスト、将来の拡張性、運用の複雑さのバランスを取る、戦略的な意思決定です。
なぜこれほど多くのインスタンスタイプが存在するのか
ワークロードの多様性への対応
現代のアプリケーションは、極めて多様な特性を持っています:
ウェブサーバー:
- CPU: 中程度の使用率(20-40%)
- メモリ: リクエスト数に比例
- ネットワーク: 高いスループット要求
- ストレージ: 低I/O
データベース:
- CPU: クエリ複雑度に依存
- メモリ: データセット全体をキャッシュ
- ネットワーク: 中程度
- ストレージ: 高IOPS要求
機械学習トレーニング:
- CPU: 前処理で使用
- GPU: モデル学習で集中使用
- メモリ: 大容量データセット
- ストレージ: 高スループット
これらの異なる要求に対して、単一のハードウェア構成で対応することは、技術的にも経済的にも非効率です。
インスタンスファミリーの詳細解説
1. 汎用インスタンス(General Purpose)
特徴と設計思想:
リソースバランス:
- vCPU : メモリ = 1:4 の比率が一般的
- 中程度のネットワーク性能
- EBS最適化がデフォルト有効(新世代)
利用シナリオ:
- マイクロサービスアーキテクチャ
- 小〜中規模のデータベース
- 開発・テスト環境
- エンタープライズアプリケーション
各プロバイダーの詳細:
AWS (M6i, M6a, T3, T4g)
M6i/M6a シリーズ:
- Intel Xeon 第3世代 / AMD EPYC 第3世代
- ニトロシステムによる最適化
- 最大 384 vCPU, 1536 GiB メモリ
- ネットワーク: 最大 50 Gbps
T3/T4g シリーズ(バースト可能):
- ベースライン性能 + バーストクレジット
- コスト効率重視のワークロード向け
- CPUクレジットの蓄積と消費
- T4g: ARM ベース(Graviton2)で20%コスト削減
価格例(us-east-1, 2024年):
m6i.large (2 vCPU, 8 GiB): $0.096/時間
t3.large (2 vCPU, 8 GiB): $0.0832/時間
Azure (Dv4, Dav4, B シリーズ)
Dv4/Dav4 シリーズ:
- Intel Xeon Platinum 8272CL / AMD EPYC 7452
- 最大 96 vCPU, 384 GiB メモリ
- Premium SSD サポート
- 高速ネットワーク対応
B シリーズ(バースト可能):
- 低コストのベースライン性能
- クレジットバンキングシステム
- 開発環境に最適
価格例(East US, 2024年):
D2v4 (2 vCPU, 8 GiB): $0.096/時間
B2s (2 vCPU, 4 GiB): $0.0416/時間
GCP (N2, N2D, E2)
N2/N2D シリーズ:
- Intel Xeon / AMD EPYC 第2世代
- カスタムマシンタイプ対応
- 最大 128 vCPU, 864 GiB メモリ
- 高性能ネットワーク
E2 シリーズ(コスト最適化):
- 複数のCPUプラットフォーム
- 自動的なライブマイグレーション
- 事前定義・カスタム両対応
価格例(us-central1, 2024年):
n2-standard-2 (2 vCPU, 8 GiB): $0.0971/時間
e2-standard-2 (2 vCPU, 8 GiB): $0.0669/時間
2. コンピュート最適化(Compute Optimized)
設計思想:
高性能CPU重視:
- 高周波数プロセッサ
- vCPU : メモリ = 1:2 の比率
- 最新のCPUアーキテクチャ
適用シナリオ:
- 高性能ウェブサーバー
- 科学計算・シミュレーション
- 分散分析
- 高性能ゲームサーバー
各プロバイダーの詳細:
AWS (C6i, C6a, C7g)
C6i/C6a シリーズ:
- Intel Xeon 第3世代 / AMD EPYC 第3世代
- 最大 3.5 GHz の高クロック
- 最大 192 vCPU, 384 GiB メモリ
- EBS最適化・SR-IOV対応
C7g シリーズ(ARM):
- AWS Graviton3 プロセッサ
- 最大 40% パフォーマンス向上
- 最大 60% エネルギー効率改善
価格例(us-east-1, 2024年):
c6i.large (2 vCPU, 4 GiB): $0.085/時間
c7g.large (2 vCPU, 4 GiB): $0.0725/時間
Azure (Fv2, Fx)
Fv2 シリーズ:
- Intel Xeon Platinum 8272CL
- 最大 3.7 GHz ベースクロック
- 最大 72 vCPU, 144 GiB メモリ
- 高速ネットワーク・Premium SSD
価格例(East US, 2024年):
F2s_v2 (2 vCPU, 4 GiB): $0.085/時間
GCP (C2, C2D)
C2/C2D シリーズ:
- Intel Xeon / AMD EPYC 第2世代
- 最大 3.9 GHz のターボクロック
- 最大 60 vCPU, 240 GiB メモリ
- 高性能ネットワーク
価格例(us-central1, 2024年):
c2-standard-2 (2 vCPU, 8 GiB): $0.1002/時間
c2d-standard-2 (2 vCPU, 8 GiB): $0.0891/時間
3. メモリ最適化(Memory Optimized)
設計思想:
大容量メモリ重視:
- vCPU : メモリ = 1:8 または 1:16 の比率
- 高メモリ帯域幅
- NUMA最適化
適用シナリオ:
- インメモリデータベース(Redis, Memcached)
- リアルタイム解析
- 大容量キャッシュ
- 高性能計算(HPC)
各プロバイダーの詳細:
AWS (R6i, R6a, X1e, z1d)
R6i/R6a シリーズ:
- Intel Xeon 第3世代 / AMD EPYC 第3世代
- 最大 1024 GiB メモリ
- DDR4-3200 メモリ
- 高帯域幅メモリアクセス
X1e シリーズ:
- 最大 3904 GiB メモリ
- SAP HANA 認定
- 高メモリ帯域幅
z1d シリーズ:
- 高周波数 + 高メモリ
- NVMe SSD 搭載
- 最大 4.0 GHz ターボクロック
価格例(us-east-1, 2024年):
r6i.large (2 vCPU, 16 GiB): $0.126/時間
x1e.large (2 vCPU, 61 GiB): $0.334/時間
z1d.large (2 vCPU, 16 GiB): $0.186/時間
Azure (Ev4, Eav4, Mv2)
Ev4/Eav4 シリーズ:
- Intel Xeon Platinum / AMD EPYC 第2世代
- 最大 672 GiB メモリ
- Premium SSD サポート
- 高速ネットワーク
Mv2 シリーズ:
- 最大 5.7 TiB メモリ
- SAP HANA 認定
- 最大 416 vCPU
価格例(East US, 2024年):
E2v4 (2 vCPU, 16 GiB): $0.126/時間
M64s_v2 (64 vCPU, 1024 GiB): $5.888/時間
GCP (N2-highmem, M1, M2)
N2-highmem シリーズ:
- Intel Xeon 第2世代
- 最大 6.5 GiB メモリ/vCPU
- 最大 864 GiB メモリ
- カスタムマシンタイプ対応
M1/M2 シリーズ:
- 最大 12 TiB メモリ
- SAP HANA 認定
- 専用ホスト
価格例(us-central1, 2024年):
n2-highmem-2 (2 vCPU, 16 GiB): $0.1188/時間
m1-ultramem-40 (40 vCPU, 961 GiB): $6.7034/時間
4. ストレージ最適化(Storage Optimized)
設計思想:
高速ストレージ重視:
- NVMe SSD 搭載
- 高 IOPS・低レイテンシ
- ローカルストレージ
適用シナリオ:
- 分散ファイルシステム
- データウェアハウス
- 高IOPS NoSQL データベース
- 検索エンジン
各プロバイダーの詳細:
AWS (I3, I3en, I4i, D2, D3)
I3/I3en シリーズ:
- NVMe SSD 搭載
- 最大 15.2 TiB NVMe ストレージ
- 最大 325万 IOPS
- 10 Gbps ネットワーク
I4i シリーズ:
- 最新世代 NVMe SSD
- 最大 30 TiB NVMe ストレージ
- 最大 400万 IOPS
- AWS Nitro SSD
D2/D3 シリーズ:
- HDD ベース大容量ストレージ
- 最大 48 TiB HDD ストレージ
- 分散ファイルシステム向け
価格例(us-east-1, 2024年):
i3.large (2 vCPU, 15.25 GiB + 475 GB NVMe): $0.156/時間
i4i.large (2 vCPU, 16 GiB + 468 GB NVMe): $0.1692/時間
d3.large (2 vCPU, 8 GiB + 6000 GB HDD): $0.1662/時間
Azure (Lv2, Lv3)
Lv2/Lv3 シリーズ:
- NVMe SSD 搭載
- 最大 1.92 TiB NVMe ストレージ
- 高 IOPS・低レイテンシ
- 高速ネットワーク
価格例(East US, 2024年):
L8s_v2 (8 vCPU, 64 GiB + 1920 GB NVMe): $0.696/時間
L8s_v3 (8 vCPU, 64 GiB + 1920 GB NVMe): $0.624/時間
GCP (Local SSD)
Local SSD:
- 375 GB NVMe SSD
- 最大 24 個まで接続可能
- 最大 680,000 IOPS
- 任意のマシンタイプに追加可能
価格例(us-central1, 2024年):
Local SSD: $0.04/時間(375 GB あたり)
n2-standard-2 + 1x Local SSD: $0.1371/時間
5. 高性能コンピューティング(HPC)
設計思想:
大規模並列処理:
- 高性能CPU・GPU
- 高帯域幅ネットワーク
- 低レイテンシ通信
- RDMA 対応
適用シナリオ:
- 科学計算・シミュレーション
- 機械学習・AI トレーニング
- 金融モデリング
- 気象・地震解析
各プロバイダーの詳細:
AWS (HPC6a, HPC7g)
HPC6a シリーズ:
- AMD EPYC 第3世代
- 最大 96 vCPU
- Elastic Fabric Adapter (EFA)
- 100 Gbps ネットワーク
HPC7g シリーズ:
- AWS Graviton3E プロセッサ
- 最大 128 vCPU
- DDR5 メモリ
- 200 Gbps ネットワーク
価格例(us-east-1, 2024年):
hpc6a.48xlarge (96 vCPU, 384 GiB): $2.88/時間
hpc7g.4xlarge (16 vCPU, 128 GiB): $1.2848/時間
Azure (HBv3, HCv1, NCv3)
HBv3 シリーズ:
- AMD EPYC 第3世代
- 最大 120 vCPU
- InfiniBand HDR
- 200 Gbps ネットワーク
HCv1 シリーズ:
- Intel Xeon Platinum
- 最大 44 vCPU
- InfiniBand EDR
- 100 Gbps ネットワーク
NCv3 シリーズ:
- NVIDIA V100 GPU
- 最大 4 GPU
- NVLink 2.0
- RDMA 対応
価格例(East US, 2024年):
HB120rs_v3 (120 vCPU, 448 GiB): $3.168/時間
HC44rs (44 vCPU, 352 GiB): $2.64/時間
NC24rs_v3 (24 vCPU, 448 GiB + 4x V100): $18.12/時間
GCP (C2, N2, A2)
C2 シリーズ:
- Intel Xeon Cascade Lake
- 最大 60 vCPU
- 高性能ネットワーク
- 科学計算最適化
A2 シリーズ:
- NVIDIA A100 GPU
- 最大 16 GPU
- NVLink 3.0
- 高帯域幅メモリ
価格例(us-central1, 2024年):
c2-standard-60 (60 vCPU, 240 GiB): $3.006/時間
a2-highgpu-1g (12 vCPU, 85 GiB + 1x A100): $3.673/時間
インスタンスタイプ選択のフレームワーク
1. ワークロード分析
パフォーマンス要件の定量化:
# ワークロード分析の例
workload_analysis = {
"cpu_utilization": {
"average": 45, # %
"peak": 85, # %
"pattern": "burst" # steady, burst, periodic
},
"memory_usage": {
"average": 4.2, # GB
"peak": 6.8, # GB
"cache_ratio": 0.6 # データキャッシュ比率
},
"network": {
"throughput": 150, # Mbps
"connections": 1000, # concurrent
"latency_sensitive": True
},
"storage": {
"iops": 1500, # IOPS
"throughput": 50, # MB/s
"capacity": 100 # GB
}
}
2. コスト最適化
Right-sizing の実践:
# コスト最適化の計算例
def calculate_instance_cost(instance_type, hours_per_month=730):
prices = {
"m6i.large": 0.096,
"m6i.xlarge": 0.192,
"c6i.large": 0.085,
"r6i.large": 0.126
}
monthly_cost = prices[instance_type] * hours_per_month
return monthly_cost
# 使用例
instances = ["m6i.large", "m6i.xlarge", "c6i.large", "r6i.large"]
for instance in instances:
cost = calculate_instance_cost(instance)
print(f"{instance}: ${cost:.2f}/month")
3. ベンチマーキング
性能評価の基準:
# CPU ベンチマーク
sysbench cpu --threads=2 --time=60 run
# メモリ ベンチマーク
sysbench memory --memory-total-size=10G --threads=2 run
# ストレージ ベンチマーク
fio --name=random-read --ioengine=libaio --rw=randread --bs=4k --numjobs=1 --size=4G --runtime=60 --time_based --group_reporting
# ネットワーク ベンチマーク
iperf3 -c target-server -t 60 -P 4
オペレーティングシステムの選択
1. Linux ディストリビューション
Amazon Linux 2
特徴:
- AWS 最適化
- 長期サポート(5年)
- Amazon Linux Extras
- セキュリティ更新の迅速な提供
適用シナリオ:
- AWS 中心の環境
- 運用コストを抑えたい場合
- AWS サービスとの統合重視
Ubuntu
特徴:
- 豊富なパッケージ
- 活発なコミュニティ
- 定期的なLTSリリース
- クラウドネイティブ対応
適用シナリオ:
- 開発環境
- コンテナ化アプリケーション
- オープンソースソフトウェア
CentOS/RHEL
特徴:
- エンタープライズ志向
- 長期サポート
- 安定性重視
- 商用サポート(RHEL)
適用シナリオ:
- エンタープライズアプリケーション
- 長期運用システム
- コンプライアンス要件
2. Windows Server
Windows Server 2019/2022
特徴:
- Active Directory 統合
- .NET アプリケーション
- SQL Server 最適化
- PowerShell 自動化
適用シナリオ:
- Microsoft 技術スタック
- エンタープライズアプリケーション
- レガシーシステム移行
ライセンス考慮事項:
BYOL (Bring Your Own License):
- 既存ライセンスの活用
- ライセンス持込割引
- コンプライアンス管理
License Included:
- 従量課金モデル
- 初期投資不要
- 使用量に応じた課金
実践的な選択事例
事例1: ウェブアプリケーション
要件:
- 平均 100 並行ユーザー
- レスポンス時間 < 200ms
- 月間 50GB データ転送
- 高可用性要求
選択結果:
推奨構成:
- インスタンスタイプ: m6i.large
- OS: Ubuntu 20.04 LTS
- 配置: 複数AZでの冗長化
- ロードバランサー: Application Load Balancer
根拠:
- バランスの取れたリソース比率
- バーストトラフィックに対応
- コスト効率の良い選択
事例2: データベースサーバー
要件:
- 500GB データベース
- 高IOPS要求(10,000 IOPS)
- メモリ集約的処理
- 99.9% 可用性
選択結果:
推奨構成:
- インスタンスタイプ: r6i.xlarge
- OS: Amazon Linux 2
- ストレージ: gp3 (プロビジョンド IOPS)
- 配置: Multi-AZ 配置
根拠:
- 高メモリ・CPU 比率
- EBS 最適化
- マネージドサービス利用
事例3: 機械学習ワークロード
要件:
- 大規模データセット処理
- GPU 計算
- 分散処理
- バッチ処理
選択結果:
推奨構成:
- インスタンスタイプ: p4d.24xlarge
- OS: Deep Learning AMI
- ストレージ: FSx for Lustre
- 配置: スポットインスタンス活用
根拠:
- 高性能GPU(8x A100)
- 高帯域幅ネットワーク
- 最適化されたML環境
3.2 仮想マシンのライフサイクル管理
起動から停止までの包括的管理
仮想マシンの適切なライフサイクル管理は、単にインスタンスを起動・停止するだけではありません。設計、プロビジョニング、設定、監視、メンテナンス、最適化、廃止まで、すべてのフェーズを通じて一貫した品質とセキュリティを確保する必要があります。
1. 設計・計画フェーズ
キャパシティプランニング
# キャパシティプランニングの例
import math
def calculate_capacity_requirements(business_metrics):
"""
ビジネスメトリクスからキャパシティ要件を計算
"""
# 基本メトリクス
daily_users = business_metrics['daily_active_users']
peak_concurrency_ratio = business_metrics['peak_concurrency_ratio']
growth_rate = business_metrics['annual_growth_rate']
# 現在の要件計算
current_peak_users = daily_users * peak_concurrency_ratio
# 成長を考慮した将来要件
planning_horizon = 2 # 2年間
future_peak_users = current_peak_users * (1 + growth_rate) ** planning_horizon
# リソース要件の計算
cpu_per_user = 0.1 # vCPU/user
memory_per_user = 0.25 # GB/user
required_vcpu = math.ceil(future_peak_users * cpu_per_user)
required_memory = math.ceil(future_peak_users * memory_per_user)
# 冗長性とバッファーを考慮
redundancy_factor = 2.0 # アクティブ-スタンバイ
buffer_factor = 1.3 # 30%のバッファー
final_vcpu = math.ceil(required_vcpu * redundancy_factor * buffer_factor)
final_memory = math.ceil(required_memory * redundancy_factor * buffer_factor)
return {
'current_peak_users': current_peak_users,
'future_peak_users': future_peak_users,
'required_vcpu': final_vcpu,
'required_memory': final_memory,
'recommended_instances': calculate_instance_mix(final_vcpu, final_memory)
}
def calculate_instance_mix(total_vcpu, total_memory):
"""
必要なリソースから最適なインスタンス構成を計算
"""
instance_types = {
'm6i.large': {'vcpu': 2, 'memory': 8, 'cost_per_hour': 0.096},
'm6i.xlarge': {'vcpu': 4, 'memory': 16, 'cost_per_hour': 0.192},
'm6i.2xlarge': {'vcpu': 8, 'memory': 32, 'cost_per_hour': 0.384},
'm6i.4xlarge': {'vcpu': 16, 'memory': 64, 'cost_per_hour': 0.768}
}
# 最適化アルゴリズム(簡略化)
best_config = None
min_cost = float('inf')
for instance_type, specs in instance_types.items():
# 必要なインスタンス数を計算
instances_for_cpu = math.ceil(total_vcpu / specs['vcpu'])
instances_for_memory = math.ceil(total_memory / specs['memory'])
required_instances = max(instances_for_cpu, instances_for_memory)
# コストを計算
monthly_cost = required_instances * specs['cost_per_hour'] * 730
if monthly_cost < min_cost:
min_cost = monthly_cost
best_config = {
'instance_type': instance_type,
'count': required_instances,
'monthly_cost': monthly_cost,
'total_vcpu': required_instances * specs['vcpu'],
'total_memory': required_instances * specs['memory']
}
return best_config
# 使用例
business_metrics = {
'daily_active_users': 10000,
'peak_concurrency_ratio': 0.15,
'annual_growth_rate': 0.25
}
capacity_plan = calculate_capacity_requirements(business_metrics)
print(f"推奨構成: {capacity_plan['recommended_instances']}")
2. プロビジョニング・起動フェーズ
Infrastructure as Code による自動化
# Terraform による VM プロビジョニング例
# variables.tf
variable "environment" {
description = "Environment name"
type = string
default = "production"
}
variable "instance_count" {
description = "Number of instances to launch"
type = number
default = 2
}
variable "instance_type" {
description = "EC2 instance type"
type = string
default = "m6i.large"
}
# main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.aws_region
}
# AMI の選択
data "aws_ami" "amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
}
}
# セキュリティグループ
resource "aws_security_group" "web_server" {
name_prefix = "${var.environment}-web-"
vpc_id = data.aws_vpc.default.id
ingress {
description = "HTTP"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "HTTPS"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "SSH"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [data.aws_vpc.default.cidr_block]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "${var.environment}-web-sg"
}
}
# Launch Template
resource "aws_launch_template" "web_server" {
name_prefix = "${var.environment}-web-"
image_id = data.aws_ami.amazon_linux.id
instance_type = var.instance_type
key_name = var.key_pair_name
vpc_security_group_ids = [aws_security_group.web_server.id]
user_data = base64encode(templatefile("${path.module}/userdata.sh", {
environment = var.environment
}))
tag_specifications {
resource_type = "instance"
tags = {
Name = "${var.environment}-web-server"
Environment = var.environment
ManagedBy = "Terraform"
}
}
# EBS 最適化
ebs_optimized = true
# 詳細監視
monitoring {
enabled = true
}
# メタデータサービス v2 強制
metadata_options {
http_endpoint = "enabled"
http_tokens = "required"
http_put_response_hop_limit = 2
}
}
# Auto Scaling Group
resource "aws_autoscaling_group" "web_server" {
name = "${var.environment}-web-asg"
vpc_zone_identifier = data.aws_subnets.default.ids
target_group_arns = [aws_lb_target_group.web_server.arn]
health_check_type = "ELB"
health_check_grace_period = 300
min_size = var.instance_count
max_size = var.instance_count * 2
desired_capacity = var.instance_count
launch_template {
id = aws_launch_template.web_server.id
version = "$Latest"
}
tag {
key = "Name"
value = "${var.environment}-web-server"
propagate_at_launch = true
}
tag {
key = "Environment"
value = var.environment
propagate_at_launch = true
}
}
User Data による初期設定
#!/bin/bash
# userdata.sh
set -e
# 変数設定
ENVIRONMENT="${environment}"
LOG_FILE="/var/log/userdata.log"
# ログ関数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}
log "Starting instance initialization for environment: $ENVIRONMENT"
# システム更新
log "Updating system packages"
yum update -y
# 必要なパッケージのインストール
log "Installing required packages"
yum install -y \
httpd \
awslogs \
amazon-cloudwatch-agent \
htop \
git \
wget \
curl \
unzip
# Apache の設定
log "Configuring Apache"
systemctl enable httpd
systemctl start httpd
# カスタムインデックスページの作成
cat > /var/www/html/index.html << EOF
<!DOCTYPE html>
<html>
<head>
<title>$ENVIRONMENT Web Server</title>
</head>
<body>
<h1>Welcome to $ENVIRONMENT Environment</h1>
<p>Instance ID: $(curl -s http://169.254.169.254/latest/meta-data/instance-id)</p>
<p>Availability Zone: $(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)</p>
<p>Instance Type: $(curl -s http://169.254.169.254/latest/meta-data/instance-type)</p>
<p>Local IP: $(curl -s http://169.254.169.254/latest/meta-data/local-ipv4)</p>
<p>Timestamp: $(date)</p>
</body>
</html>
EOF
# CloudWatch Agent の設定
log "Configuring CloudWatch Agent"
cat > /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json << EOF
{
"metrics": {
"namespace": "Custom/$ENVIRONMENT",
"metrics_collected": {
"cpu": {
"measurement": [
"cpu_usage_idle",
"cpu_usage_iowait",
"cpu_usage_user",
"cpu_usage_system"
],
"metrics_collection_interval": 60,
"totalcpu": false
},
"disk": {
"measurement": [
"used_percent"
],
"metrics_collection_interval": 60,
"resources": [
"/"
]
},
"diskio": {
"measurement": [
"io_time"
],
"metrics_collection_interval": 60,
"resources": [
"*"
]
},
"mem": {
"measurement": [
"mem_used_percent"
],
"metrics_collection_interval": 60
},
"netstat": {
"measurement": [
"tcp_established",
"tcp_time_wait"
],
"metrics_collection_interval": 60
},
"swap": {
"measurement": [
"swap_used_percent"
],
"metrics_collection_interval": 60
}
}
},
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/httpd/access_log",
"log_group_name": "/aws/ec2/$ENVIRONMENT/httpd/access",
"log_stream_name": "{instance_id}"
},
{
"file_path": "/var/log/httpd/error_log",
"log_group_name": "/aws/ec2/$ENVIRONMENT/httpd/error",
"log_stream_name": "{instance_id}"
}
]
}
}
}
}
EOF
# CloudWatch Agent の起動
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a fetch-config \
-m ec2 \
-c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json \
-s
# 自動起動設定
systemctl enable amazon-cloudwatch-agent
# セキュリティ設定
log "Applying security configurations"
# SSH の設定強化
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
systemctl restart sshd
# ファイアウォール設定
systemctl enable firewalld
systemctl start firewalld
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
# アプリケーションのデプロイ
log "Deploying application"
cd /var/www/html
git clone https://github.com/your-org/your-app.git app
chown -R apache:apache app/
systemctl restart httpd
# ヘルスチェック用エンドポイント
cat > /var/www/html/health.html << EOF
{
"status": "healthy",
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"instance_id": "$(curl -s http://169.254.169.254/latest/meta-data/instance-id)",
"services": {
"httpd": "$(systemctl is-active httpd)",
"cloudwatch-agent": "$(systemctl is-active amazon-cloudwatch-agent)"
}
}
EOF
log "Instance initialization completed successfully"
# 完了通知(SNS等)
aws sns publish \
--topic-arn "arn:aws:sns:us-east-1:123456789012:instance-notifications" \
--message "Instance $(curl -s http://169.254.169.254/latest/meta-data/instance-id) initialized successfully in $ENVIRONMENT environment" \
--subject "Instance Initialization Complete"
log "Initialization complete"
3. 設定・構成管理フェーズ
Ansible による構成管理
# playbook.yml
---
- name: Configure web servers
hosts: web_servers
become: yes
vars:
app_name: "myapp"
app_version: "1.0.0"
environment: "production"
tasks:
- name: Install packages
yum:
name:
- httpd
- php
- php-mysql
- git
- htop
- vim
state: present
- name: Configure Apache
template:
src: httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
backup: yes
notify: restart httpd
- name: Create virtual host
template:
src: vhost.conf.j2
dest: /etc/httpd/conf.d/``{{ app_name }}``.conf
notify: restart httpd
- name: Deploy application
git:
repo: https://github.com/your-org/``{{ app_name }}``.git
dest: /var/www/html/``{{ app_name }}``
version: "``{{ app_version }}``"
force: yes
notify: restart httpd
- name: Set file permissions
file:
path: /var/www/html/``{{ app_name }}``
owner: apache
group: apache
mode: '0755'
recurse: yes
- name: Configure logrotate
template:
src: logrotate.conf.j2
dest: /etc/logrotate.d/``{{ app_name }}``
- name: Setup monitoring
include_tasks: monitoring.yml
- name: Configure backup
include_tasks: backup.yml
handlers:
- name: restart httpd
systemd:
name: httpd
state: restarted
enabled: yes
4. 運用・監視フェーズ
CloudWatch による監視設定
# monitoring_setup.py
import boto3
import json
def setup_comprehensive_monitoring(instance_id, environment):
"""
包括的な監視設定を行う
"""
cloudwatch = boto3.client('cloudwatch')
# カスタムメトリクスの設定
custom_metrics = [
{
'MetricName': 'ApplicationResponseTime',
'Namespace': f'Custom/{environment}',
'Dimensions': [
{
'Name': 'InstanceId',
'Value': instance_id
}
]
},
{
'MetricName': 'ActiveConnections',
'Namespace': f'Custom/{environment}',
'Dimensions': [
{
'Name': 'InstanceId',
'Value': instance_id
}
]
}
]
# アラームの設定
alarms = [
{
'AlarmName': f'{environment}-{instance_id}-HighCPU',
'ComparisonOperator': 'GreaterThanThreshold',
'EvaluationPeriods': 2,
'MetricName': 'CPUUtilization',
'Namespace': 'AWS/EC2',
'Period': 300,
'Statistic': 'Average',
'Threshold': 80.0,
'ActionsEnabled': True,
'AlarmActions': [
'arn:aws:sns:us-east-1:123456789012:high-cpu-alarm'
],
'AlarmDescription': 'High CPU utilization detected',
'Dimensions': [
{
'Name': 'InstanceId',
'Value': instance_id
}
]
},
{
'AlarmName': f'{environment}-{instance_id}-HighMemory',
'ComparisonOperator': 'GreaterThanThreshold',
'EvaluationPeriods': 2,
'MetricName': 'MemoryUtilization',
'Namespace': 'CWAgent',
'Period': 300,
'Statistic': 'Average',
'Threshold': 85.0,
'ActionsEnabled': True,
'AlarmActions': [
'arn:aws:sns:us-east-1:123456789012:high-memory-alarm'
],
'AlarmDescription': 'High memory utilization detected',
'Dimensions': [
{
'Name': 'InstanceId',
'Value': instance_id
}
]
},
{
'AlarmName': f'{environment}-{instance_id}-DiskSpace',
'ComparisonOperator': 'GreaterThanThreshold',
'EvaluationPeriods': 1,
'MetricName': 'DiskSpaceUtilization',
'Namespace': 'CWAgent',
'Period': 300,
'Statistic': 'Average',
'Threshold': 90.0,
'ActionsEnabled': True,
'AlarmActions': [
'arn:aws:sns:us-east-1:123456789012:disk-space-alarm'
],
'AlarmDescription': 'Low disk space detected',
'Dimensions': [
{
'Name': 'InstanceId',
'Value': instance_id
}
]
}
]
# アラーム作成
for alarm in alarms:
try:
cloudwatch.put_metric_alarm(**alarm)
print(f"Created alarm: {alarm['AlarmName']}")
except Exception as e:
print(f"Failed to create alarm {alarm['AlarmName']}: {e}")
return True
# 実行例
if __name__ == "__main__":
instance_id = "i-1234567890abcdef0"
environment = "production"
setup_comprehensive_monitoring(instance_id, environment)
5. メンテナンス・更新フェーズ
自動化されたパッチ管理
#!/bin/bash
# patch_management.sh
set -e
# 設定
ENVIRONMENT="production"
MAINTENANCE_WINDOW="02:00-04:00"
BACKUP_RETENTION_DAYS=30
NOTIFICATION_TOPIC="arn:aws:sns:us-east-1:123456789012:maintenance-notifications"
# ログ設定
LOG_FILE="/var/log/patch_management.log"
exec 1> >(tee -a $LOG_FILE)
exec 2> >(tee -a $LOG_FILE >&2)
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
# 事前チェック
pre_patch_checks() {
log "Starting pre-patch checks"
# ディスク容量チェック
DISK_USAGE=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ $DISK_USAGE -gt 85 ]; then
log "ERROR: Disk usage is $DISK_USAGE%. Aborting patch installation."
exit 1
fi
# サービス状態チェック
CRITICAL_SERVICES=("httpd" "amazon-cloudwatch-agent")
for service in "${CRITICAL_SERVICES[@]}"; do
if ! systemctl is-active --quiet $service; then
log "ERROR: Critical service $service is not running. Aborting patch installation."
exit 1
fi
done
# メモリ使用量チェック
MEMORY_USAGE=$(free | grep Mem | awk '{printf "%.0f", $3/$2 * 100.0}')
if [ $MEMORY_USAGE -gt 90 ]; then
log "WARNING: Memory usage is $MEMORY_USAGE%. Proceeding with caution."
fi
log "Pre-patch checks completed successfully"
}
# バックアップ作成
create_backup() {
log "Creating system backup"
# 重要な設定ファイルのバックアップ
BACKUP_DIR="/opt/backups/$(date +%Y%m%d_%H%M%S)"
mkdir -p $BACKUP_DIR
# 設定ファイル
tar -czf $BACKUP_DIR/system_config.tar.gz \
/etc/httpd/ \
/etc/ssh/ \
/etc/crontab \
/etc/fstab \
/etc/hosts \
/etc/resolv.conf \
2>/dev/null || true
# アプリケーションファイル
tar -czf $BACKUP_DIR/application.tar.gz \
/var/www/html/ \
2>/dev/null || true
# データベースバックアップ(該当する場合)
if systemctl is-active --quiet mysqld; then
mysqldump --all-databases --single-transaction > $BACKUP_DIR/mysql_backup.sql
fi
# S3へのバックアップ
aws s3 cp $BACKUP_DIR/ s3://your-backup-bucket/instances/$(curl -s http://169.254.169.254/latest/meta-data/instance-id)/$(date +%Y%m%d_%H%M%S)/ --recursive
log "Backup created successfully at $BACKUP_DIR"
}
# パッチ適用
apply_patches() {
log "Starting patch installation"
# パッケージリストの更新
yum update -y --security
# 特定のパッケージの更新(必要に応じて)
CRITICAL_PACKAGES=("kernel" "glibc" "openssl" "openssh")
for package in "${CRITICAL_PACKAGES[@]}"; do
if yum list updates $package &>/dev/null; then
log "Updating critical package: $package"
yum update -y $package
fi
done
log "Patch installation completed"
}
# 事後チェック
post_patch_checks() {
log "Starting post-patch checks"
# サービス状態チェック
CRITICAL_SERVICES=("httpd" "amazon-cloudwatch-agent")
for service in "${CRITICAL_SERVICES[@]}"; do
if ! systemctl is-active --quiet $service; then
log "ERROR: Critical service $service is not running after patch installation."
# 自動回復試行
systemctl start $service
sleep 5
if ! systemctl is-active --quiet $service; then
log "ERROR: Failed to restart $service. Manual intervention required."
# 通知送信
aws sns publish \
--topic-arn $NOTIFICATION_TOPIC \
--message "Critical service $service failed to start after patching on $(hostname). Manual intervention required." \
--subject "Patch Installation Error"
fi
fi
done
# アプリケーションヘルスチェック
if ! curl -f http://localhost/health.html &>/dev/null; then
log "ERROR: Application health check failed after patch installation."
# 通知送信
aws sns publish \
--topic-arn $NOTIFICATION_TOPIC \
--message "Application health check failed after patching on $(hostname). Manual intervention required." \
--subject "Patch Installation Error"
fi
log "Post-patch checks completed"
}
# 通知送信
send_notification() {
local status=$1
local message=$2
aws sns publish \
--topic-arn $NOTIFICATION_TOPIC \
--message "$message on $(hostname) at $(date)" \
--subject "Patch Management: $status"
}
# 古いバックアップの削除
cleanup_old_backups() {
log "Cleaning up old backups"
# ローカルバックアップの削除
find /opt/backups -type d -mtime +$BACKUP_RETENTION_DAYS -exec rm -rf {} \;
# S3バックアップの削除(S3 Lifecycle Policy推奨)
aws s3api put-bucket-lifecycle-configuration \
--bucket your-backup-bucket \
--lifecycle-configuration file://backup-lifecycle.json
log "Old backups cleanup completed"
}
# メイン処理
main() {
log "Starting patch management process"
# 開始通知
send_notification "Started" "Patch management process started"
# 処理実行
pre_patch_checks
create_backup
apply_patches
post_patch_checks
cleanup_old_backups
# 完了通知
send_notification "Completed" "Patch management process completed successfully"
log "Patch management process completed successfully"
}
# 実行
main "$@"
6. 最適化・スケーリングフェーズ
自動スケーリング設定
# auto_scaling_setup.py
import boto3
import json
from datetime import datetime, timedelta
class AutoScalingManager:
def __init__(self, region='us-east-1'):
self.autoscaling = boto3.client('autoscaling', region_name=region)
self.cloudwatch = boto3.client('cloudwatch', region_name=region)
def create_scaling_policy(self, asg_name, policy_name, policy_type='TargetTrackingScaling'):
"""
スケーリングポリシーを作成
"""
if policy_type == 'TargetTrackingScaling':
# ターゲット追跡スケーリング
response = self.autoscaling.put_scaling_policy(
AutoScalingGroupName=asg_name,
PolicyName=policy_name,
PolicyType='TargetTrackingScaling',
TargetTrackingConfiguration={
'TargetValue': 70.0,
'PredefinedMetricSpecification': {
'PredefinedMetricType': 'ASGAverageCPUUtilization'
},
'ScaleOutCooldown': 300,
'ScaleInCooldown': 300
}
)
elif policy_type == 'StepScaling':
# ステップスケーリング
response = self.autoscaling.put_scaling_policy(
AutoScalingGroupName=asg_name,
PolicyName=policy_name,
PolicyType='StepScaling',
AdjustmentType='ChangeInCapacity',
StepAdjustments=[
{
'MetricIntervalLowerBound': 0.0,
'MetricIntervalUpperBound': 50.0,
'ScalingAdjustment': 1
},
{
'MetricIntervalLowerBound': 50.0,
'ScalingAdjustment': 2
}
],
Cooldown=300
)
return response['PolicyARN']
def create_scheduled_scaling(self, asg_name, schedule_name, recurrence, min_size, max_size, desired_capacity):
"""
スケジュールベースのスケーリングを作成
"""
self.autoscaling.put_scheduled_update_group_action(
AutoScalingGroupName=asg_name,
ScheduledActionName=schedule_name,
Recurrence=recurrence,
MinSize=min_size,
MaxSize=max_size,
DesiredCapacity=desired_capacity
)
def setup_predictive_scaling(self, asg_name):
"""
予測スケーリングを設定
"""
self.autoscaling.put_scaling_policy(
AutoScalingGroupName=asg_name,
PolicyName='PredictiveScalingPolicy',
PolicyType='PredictiveScaling',
PredictiveScalingConfiguration={
'MetricSpecifications': [
{
'TargetValue': 70.0,
'PredefinedMetricPairSpecification': {
'PredefinedMetricType': 'ASGCPUUtilization'
}
}
],
'Mode': 'ForecastAndScale',
'SchedulingBufferTime': 300,
'MaxCapacityBreachBehavior': 'HonorMaxCapacity',
'MaxCapacityBuffer': 10
}
)
def configure_comprehensive_scaling(self, asg_name, environment):
"""
包括的なスケーリング設定
"""
# 1. CPU ベースのターゲット追跡
cpu_policy_arn = self.create_scaling_policy(
asg_name,
f'{environment}-cpu-target-tracking',
'TargetTrackingScaling'
)
# 2. メモリベースのターゲット追跡
memory_policy_arn = self.autoscaling.put_scaling_policy(
AutoScalingGroupName=asg_name,
PolicyName=f'{environment}-memory-target-tracking',
PolicyType='TargetTrackingScaling',
TargetTrackingConfiguration={
'TargetValue': 80.0,
'CustomizedMetricSpecification': {
'MetricName': 'MemoryUtilization',
'Namespace': 'CWAgent',
'Dimensions': [
{
'Name': 'AutoScalingGroupName',
'Value': asg_name
}
],
'Statistic': 'Average'
},
'ScaleOutCooldown': 300,
'ScaleInCooldown': 300
}
)
# 3. ネットワークベースのターゲット追跡
network_policy_arn = self.autoscaling.put_scaling_policy(
AutoScalingGroupName=asg_name,
PolicyName=f'{environment}-network-target-tracking',
PolicyType='TargetTrackingScaling',
TargetTrackingConfiguration={
'TargetValue': 6000000.0, # 6MB/s
'PredefinedMetricSpecification': {
'PredefinedMetricType': 'ASGAverageNetworkIn'
},
'ScaleOutCooldown': 300,
'ScaleInCooldown': 300
}
)
# 4. スケジュールベースのスケーリング
# 営業時間の開始(平日 9:00)
self.create_scheduled_scaling(
asg_name,
f'{environment}-scale-up-business-hours',
'0 9 * * 1-5', # 平日 9:00 AM
2, 10, 4
)
# 営業時間の終了(平日 18:00)
self.create_scheduled_scaling(
asg_name,
f'{environment}-scale-down-after-hours',
'0 18 * * 1-5', # 平日 6:00 PM
1, 6, 2
)
# 週末の最小構成
self.create_scheduled_scaling(
asg_name,
f'{environment}-scale-down-weekend',
'0 0 * * 6', # 土曜日 12:00 AM
1, 4, 1
)
# 5. 予測スケーリング(本番環境のみ)
if environment == 'production':
self.setup_predictive_scaling(asg_name)
return {
'cpu_policy_arn': cpu_policy_arn,
'memory_policy_arn': memory_policy_arn['PolicyARN'],
'network_policy_arn': network_policy_arn['PolicyARN']
}
# 使用例
if __name__ == "__main__":
manager = AutoScalingManager()
# スケーリング設定の適用
policy_arns = manager.configure_comprehensive_scaling(
'production-web-asg',
'production'
)
print(f"Scaling policies created: {policy_arns}")
7. 廃止・削除フェーズ
安全な廃止プロセス
# instance_decommission.py
import boto3
import json
import time
from datetime import datetime, timedelta
class InstanceDecommissionManager:
def __init__(self, region='us-east-1'):
self.ec2 = boto3.client('ec2', region_name=region)
self.autoscaling = boto3.client('autoscaling', region_name=region)
self.elb = boto3.client('elbv2', region_name=region)
self.cloudwatch = boto3.client('cloudwatch', region_name=region)
self.sns = boto3.client('sns', region_name=region)
def safe_decommission(self, instance_id, reason='planned_retirement'):
"""
安全なインスタンス廃止プロセス
"""
try:
# 1. インスタンス情報の取得
instance_info = self.get_instance_info(instance_id)
# 2. 事前チェック
self.pre_decommission_checks(instance_id, instance_info)
# 3. トラフィック排出
self.drain_traffic(instance_id, instance_info)
# 4. データバックアップ
self.backup_instance_data(instance_id, instance_info)
# 5. 監視・アラートの無効化
self.disable_monitoring(instance_id)
# 6. インスタンスの停止
self.stop_instance(instance_id)
# 7. 最終確認後の削除
self.terminate_instance(instance_id, instance_info)
# 8. 後処理
self.post_decommission_cleanup(instance_id, instance_info)
return True
except Exception as e:
self.send_notification(
'Decommission Failed',
f'Failed to decommission instance {instance_id}: {str(e)}'
)
return False
def get_instance_info(self, instance_id):
"""
インスタンス情報を取得
"""
response = self.ec2.describe_instances(InstanceIds=[instance_id])
instance = response['Reservations'][0]['Instances'][0]
# Auto Scaling Group の確認
asg_name = None
for tag in instance.get('Tags', []):
if tag['Key'] == 'aws:autoscaling:groupName':
asg_name = tag['Value']
break
# Load Balancer の確認
target_groups = self.find_target_groups(instance_id)
return {
'instance': instance,
'asg_name': asg_name,
'target_groups': target_groups,
'state': instance['State']['Name'],
'instance_type': instance['InstanceType'],
'launch_time': instance['LaunchTime']
}
def pre_decommission_checks(self, instance_id, instance_info):
"""
廃止前チェック
"""
# インスタンスの状態確認
if instance_info['state'] not in ['running', 'stopped']:
raise Exception(f"Instance {instance_id} is in {instance_info['state']} state")
# 重要なサービスの確認
if self.is_critical_instance(instance_id, instance_info):
raise Exception(f"Instance {instance_id} is marked as critical")
# 最後のバックアップ確認
last_backup = self.get_last_backup_time(instance_id)
if last_backup < datetime.now() - timedelta(days=1):
raise Exception(f"Last backup for {instance_id} is older than 24 hours")
def drain_traffic(self, instance_id, instance_info):
"""
トラフィックの排出
"""
# Auto Scaling Group からの除外
if instance_info['asg_name']:
self.autoscaling.detach_instances(
InstanceIds=[instance_id],
AutoScalingGroupName=instance_info['asg_name'],
ShouldDecrementDesiredCapacity=True
)
# Target Group からの除外
for tg_arn in instance_info['target_groups']:
self.elb.deregister_targets(
TargetGroupArn=tg_arn,
Targets=[{'Id': instance_id}]
)
# ドレイン完了待機
self.wait_for_draining(tg_arn, instance_id)
def wait_for_draining(self, target_group_arn, instance_id, timeout=300):
"""
ドレイン完了まで待機
"""
start_time = time.time()
while time.time() - start_time < timeout:
response = self.elb.describe_target_health(
TargetGroupArn=target_group_arn,
Targets=[{'Id': instance_id}]
)
if response['TargetHealthDescriptions']:
state = response['TargetHealthDescriptions'][0]['TargetHealth']['State']
if state == 'draining':
print(f"Instance {instance_id} is draining...")
time.sleep(10)
continue
elif state == 'unused':
print(f"Instance {instance_id} drain completed")
return
time.sleep(10)
raise Exception(f"Timeout waiting for instance {instance_id} to drain")
def backup_instance_data(self, instance_id, instance_info):
"""
インスタンスデータのバックアップ
"""
# EBS スナップショットの作成
volumes = []
for bdm in instance_info['instance'].get('BlockDeviceMappings', []):
if 'Ebs' in bdm:
volumes.append(bdm['Ebs']['VolumeId'])
snapshot_ids = []
for volume_id in volumes:
response = self.ec2.create_snapshot(
VolumeId=volume_id,
Description=f"Decommission backup for {instance_id}"
)
snapshot_ids.append(response['SnapshotId'])
# タグ付け
if snapshot_ids:
self.ec2.create_tags(
Resources=snapshot_ids,
Tags=[
{'Key': 'Name', 'Value': f'{instance_id}-decommission-backup'},
{'Key': 'InstanceId', 'Value': instance_id},
{'Key': 'DecommissionDate', 'Value': datetime.now().isoformat()},
{'Key': 'RetentionDays', 'Value': '30'}
]
)
return snapshot_ids
def disable_monitoring(self, instance_id):
"""
監視とアラートの無効化
"""
# CloudWatch アラームの無効化
alarms = self.cloudwatch.describe_alarms()
for alarm in alarms['MetricAlarms']:
for dimension in alarm.get('Dimensions', []):
if dimension['Name'] == 'InstanceId' and dimension['Value'] == instance_id:
self.cloudwatch.disable_alarm_actions(
AlarmNames=[alarm['AlarmName']]
)
print(f"Disabled alarm: {alarm['AlarmName']}")
def stop_instance(self, instance_id):
"""
インスタンスの停止
"""
self.ec2.stop_instances(InstanceIds=[instance_id])
# 停止完了待機
waiter = self.ec2.get_waiter('instance_stopped')
waiter.wait(InstanceIds=[instance_id])
print(f"Instance {instance_id} stopped successfully")
def terminate_instance(self, instance_id, instance_info):
"""
インスタンスの削除
"""
# 最終確認
confirmation = input(f"Are you sure you want to terminate instance {instance_id}? (yes/no): ")
if confirmation.lower() != 'yes':
print("Termination cancelled")
return
self.ec2.terminate_instances(InstanceIds=[instance_id])
# 削除完了待機
waiter = self.ec2.get_waiter('instance_terminated')
waiter.wait(InstanceIds=[instance_id])
print(f"Instance {instance_id} terminated successfully")
def post_decommission_cleanup(self, instance_id, instance_info):
"""
廃止後の後処理
"""
# セキュリティグループの未使用確認
self.check_unused_security_groups(instance_info)
# EIP の解放確認
self.check_unused_elastic_ips(instance_info)
# 通知送信
self.send_notification(
'Instance Decommissioned',
f'Instance {instance_id} has been successfully decommissioned'
)
def send_notification(self, subject, message):
"""
通知の送信
"""
try:
self.sns.publish(
TopicArn='arn:aws:sns:us-east-1:123456789012:decommission-notifications',
Message=message,
Subject=subject
)
except Exception as e:
print(f"Failed to send notification: {e}")
# 使用例
if __name__ == "__main__":
manager = InstanceDecommissionManager()
# インスタンスの安全な廃止
instance_id = "i-1234567890abcdef0"
success = manager.safe_decommission(instance_id, reason="planned_retirement")
if success:
print(f"Instance {instance_id} decommissioned successfully")
else:
print(f"Failed to decommission instance {instance_id}")