ECSサービスにてFargate のプラットフォームバージョンのアップデート手順

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、「どうやって直すのか?」 という具体的な修復手順(コンソール、AWS CLI、Terraformなど)まで、分かりやすく解説します。

この記事では、Fargateを使用するサービスのプラットフォームバージョンが最新に設定されていない状態について、リスクと対策を解説します。

ポリシーの説明

Amazon ECS の Security Hub コントロール – AWS Security Hub

このコントロールは、Amazon ECS Fargate サービスが最新バージョンの Fargate プラットフォームで実行されているかどうかをチェックします。プラットフォームが最新バージョンでない場合、このコントロールは失敗します。

リスク

Amazon ECS Fargateは、サーバーやクラスターの管理なしにコンテナを実行できる、サーバーレスのコンピュートエンジンです。Fargateのプラットフォームバージョンは、基盤となるインフラストラクチャ(カーネル、オペレーティングシステム、コンテナランタイムなど)のバージョンを示し、AWSによって定期的に更新されます。Fargateを使用するサービスのプラットフォームバージョンが最新に設定されていない場合、以下のようなセキュリティと運用上のリスクが発生します。

  • セキュリティ脆弱性の露出: 古いプラットフォームバージョンは、既知のセキュリティ脆弱性を含んでいる可能性があります。AWSは新しいバージョンでこれらの脆弱性を修正しますが、古いバージョンを使い続けると、潜在的な攻撃のターゲットとなるリスクが高まります。
  • 最新機能やパフォーマンス改善の未利用: 新しいプラットフォームバージョンには、コンテナの起動速度向上、リソース利用効率の改善、新しいネットワーキング機能など、パフォーマンスや機能に関する重要な更新が含まれることがあります。最新バージョンを利用しないと、これらのメリットを享受できません。
  • バグや問題の継続: AWSは、古いプラットフォームバージョンで発見されたバグや運用上の問題を修正するために、新しいバージョンをリリースします。古いバージョンに留まると、これらの問題が解決されず、アプリケーションの不安定性や予期せぬ挙動につながる可能性があります。
  • トラブルシューティングの複雑化: 問題が発生した際、古いプラットフォームバージョンを使用していると、AWSのサポートチームも最新のベストプラクティスに基づいた支援を提供しにくくなることがあります。また、コミュニティで共有される解決策も最新バージョンを前提としていることが多いため、トラブルシューティングが難しくなります。
  • コンプライアンス要件への対応遅延: 一部のセキュリティおよびコンプライアンス基準では、基盤となるインフラストラクチャを最新の状態に保つことが求められる場合があります。古いプラットフォームバージョンを使用し続けると、これらの要件を満たせなくなる可能性があります。

対策

Fargateを使用するサービスのプラットフォームバージョンを常に最新に設定することは、セキュリティを確保し、最新の機能とパフォーマンス改善を活用するために不可欠です。

  • サービス定義でのプラットフォームバージョン指定: ECSサービスをデプロイする際、LATEST というプラットフォームバージョンを指定します。これにより、AWSが新しいプラットフォームバージョンをリリースするたびに、次回タスクが起動する際に自動的に最新のバージョンが適用されます。
  • 既存サービスの更新: 既存のFargateサービスが特定の古いプラットフォームバージョンに固定されている場合は、サービス定義を更新して LATEST を使用するように変更します。その後、サービスの強制デプロイを実行して、既存のタスクを最新プラットフォームバージョンで起動し直す必要があります。
  • デプロイプロセスの自動化: CI/CDパイプラインに、Fargateサービスのプラットフォームバージョンを LATEST に設定し、必要に応じて強制的に新しいタスクを起動するステップを組み込むことを推奨します。
  • モニタリングとテスト: 新しいプラットフォームバージョンが自動的に適用された後も、アプリケーションの動作に問題がないか、CloudWatchメトリクスやログを通じて継続的にモニタリングします。本番環境への適用前に、テスト環境で新しいプラットフォームバージョンでの動作を確認することが理想的です。

修復方法

AWSコンソールでの修復手順

AWSコンソールを使用して、Fargateサービスが最新のプラットフォームバージョンを使用するように設定します。

  1. ECSサービスへ移動:
    • AWSコンソールにログインし、ECSサービスを開きます。
  2. クラスターを選択:
    • 左側のナビゲーションペインで「クラスター」を選択し、目的のECSクラスターをクリックします。
  3. サービスを選択:
    • クラスターの詳細ページで、「サービス」タブに移動し、設定を変更したいFargateサービスの名前をクリックします。
  4. サービスを更新:
    • サービスの詳細ページで「更新」ボタンをクリックします。
  5. プラットフォームバージョンの設定:
    • 「デプロイ設定」セクションまでスクロールします。
    • 「プラットフォームバージョン」のドロップダウンメニューで、「LATEST」を選択します。
    • (既存のタスクをすぐに更新したい場合)「強制的に新しいデプロイをデプロイ」にチェックを入れます。これにより、既存のタスクが停止され、新しいプラットフォームバージョンで新しいタスクが起動されます。
  6. 変更を適用:
    • 設定の変更を確認し、「更新」ボタンをクリックしてサービスを更新します。

Terraformでの修復手順

TerraformでFargateを使用するECSサービスが最新のプラットフォームバージョンを使用するように設定するには、aws_ecs_service リソースの platform_version パラメータを "LATEST" に設定します。

# ECSクラスターの定義 (既存のものを使用するか、ここで定義)
resource "aws_ecs_cluster" "my_ecs_cluster" {
  name = "my-fargate-cluster"
  # 必要に応じてContainer Insightsなどの設定を追加
  setting {
    name  = "containerInsights"
    value = "enabled"
  }
}

# ECSタスク定義の定義 (Fargate互換)
resource "aws_ecs_task_definition" "my_app_task" {
  family                   = "my-fargate-app"
  cpu                      = "256"
  memory                   = "512"
  network_mode             = "awsvpc"
  requires_compatibilities = ["FARGATE"]
  execution_role_arn       = aws_iam_role.ecs_task_execution_role.arn # 後述のIAMロールを参照

  container_definitions = jsonencode([
    {
      name      = "my-container"
      image     = "nginx:latest" # あなたのコンテナイメージに置き換え
      portMappings = [
        {
          containerPort = 80
          hostPort      = 80
          protocol      = "tcp"
        }
      ]
      logConfiguration = {
        logDriver = "awslogs"
        options = {
          "awslogs-group"         = aws_cloudwatch_log_group.ecs_logs.name
          "awslogs-region"        = data.aws_region.current.name
          "awslogs-stream-prefix" = "ecs"
        }
      }
    }
  ])

  tags = {
    Name = "MyFargateTaskDefinition"
  }
}

# ECSサービスを定義 (Fargate上で実行)
resource "aws_ecs_service" "my_app_service" {
  name            = "my-fargate-service"
  cluster         = aws_ecs_cluster.my_ecs_cluster.id
  task_definition = aws_ecs_task_definition.my_app_task.arn
  desired_count   = 1 # 必要なタスク数に調整
  launch_type     = "FARGATE"

  # Fargateサービスのプラットフォームバージョンを "LATEST" に設定
  platform_version = "LATEST"

  network_configuration {
    subnets          = [aws_subnet.public_a.id, aws_subnet.public_c.id] # あなたのサブネットIDに置き換え
    security_groups  = [aws_security_group.ecs_fargate_sg.id] # 適切なセキュリティグループに置き換え
    assign_public_ip = true
  }

  # (オプション) 強制的に新しいデプロイを開始したい場合 (例えば、既存タスクを更新する場合)
  # deployment_force_new_deployment = true

  tags = {
    Name = "MyFargateService"
  }
}

# CloudWatch Logsグループ (コンテナログ用)
resource "aws_cloudwatch_log_group" "ecs_logs" {
  name              = "/ecs/my-fargate-app"
  retention_in_days = 30 # ログの保持期間 (必要に応じて変更)
}

# ECSタスク実行ロール (FargateがCloudWatch LogsやECRにアクセスするため)
resource "aws_iam_role" "ecs_task_execution_role" {
  name = "ecs-task-execution-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "ecs-tasks.amazonaws.com"
        }
      },
    ]
  })
}

# ECSタスク実行ロールに管理ポリシーをアタッチ
resource "aws_iam_role_policy_attachment" "ecs_task_execution_role_policy" {
  role       = aws_iam_role.ecs_task_execution_role.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}

# セキュリティグループの定義 (Fargateタスク用)
resource "aws_security_group" "ecs_fargate_sg" {
  name        = "ecs-fargate-security-group"
  description = "Allow inbound traffic to Fargate tasks"
  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範囲に制限してください
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  tags = {
    Name = "FargateSecurityGroup"
  }
}

# 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"
  }
}

# 現在のAWSリージョンを取得するためのデータソース
data "aws_region" "current" {}

上記のTerraformコードでは、aws_ecs_service リソースの platform_version パラメータを "LATEST" に設定しています。これにより、Fargateサービスは常に利用可能な最新のプラットフォームバージョンでタスクを起動するようになります。

nginx:latestmy-fargate-clusteryour-email@example.comYOUR_TRUSTED_IP_RANGE/32 などのプレースホルダーは、実際の環境に合わせて修正してください。

最後に

この記事では、Fargateを使用するサービスのプラットフォームバージョンが最新に設定されていない状態について、リスクと対策を解説しました。Fargateのプラットフォームバージョンを常に最新に保つことは、コンテナ化されたアプリケーションのセキュリティ、パフォーマンス、および信頼性を確保するためのベストプラクティスです。これにより、AWSが提供する最新の改善点を自動的に活用し、安全で効率的なコンテナ環境を維持できます。

この問題の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。

運用が非常に楽に出来る製品になっていますので、ぜひ興味がある方はお問い合わせお待ちしております。

最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです

この記事をシェアする

クラウドセキュリティ対策実践集一覧へ戻る

貴社の利用状況に合わせた見積もりを作成します。

料金プランを詳しく見る