🗂

AWS学びなおし(+TF)_fargate

2025/03/08に公開

AWS Fargateは、コンテナ型のアプリケーションをデプロイ・実行するための、サーバーレスコンピューティングエンジンです。具体的には、Amazon Elastic Container Service (ECS) および Amazon Elastic Kubernetes Service (EKS) で利用できる起動タイプの一つであり、コンテナを実行するための基盤となるサーバー (EC2インスタンス) の管理をAWSに完全に委任できます。

従来のコンテナ実行環境との違い

従来のコンテナ実行環境 (ECS on EC2, EKS on EC2) では、ユーザー自身がEC2インスタンスのプロビジョニング、パッチ適用、スケーリング、メンテナンスを行う必要がありました。これは、インフラ管理の負担が大きく、コンテナオーケストレーションの複雑さを増す要因となっていました。

Fargateを利用することで、これらのサーバー管理作業から解放され、コンテナ化されたアプリケーションの開発と運用に集中できます。AWSが裏側でコンテナを実行するためのインフラを自動的に管理してくれるため、ユーザーはコンテナの定義 (CPU, メモリ, ネットワーク設定など) とアプリケーションのロジックに専念できます。

Fargateの主なメリット

  • サーバーレス: EC2インスタンスの管理が不要。インフラストラクチャの運用から解放され、アプリケーション開発に集中できる。
  • シンプルなスケーリング: コンテナの需要に応じて自動的にスケールアップ/ダウン。インフラのスケーリングを意識する必要がない。
  • 高可用性と安全性: AWSが基盤インフラを管理するため、可用性とセキュリティが確保される。
  • コスト効率: コンテナが実際に消費したCPUとメモリに対してのみ課金される従量課金制。EC2インスタンスのようにアイドル状態のリソースに対する課金が発生しない。
  • 統合されたエコシステム: ECS/EKSとシームレスに統合されており、既存のAWSサービス (ロードバランサー, VPC, IAM, CloudWatchなど) と容易に連携できる。

Fargateの主なデメリット

  • 柔軟性の制限: EC2インスタンスに比べて、基盤となるOSやミドルウェアへのアクセスが制限される。高度なカスタマイズが必要なワークロードには不向きな場合がある。
  • コールドスタート: コンテナの起動にEC2インスタンスよりも時間がかかる場合がある (特に起動頻度が低いアプリケーション)。
  • 料金: EC2インスタンスと比較して、CPU/メモリあたりの料金は高めに設定されている。常に高負荷なワークロードにはコストが高くなる可能性がある。
  • GPUワークロードの非対応: 現時点ではGPUを利用するコンテナワークロードには対応していない。
  • 一部機能の制限: ECS on EC2/EKS on EC2 に比べて、利用できる機能に一部制限がある場合がある (例: 特権コンテナ)。

Fargateが適しているユースケース

  • マイクロサービス: ステートレスで独立性の高いマイクロサービスに最適。
  • APIサーバー: Web APIなどのバックエンドサービス。
  • バッチ処理: 短時間で完了するバッチ処理ジョブ。
  • Webアプリケーション: トラフィック変動が大きく、自動スケーリングが求められるWebアプリケーション。
  • CI/CDパイプライン: コンテナイメージのビルドやテストなどのCI/CDタスク。

Fargateが不向きなユースケース

  • GPUを利用するワークロード: 機械学習推論、動画処理など。
  • ステートフルアプリケーション: データベース、キャッシュサーバーなど (EFSなどの永続ストレージとの連携は可能ですが、EC2インスタンスと比較して複雑になる場合があります)。
  • 高度なカスタマイズが必要なワークロード: OSレベルのチューニング、カーネルモジュールのロードなど。
  • 常に高負荷で長時間稼働するワークロード: コスト面でEC2インスタンスの方が有利な場合がある。

ECSとEKSにおけるFargate

FargateはECSとEKSの両方で利用できますが、それぞれ少しずつ特徴が異なります。

  • ECS on Fargate: ECSネイティブのオーケストレーション機能を利用し、比較的シンプルなコンテナアプリケーションの実行に適しています。学習コストが低く、手軽にサーバーレスコンテナ環境を構築できます。
  • EKS on Fargate: Kubernetesの強力なオーケストレーション機能を利用し、より複雑なコンテナアプリケーションやマイクロサービスアーキテクチャに適しています。Kubernetesの豊富な機能 (デプロイメント、サービス、Ingressなど) を活用できますが、ECS on Fargateよりも学習コストが高くなります。

どちらを選択するかは、アプリケーションの複雑さ、チームのスキルセット、運用要件などによって異なります。

【実務レベルの内容と重要事項】

Fargateを実務で利用する上で、以下の点が重要になります。

1. ネットワーク設定 (VPC, サブネット, セキュリティグループ)

  • FargateタスクはVPC内のサブネットで実行されます。プライベートサブネットでの実行が推奨され、インターネットへのアクセスが必要な場合はNAT Gatewayなどを経由します。
  • セキュリティグループを設定し、タスクへのインバウンド/アウトバウンドトラフィックを制御します。最小限の権限の原則に基づき、必要なポートのみを許可します。
  • VPCエンドポイント (S3, ECR, CloudWatch Logsなど) を利用することで、インターネットを経由せずにAWSサービスにアクセスできます。

2. IAMロールと権限管理

  • FargateタスクにIAMロールを付与し、タスク内で実行されるアプリケーションがAWSリソースにアクセスするための権限を管理します。
  • 最小権限の原則に基づき、タスクに必要な最小限の権限のみを付与します。
  • ECSタスク実行ロール (Task Execution Role) と ECSタスクロール (Task Role) の違いを理解し、適切に設定する必要があります。

3. コンテナイメージの最適化

  • コンテナイメージサイズを小さくすることで、イメージのダウンロード時間と起動時間を短縮できます。
  • マルチステージビルドを活用し、不要なツールやライブラリを最終イメージから削除します。
  • ベースイメージを軽量なもの (Alpine Linuxなど) に変更することを検討します。
  • コンテナイメージレジストリ (ECR) を利用し、イメージの管理と配信を効率化します。

4. リソース設定 (CPU, メモリ)

  • Fargateタスクに割り当てるCPUとメモリを適切に設定することが重要です。リソース不足はアプリケーションのパフォーマンス低下やエラーの原因となります。
  • ワークロードの特性に合わせて、適切なリソース量を決定する必要があります。
  • CloudWatch Container Insightsなどを利用して、リソース使用率を監視し、必要に応じてリソース設定を調整します。

5. ロギングとモニタリング

  • FargateタスクのログをCloudWatch Logsに出力するように設定します。アプリケーションログだけでなく、ECSエージェントのログも収集することで、問題発生時の原因究明に役立ちます。
  • CloudWatchメトリクスやContainer Insightsを利用して、タスクのCPU使用率、メモリ使用率、ネットワークトラフィックなどを監視します。
  • CloudWatchアラームを設定し、異常を検知したら通知を受け取れるようにします。

6. 永続ストレージ

  • Fargateタスクはステートレスであることが原則ですが、EFS (Elastic File System) を利用することで、複数のタスク間で共有可能な永続ストレージをマウントできます。
  • EBS (Elastic Block Storage) はFargateタスクに直接アタッチすることはできません。
  • S3などのオブジェクトストレージも、アプリケーションから利用できます。

7. コスト最適化

  • Fargate Spotを利用することで、通常料金よりも大幅に割引された価格でFargateタスクを実行できます (中断される可能性があるため、耐障害性のあるワークロード向け)。
  • タスクのリソース設定 (CPU, メモリ) を最適化し、過剰なリソース割り当てを避けることで、コストを削減できます。
  • 不要なタスクを停止または削除し、リソースの無駄をなくします。
  • Savings Plans for Compute や EC2 Spot Instances と同様の割引プランが提供される可能性も考慮し、最新情報を確認します。

8. デプロイ戦略

  • ローリングアップデート、ブルー/グリーンデプロイメントなどのデプロイ戦略を検討し、アプリケーションのダウンタイムを最小限に抑えるようにします。
  • ECS Blue/Green デプロイメントなどのマネージドなデプロイ機能を利用することもできます。

9. セキュリティ

  • コンテナイメージの脆弱性スキャンを定期的に実施し、脆弱性が見つかった場合は速やかに修正します。
  • コンテナレジストリ (ECR) のアクセス制御を適切に設定し、不正アクセスを防止します。
  • FargateタスクのIAMロールを最小限の権限に設定し、セキュリティリスクを低減します。
  • セキュリティグループを設定し、不要なポートを閉じます。

10. 制限事項の把握

  • Fargateにはいくつかの制限事項があります (例: 特権コンテナの非サポート、ホストネットワークモードの非サポートなど)。
  • ワークロードの要件とFargateの制限事項を照らし合わせ、Fargateが適切な選択肢であるか事前に確認する必要があります。
  • AWSのドキュメントやFAQなどを参照し、最新の制限事項を把握しておきましょう。

【実務でどの程度使用されるのか】

Fargateは実務で広く利用されています。特に、マイクロサービスアーキテクチャを採用する企業や、コンテナ技術を積極的に活用する企業での採用事例が増えています。

利用が拡大している背景

  • サーバーレスの恩恵: インフラ管理の負担軽減は、開発チームにとって大きなメリットです。開発者はアプリケーション開発に集中でき、開発スピードの向上や運用コストの削減につながります。
  • コンテナ技術の普及: Dockerなどのコンテナ技術がデファクトスタンダードとなり、コンテナ化されたアプリケーションが増加していることも、Fargateの利用を後押ししています。
  • AWSのマネージドサービスの進化: ECSやEKSなどのマネージドサービスが成熟し、Fargateとの連携も強化されています。より簡単に、より安定してコンテナ環境を構築・運用できるようになりました。
  • コスト効率の向上: Fargateの料金体系は従量課金制であり、無駄なリソースに対する課金が発生しません。特に、トラフィック変動が大きいワークロードや、間欠的に実行されるワークロードにおいて、コストメリットを享受できます。

具体的な利用例

  • Webアプリケーションのバックエンド: APIサーバー、WebアプリケーションサーバーなどをFargateで実行し、自動スケーリングと高可用性を実現。
  • バッチ処理: 定期的なバッチ処理ジョブ、データ変換処理などをFargateで実行。
  • イベントドリブンなアプリケーション: SQS, SNS, EventBridgeなどのイベントソースからのイベントに応じて、Fargateタスクを起動し処理を実行。
  • CI/CDパイプライン: コンテナイメージのビルド、テスト、デプロイなどのCI/CDタスクをFargateで実行。
  • 機械学習推論: 機械学習モデルの推論エンドポイントをFargateでデプロイし、スケーラブルな推論サービスを提供 (GPU非対応のため、CPUベースの推論に限る)。

利用時の考慮事項

  • ワークロードの特性: Fargateはステートレスなワークロードに適しています。ステートフルなアプリケーションの場合は、EFSやAuroraなどの永続ストレージとの連携を検討する必要があります。
  • コスト: 常に高負荷なワークロードの場合は、EC2インスタンスの方がコスト効率が良い場合があります。ワークロードの特性に応じて、適切なプラットフォームを選択する必要があります。
  • 学習コスト: Fargate自体は比較的簡単に利用開始できますが、ECS/EKSや関連するAWSサービス (VPC, IAM, CloudWatchなど) についての知識が必要です。
  • 運用体制: Fargateを利用する場合でも、アプリケーションの監視、ログ収集、トラブルシューティングなどの運用作業は必要です。適切な運用体制を構築する必要があります。

結論

Fargateは、サーバーレスコンテナ実行環境として、実務で広く利用されており、今後もその利用は拡大していくと予想されます。インフラ管理の負担を軽減し、アプリケーション開発に集中したい場合や、自動スケーリングと高可用性を実現したい場合に、有力な選択肢となります。ただし、ワークロードの特性やコスト、運用体制などを考慮し、適切なプラットフォームを選択することが重要です。

【terraformのコードで記述する場合の基本的内容と実務レベルの内容】

TerraformでFargateを記述する場合の基本と実務レベルの内容を解説します。

基本的なTerraformコード (ECS on Fargate)

まずはECS on Fargateの基本的な構成をTerraformで記述する例です。

resource "aws_ecs_cluster" "example" {
  name = "example-cluster"
}

resource "aws_ecs_task_definition" "example" {
  family               = "example-task-definition"
  network_mode         = "awsvpc" # Fargateではawsvpcネットワークモードが必須
  requires_compatibilities = ["FARGATE"] # 起動タイプにFARGATEを指定
  cpu                  = 256      # 0.25 vCPU
  memory               = 512      # 0.5 GB
  execution_role_arn   = aws_iam_role.ecs_task_execution_role.arn # ECSタスク実行ロール
  task_role_arn        = aws_iam_role.ecs_task_role.arn          # ECSタスクロール

  container_definitions = jsonencode([
    {
      name      = "example-container",
      image     = "public.ecr.aws/nginx/nginx:latest", # コンテナイメージ
      portMappings = [
        {
          containerPort = 80
          hostPort      = 80
        }
      ]
    }
  ])
}

resource "aws_ecs_service" "example" {
  name            = "example-service"
  cluster         = aws_ecs_cluster.example.id
  task_definition = aws_ecs_task_definition.example.arn
  desired_count   = 1
  launch_type     = "FARGATE" # 起動タイプにFARGATEを指定
  network_configuration {
    subnets          = [aws_subnet.private_subnet_1.id, aws_subnet.private_subnet_2.id] # サブネット
    security_groups = [aws_security_group.ecs_tasks.id] # セキュリティグループ
  }
}

# (VPC, サブネット, セキュリティグループ, IAMロールなどのリソース定義は省略)

コードの解説

  • aws_ecs_cluster: ECSクラスタを作成します。
  • aws_ecs_task_definition: ECSタスク定義を作成します。
    • network_mode = "awsvpc": Fargateではawsvpcネットワークモードが必須です。
    • requires_compatibilities = ["FARGATE"]: 起動タイプにFARGATEを指定します。
    • cpu, memory: タスクに割り当てるCPUとメモリを指定します。FargateのCPU/メモリ組み合わせは事前に定義された範囲から選択する必要があります。
    • execution_role_arn: ECSタスク実行ロール (コンテナイメージのプル、ログ出力などのECSエージェントに必要な権限) を指定します。
    • task_role_arn: ECSタスクロール (コンテナ内で実行されるアプリケーションがAWSリソースにアクセスするための権限) を指定します。
    • container_definitions: コンテナの定義 (イメージ、ポートマッピングなど) をJSON形式で記述します。
  • aws_ecs_service: ECSサービスを作成します。
    • launch_type = "FARGATE": 起動タイプにFARGATEを指定します。
    • network_configuration: ネットワーク設定 (サブネット、セキュリティグループ) を指定します。

実務レベルのTerraformコード

実務レベルでは、上記の基本コードに加えて、以下の要素を考慮する必要があります。

1. モジュール化

  • Fargateの構成をモジュール化することで、コードの再利用性と可読性を高めます。
  • 例えば、VPC、ECSクラスタ、Fargateサービスなどをそれぞれモジュール化し、組み合わせて利用します。

2. 変数定義

  • 環境 (開発環境、本番環境など) やリージョン、アベイラビリティゾーンなどのパラメータを変数として定義し、コードの柔軟性を高めます。
  • variables.tf ファイルなどで変数を定義し、terraform.tfvars ファイルなどで環境ごとの値を設定します。

3. プロビジョナー

  • 必要に応じて、ローカルプロビジョナーやリモートプロビジョナーを利用して、コンテナイメージのビルド、設定ファイルのデプロイ、アプリケーションの初期設定などを行います。
  • ただし、プロビジョナーはTerraformの管理外のリソースに影響を与えるため、慎重に利用する必要があります。

4. リモートバックエンド

  • Terraformの状態ファイル (terraform.tfstate) をローカルに保存するのではなく、S3などのリモートバックエンドに保存することで、チームでの共同作業や状態ファイルの安全性を高めます。
  • DynamoDBによる状態ファイルのロックも有効にすることで、コンフリクトを防止できます。

5. ネットワーク設定の詳細

  • パブリックサブネットとプライベートサブネットを適切に構成し、Fargateタスクはプライベートサブネットで実行するようにします。
  • NAT GatewayやVPCエンドポイントを利用して、インターネットアクセスやAWSサービスへのアクセスを安全に行えるようにします。
  • ロードバランサー (ALB, NLB) と連携し、外部からのトラフィックをFargateタスクに分散します。

6. セキュリティ設定の詳細

  • セキュリティグループを詳細に設定し、必要なポートのみを許可します。
  • IAMロールを最小権限の原則に基づき設定します。
  • KMS (Key Management Service) を利用して、機密情報を暗号化します。

7. 監視・ロギング設定

  • CloudWatch Logsへのログ出力設定をTerraformで記述します。
  • CloudWatchメトリクスやContainer Insightsの監視設定もTerraformで記述することを検討します。
  • CloudWatchアラームの設定もTerraformで記述し、異常検知を自動化します。

8. スケーリング設定

  • ECSサービスのスケーリング設定 (Auto Scaling) をTerraformで記述し、負荷に応じて自動的にタスク数を増減させるようにします。
  • ターゲット追跡スケーリングやステップスケーリングなどのスケーリングポリシーを適切に設定します。

9. デプロイ戦略

  • ブルー/グリーンデプロイメントなどのデプロイ戦略をTerraformで実現することを検討します。
  • ECS Blue/Green デプロイメント機能をTerraformで利用することもできます。

実務レベルのTerraformコード例 (一部)

# variables.tf
variable "environment" {
  type        = string
  description = "Environment name (e.g., dev, prod)"
}

variable "aws_region" {
  type        = string
  default     = "ap-northeast-1"
  description = "AWS region"
}

# terraform.tfvars (例: development環境)
environment = "dev"
# main.tf (一部抜粋)
module "ecs_fargate_service" {
  source  = "./modules/ecs_fargate_service"
  environment = var.environment
  cluster_name = aws_ecs_cluster.example.name
  task_definition_arn = aws_ecs_task_definition.example.arn
  desired_count = 2
  subnet_ids = [aws_subnet.private_subnet_1.id, aws_subnet.private_subnet_2.id]
  security_group_ids = [aws_security_group.ecs_tasks.id]
  load_balancer_arn = aws_lb.alb.arn
  target_group_arn = aws_lb_target_group.alb_target_group.arn
}
# modules/ecs_fargate_service/main.tf
resource "aws_ecs_service" "fargate_service" {
  name            = "${var.environment}-fargate-service"
  cluster         = var.cluster_name
  task_definition = var.task_definition_arn
  desired_count   = var.desired_count
  launch_type     = "FARGATE"
  network_configuration {
    subnets          = var.subnet_ids
    security_groups = var.security_group_ids
  }

  load_balancer {
    target_group_arn = var.target_group_arn
    container_name   = "example-container" # コンテナ名を指定
    container_port   = 80
  }

  # Auto Scaling設定 (例: CPU使用率に基づくターゲット追跡スケーリング)
  deployment_controller {
    type = "ECS"
  }

  scaling_configuration {
    maximum_percent          = 200
    minimum_percent          = 100

    managed_scaling {
      maximum_capacity       = 4
      minimum_capacity       = 1
      target_tracking_configurations {
        target_value               = 70.0
        predefined_metric_specification {
          predefined_metric_type = "ECSServiceAverageCPUUtilization"
        }
        scale_in_cooldown          = 60
        scale_out_cooldown         = 60
      }
    }
  }
}

まとめ

TerraformでFargateを記述する際は、基本的なリソース定義に加えて、モジュール化、変数定義、リモートバックエンド、ネットワーク/セキュリティ設定、監視・ロギング、スケーリング、デプロイ戦略などを考慮することで、より実務レベルで利用可能な、堅牢で運用しやすいインフラを構築できます。

Discussion