Auto Scaling グループでEC2 起動テンプレートを使用する設定手順について

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、「どうやって直すのか?」 という具体的な修復手順(コンソール、AWS CLI、Terraformなど)まで、分かりやすく解説します。
この記事では、EC2 Auto Scalingグループが起動テンプレートを使用していない状態について、リスクと対策を解説します。

ポリシーの説明
Auto Scaling の Security Hub コントロール – AWS Security Hub
このコントロールは、Amazon EC2 Auto Scaling グループが、EC2 起動テンプレートから作成されたものかどうかを確認します。Amazon EC2 Auto Scaling グループが起動テンプレートを使用して作成されていない場合、または混合インスタンスポリシーで起動テンプレートが指定されていない場合、このコントロールは失敗します。
リスク
Amazon EC2 Auto Scalingは、EC2インスタンスの数を自動的に調整し、アプリケーションの可用性とパフォーマンスを維持するサービスです。Auto Scalingグループは、インスタンスの起動設定(Launch Configuration)または起動テンプレート(Launch Template)のいずれかを使用してEC2インスタンスを起動します。しかし、起動テンプレートを使用せず、古い起動設定に依存している場合、以下のような運用上およびセキュリティ上のリスクが発生します。
- 最新機能や改善点へのアクセス制限: 起動設定は、AWSがEC2やAuto Scalingに導入する新しい機能や改善(例:最新のインスタンスタイプ、スポットインスタンスの高度な機能、ネットワークインターフェース設定の柔軟性など)に対応できない場合があります。これにより、最新のテクノロジーを活用した最適化やコスト削減の機会を逃します。
- 設定管理の複雑化: 起動設定では、一部のEC2インスタンス設定が制限されているため、必要に応じてユーザーデータスクリプトで不足分を補う必要があり、設定が複雑になりがちです。起動テンプレートは、より多くのEC2設定を直接サポートするため、管理がシンプルになります。
- セキュリティ設定の適用遅延: 新しいセキュリティ機能やベストプラクティスが導入されても、起動設定ではそれらをすぐに利用できないことがあります。これにより、セキュリティパッチの適用や、より安全な設定への移行が遅れる可能性があります。
- 異なるリソースタイプ間の不整合: 起動テンプレートは、EC2インスタンスだけでなく、スポットインスタンス、Dedicated Hosts、Reserved Instancesなど、様々な購入オプションやキャパシティタイプに対応しています。起動設定ではこれらの柔軟性が低く、異なるリソースタイプを組み合わせた最適な運用が難しい場合があります。
- デプロイメントの柔軟性不足: 起動テンプレートはバージョン管理をサポートしているため、異なる設定のテンプレートバージョンを簡単に切り替えることができます。これにより、A/Bテストやカナリアリリースなどの高度なデプロイ戦略が容易になりますが、起動設定ではこれが困難です。
対策
EC2 Auto Scalingグループで起動テンプレートを使用することは、AWSの最新機能を活用し、設定管理を簡素化し、将来の拡張性に対応するために不可欠です。
- 起動テンプレートへの移行: 既存のAuto Scalingグループが起動設定を使用している場合は、可能な限り起動テンプレートへの移行を計画します。AWS Management Console、AWS CLI、またはTerraformを使用して移行できます。
- バージョン管理の活用: 起動テンプレートのバージョン管理機能を活用し、変更履歴を明確にし、必要に応じて古いバージョンにロールバックできるようにします。これにより、デプロイの安全性が向上します。
- 包括的なインスタンス設定: 起動テンプレートを使用して、AMI、インスタンスタイプ、キーペア、セキュリティグループ、ユーザーデータ、ストレージボリューム、ネットワークインターフェースなど、EC2インスタンスのすべての側面を詳細に定義します。
- 最新のAMIの使用: 起動テンプレート内で、定期的に最新のAMI(Amazon マシンイメージ)を使用するように更新します。これにより、セキュリティパッチが適用された最新のOSやランタイムを使用できます。
- IAMロールの適切な割り当て: インスタンスプロファイルに適切なIAMロールを割り当て、EC2インスタンスが必要なAWSサービスにのみアクセスできるようにします。これは起動テンプレートで設定できます。
- コスト最適化: 起動テンプレートの機能を活用して、オンデマンドインスタンスとスポットインスタンスの組み合わせなど、コスト効率の高い購入オプションを検討します。
修復方法
AWSコンソールでの修復手順
AWSコンソールを使用して、既存のEC2 Auto Scalingグループを起動テンプレートに移行します。
- EC2サービスへ移動:
- AWSコンソールにログインし、EC2サービスを開きます。
- Auto Scalingグループの選択:
- 左側のナビゲーションペインで「Auto Scaling グループ」を選択します。
- 起動テンプレートに移行したいAuto Scalingグループを選択します。
- 既存の起動設定からの起動テンプレート作成:
- グループの詳細ページで、「詳細」タブを選択し、「起動設定」の項目を確認します。
- 起動設定の名前をクリックし、起動設定の詳細ページへ移動します。
- 「アクション」ドロップダウンメニューから「テンプレートから起動テンプレートを作成」を選択します。
- 必要な情報を入力し、新しい起動テンプレートを作成します。この際、元の起動設定のほとんどの設定が自動的に引き継がれます。
- Auto Scalingグループの更新:
- 再びAuto Scalingグループの詳細ページに戻り、「編集」をクリックします。
- 「起動テンプレート」セクションで、先ほど作成した新しい起動テンプレートを選択します。
- *「バージョン」ドロップダウンから、使用したい起動テンプレートのバージョン(通常は最新バージョン)を選択します。
- 「更新」をクリックして変更を適用します。
- インスタンスのリフレッシュ (オプション):
- Auto Scalingグループが新しいインスタンスを起動する際には、新しい起動テンプレートが使用されます。既存のインスタンスも新しい設定に更新したい場合は、「インスタンス管理」タブから「インスタンスのリフレッシュ」を開始することで、古いインスタンスを順次終了し、新しいインスタンスで置き換えることができます。

Terraformでの修復手順
TerraformでEC2 Auto Scalingグループに起動テンプレートを使用させるには、aws_launch_template
リソースを定義し、それを aws_autoscaling_group
リソースの launch_template
ブロックで参照します。
注: 起動設定 (aws_launch_configuration
) と起動テンプレート (aws_launch_template
) は排他的です。同じAuto Scalingグループで両方を同時に使用することはできません。既存のaws_launch_configuration
を使用しているAuto ScalingグループをTerraformで移行する場合、まずそのaws_launch_configuration
の定義を削除またはコメントアウトし、代わりにaws_launch_template
と関連するaws_autoscaling_group
の設定を追加する必要があります。
# EC2 Auto Scalingグループで使用する起動テンプレートを定義
resource "aws_launch_template" "my_app_launch_template" {
name_prefix = "my-app-lt-"
image_id = "ami-0abcdef1234567890" # 使用するAMI IDに置き換えてください (例: 最新のAmazon Linux 2 AMIなど)
instance_type = "t3.medium" # インスタンスタイプを適切に選択
key_name = "my-ec2-keypair" # 使用するキーペア名に置き換えてください (オプション)
# セキュリティグループの指定 (適切なセキュリティグループIDに置き換え)
vpc_security_group_ids = [aws_security_group.app_instance_sg.id]
# (オプション) 詳細なモニタリングを有効にする
monitoring {
enabled = true
}
# (オプション) EBSボリュームの設定
block_device_mappings {
device_name = "/dev/xvda"
ebs {
volume_size = 30
volume_type = "gp3"
encrypted = true
delete_on_termination = true
}
}
# (オプション) インスタンスにアタッチするIAMロール
iam_instance_profile {
name = aws_iam_instance_profile.app_instance_profile.name
}
# (オプション) ユーザーデータ (Base64エンコード推奨)
user_data = base64encode(<<EOF
#!/bin/bash
echo "Hello from user data!" > /tmp/user-data.log
sudo yum update -y
sudo yum install -y httpd
sudo systemctl start httpd
sudo systemctl enable httpd
EOF
)
tags = {
Name = "MyAppLaunchTemplate"
}
}
# Auto Scalingグループの定義
resource "aws_autoscaling_group" "my_app_asg" {
name = "my-application-asg"
# 起動テンプレートを参照
launch_template {
id = aws_launch_template.my_app_launch_template.id
version = "$Latest" # 常に最新バージョンを使用
}
min_size = 1
max_size = 3
desired_capacity = 1
vpc_zone_identifier = [aws_subnet.public_a.id, aws_subnet.public_c.id] # あなたのサブネットIDに置き換え
# (オプション) ELB/ALBへのアタッチ (ALBの場合)
# target_group_arns = [aws_lb_target_group.my_app_tg.arn]
health_check_type = "EC2" # ALB/CLBと連携する場合は "ELB"
health_check_grace_period = 300 # 秒
tag {
key = "Name"
value = "MyAppInstance"
propagate_at_launch = true
}
tag {
key = "Environment"
value = "Development"
propagate_at_launch = true
}
}
# 関連リソースの定義例 (Security Group, IAM Role, Subnet など)
# これらはあなたの環境に合わせて定義または参照してください。
resource "aws_security_group" "app_instance_sg" {
name = "app-instance-security-group"
description = "Allow inbound HTTP traffic to app instances"
vpc_id = aws_vpc.main.id # あなたのVPC IDに置き換え
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # 適切なIP範囲に制限してください
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["YOUR_TRUSTED_IP_RANGE/32"] # SSHアクセス元IPアドレスに制限
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_iam_role" "ecs_instance_role" {
name = "my-app-instance-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "ec2.amazonaws.com"
}
},
]
})
}
resource "aws_iam_instance_profile" "app_instance_profile" {
name = "my-app-instance-profile"
role = aws_iam_role.ecs_instance_role.name
}
# (S3バケットへのアクセスなど、インスタンスに付与したいポリシーをここに定義)
resource "aws_iam_role_policy" "example_policy" {
name = "my-app-instance-policy"
role = aws_iam_role.ecs_instance_role.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"s3:GetObject",
"s3:ListBucket"
],
Resource = "*" # より限定されたリソースに制限してください
},
]
})
}
# VPCおよびサブネットの定義例 (必要に応じて)
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "main-vpc"
}
}
resource "aws_subnet" "public_a" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-1a" # あなたのリージョンに合わせて変更
tags = {
Name = "public-subnet-a"
}
}
resource "aws_subnet" "public_c" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24"
availability_zone = "ap-northeast-1c" # あなたのリージョンに合わせて変更
tags = {
Name = "public-subnet-c"
}
}
上記のTerraformコードでは、aws_launch_template
リソースでEC2インスタンスの起動に関する詳細な設定(AMI、インスタンスタイプ、セキュリティグループ、ユーザーデータなど)を定義し、そのテンプレートを aws_autoscaling_group
リソースの launch_template
ブロックで参照しています。version = "$Latest"
を指定することで、常に起動テンプレートの最新バージョンが使用されるように設定しています。
ami-0abcdef1234567890
や my-ec2-keypair
、your-email@example.com
、YOUR_TRUSTED_IP_RANGE/32
などのプレースホルダーは、実際の環境に合わせて修正してください。
最後に
この記事では、EC2 Auto Scalingグループが起動テンプレートを使用していない状態について、リスクと対策を解説しました。起動テンプレートの使用は、Auto Scalingグループの設定をより柔軟で管理しやすくし、EC2の最新機能を活用するためのベストプラクティスです。これにより、アプリケーションの可用性、スケーラビリティ、セキュリティ、およびコスト効率を向上させることができます。
この問題の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。
運用が非常に楽に出来る製品になっていますので、ぜひ興味がある方はお問い合わせお待ちしております。
最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。