ENGINEER BLOG ENGINEER BLOG
  • 公開日
  • 最終更新日

AWS FargateでS3上のCSVを集計するシンプルなバッチ処理を構築してみた

この記事を共有する

目次

1. はじめに

パーソル&サーバーワークスの菅野 索です。

AWSを中心としたクラウドインフラの設計・構築・運用を担当しています。

今回はAWS Fargateを利用し、Amazon S3に保存したCSVファイルを集計するシンプルなバッチ処理を構築しました。

検証を目的とした構成のため、ネットワークはPublic Subnetを利用したシンプルな構成としています。本番環境ではPrivate SubnetやVPC Endpointの利用を検討してください。

2. AWS Fargateとは

AWS Fargateは、Amazon ECS向けのサーバーレスコンテナ実行サービスです。

従来のコンテナ実行環境ではEC2インスタンスの管理が必要でしたが、Fargateではコンテナ実行基盤をAWSが管理します。

そのため利用者は、コンテナイメージの作成やタスク定義の作成、アプリケーション開発に集中できます。

主な特徴は以下の通りです。

  • コンテナ実行基盤の管理が不要
  • ECSとの統合が容易
  • コンテナ単位でCPU・メモリを指定可能
  • 必要なタイミングでコンテナを起動可能

コンテナ実行基盤の運用負荷を軽減できる点がFargateの大きな特徴です。

3. 今回やること

今回はS3に保存したCSVファイルを読み込み、売上金額を集計するバッチ処理を作成します。

入力データは以下の通りです。

【csv】
date,amount
2025-01-01,1000
2025-01-02,1500
2025-01-03,2000

実行結果は以下になります。

Total Amount : 4500

4. LambdaではなくFargateを選んだ理由

今回の処理はAWS Lambdaでも実装できます。

一方で今回は以下の理由からFargateを選択しました。

  • コンテナ実行環境を試したかった
  • Pythonアプリケーションをそのままコンテナ化できる
  • 将来的な処理拡張に対応しやすい

小規模な処理であればLambdaも有力な選択肢です。一方で、コンテナベースの実行環境やECSの基本的な仕組みを学習する用途では、Fargateは理解しやすい選択肢の一つだと感じました。

5. 構成図

構成図_202609_Blog_01.png

今回利用したAWSサービスは以下です。

  • Amazon ECS(AWS Fargate)
  • Amazon ECR
  • Amazon S3
  • Amazon EventBridge Scheduler
  • Amazon CloudWatch Logs

本構成では、EventBridge SchedulerからECSのRunTask APIを実行し、Fargateタスクを起動しています。

6. 集計プログラムについて

今回は以下のPythonコードを利用しました。

ここを押すと展開します

import os
import boto3
import csv
from io import StringIO
s3 = boto3.client("s3")
bucket_name = os.environ["BUCKET_NAME"]
response = s3.get_object(
    Bucket=bucket_name,
    Key="sales.csv"
)
csv_data = response["Body"].read().decode("utf-8")
reader = csv.DictReader(
    StringIO(csv_data)
)
total = sum(
    int(row["amount"])
    for row in reader
)
print(f"Total Amount : {total}")

処理内容はシンプルで、S3からCSVファイルを取得し、amount列の値を集計してCloudWatch Logs上に出力します。

6-1 コンテナイメージについて

今回は検証用途だったため、CloudShellを利用してDockerイメージを作成し、Amazon ECRへプッシュしました。

ローカル環境を準備することなくAWS上だけで検証できるため、手軽に試せる点が便利でした。

※今回は最低限の構成のためrequirements.txtは作成しておりません。

6-2 Dockerfile

コンテナ化には以下のDockerfileを利用しました。

FROM python:3.11-slim
WORKDIR /app
COPY app.py .
RUN pip install --no-cache-dir boto3
CMD ["python", "app.py"]

6-3 インフラ構成

インフラはCloudFormationで作成しました。

今回作成した主なリソースは以下の通りです。

※以下作成リソースのCloudFormationコードは「12. 参考」に記載しております。

  • VPC
  • Public Subnet
  • Internet Gateway
  • Amazon ECR
  • Amazon ECS Cluster
  • ECS Task Definition
  • Amazon S3
  • Amazon CloudWatch Logs
  • IAM Role
  • Amazon EventBridge Scheduler

6-4 Fargateタスク定義

今回利用したタスク定義の主要部分は以下の通りです。

ここを押すと展開します

TaskDefinition:
  Type: AWS::ECS::TaskDefinition
  Properties:
    Family: csv-batch
    RequiresCompatibilities:
      - FARGATE
    Cpu: 256
    Memory: 512
    NetworkMode: awsvpc
    ContainerDefinitions:
      - Name: csv-batch
        Environment:
          - Name: BUCKET_NAME
            Value: 

6-5 検証用CSV

S3へ配置するCSVファイルです。

今回は環境変数 BUCKET_NAME で指定したS3バケットへ sales.csv という名前で配置しています。

date,amount
2025-01-01,1000
2025-01-02,1500
2025-01-03,2000

7. 実際の構築手順

7-1 CloudFormationテンプレートを作成

以下URLを参照し、CloudFormationにてリソースを作成します。 コンソールを使用して CloudFormation スタックを作成する

7-2 格納用CSVファイル作成

CloudShellを起動して以下コマンドでエディタを起動し、格納用CSV(### 検証用CSVの内容を参照)を作成し保存(:wq)します。

vi sales.csv

7-3 CloudFormationで作成されたS3バケットへアップロード

以下コマンドで、S3上にCSVをコピーします。

aws s3 cp sales.csv s3://<作成したバケット名>/

7-4 プログラムファイル作成

以下コマンドでエディタを起動し、集計用プログラム(### 集計プログラムについて)を作成し保存(:wq)します。

vi app.py

7-5 Dockerfile作成

以下コマンドでエディタを起動し、Dockerfile(### Dockerfile)を作成し保存(:wq)します。

vi dockerfile

7-6 Dockerイメージを作成

docker build -t csv-batch-app .

7-7 Amazon ECRへイメージをプッシュ

以下のコマンドにてローカルにビルドしたDockerイメージが存在することを確認します。

docker images | grep csv-batch-app

上記でECRリポジトリが確認できたら以下のコマンドを実行します。

ここを押すと展開します

ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
REGION=${AWS_REGION}
aws ecr get-login-password \
| docker login \
  --username AWS \
  --password-stdin \
  ${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com && \
docker tag csv-batch-app:latest \
  ${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/csv-batch-app:latest && \
docker push \
  ${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/csv-batch-app:latest

7-8 EventBridge Schedulerにてスケジュール作成

以下URLを参照し、スケジュールを作成します。

Amazon EventBridge スケジューラ

EventBridge Schedulerにてスケジュールを作成し、ターゲットとしてECSのRunTaskを指定します。

また今回の検証では、パブリックサブネットを利用しているため、同じ構成にする場合は「自動割り当てパブリック IP」を有効化にするのを忘れないで下さい。

自動割り当てパブリックIP.png

例えば以下のcron式を設定すると、毎時0分にFargateタスクを実行できます。

cron(0 * * * ? *)

これにより指定したスケジュールでFargateタスクを自動実行できます。

8. 実際の動作

EventBridge Scheduler にてタスク実行後、CloudWatch Logsを確認すると以下の通り出力されました。

スクリーンショット 2026-09-23 190710.png

スクリーンショット 2026-09-23 190727.png

期待通りにCSV内の金額を集計できていることを確認できました。

9. 構築時の気づき

CloudWatch Logsは早めに設定しておく

当初ログ出力設定を用意しておらず、タスク実行の問題調査に時間がかかりました。

Fargateを利用する場合は、まず最初にCloudWatch Logsを設定し、ログを確認できる状態にしておくことをおすすめします。

Fargateではawsvpcが必須

Fargateでは以下の設定が必須です。

NetworkMode: awsvpc

当初は「FargateはサーバーレスサービスであるためVPCは不要ではないか」と考えていました。

しかし実際にはFargateで実行されるタスクはVPC内のサブネット上で起動するため、VPCやサブネット、セキュリティグループなどのネットワーク設定が必要です。

また、ECSはコンテナ実行を管理するコントロールプレーンとして動作し、Fargateはコンテナ実行環境を提供する役割(データプレーン)を担っています。

Fargateを利用する際は、コンテナだけでなくネットワーク構成についても理解しておくことが重要だと感じました。

EventBridge Scheduler スケジュール作成時は「自動割り当てパブリック IP」を有効化が必要

スケジュール作成時に自動割り当てパブリック IPを有効化していなかったため、手動ではECSからFargateを起動できるが、スケジュール実行だと起動できない事象に陥り、原因を突き止めるのに時間がかかってしまいました。

パブリックサブネット上でFargateをスケジュール実行する場合は自動パブリックIP割り当て有効化が必要なのだと勉強になりました。

10. やってみた感想

今回Fargateを利用したバッチ処理を構築しましたが、コンテナ実行基盤を意識せずにアプリケーション開発へ集中できる点が印象的でした。

Lambdaと比較すると設定項目は増えますが、一度コンテナ化してしまえば実行環境の差異を意識せずに運用できる点は大きなメリットだと感じています。

またECSの基本要素であるCluster、Task Definition、Taskの関係についても理解を深めることができました。

11. まとめ

今回はAWS Fargateを利用して、S3上のCSVファイルを集計するシンプルなバッチ処理を構築しました。

Lambdaでも実現可能な処理ではありますが、コンテナベースのアプリケーション実行やECRとの連携、EventBridge Schedulerによる定期実行など、ECS/Fargateを利用したバッチ処理の基本構成を一通り確認できました。

FargateはWebアプリケーションだけでなく、定期実行バッチやデータ処理ジョブとの相性も良くコンテナ運用を学習する入り口としても有用なサービスだと感じています。

なお、今回は検証用途としてPublic Subnet構成を採用しましたが、本番環境ではPrivate SubnetやVPC Endpointを利用した閉域構成を検討することをおすすめします。

同様の構成を検討している方や、これからECS/Fargateを学習する方の参考になれば幸いです。

12. 参考

リソース作成用CloudFormationコード

ここを押すと展開します

AWSTemplateFormatVersion: '2010-09-09'
Description: CSV Aggregation Batch using AWS Fargate
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.100.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
  InternetGateway:
    Type: AWS::EC2::InternetGateway
  VPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway
  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [0, !GetAZs '']
      CidrBlock: 10.100.1.0/24
      MapPublicIpOnLaunch: true
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
  DefaultRoute:
    Type: AWS::EC2::Route
    DependsOn: VPCGatewayAttachment
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
  PublicSubnetAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicRouteTable
      SubnetId: !Ref PublicSubnet
  FargateSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Fargate Batch Security Group
      VpcId: !Ref VPC
      SecurityGroupEgress:
        - IpProtocol: "-1"
          CidrIp: 0.0.0.0/0
  SalesBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub sales-batch-${AWS::AccountId}-${AWS::Region}
  ECRRepository:
    Type: AWS::ECR::Repository
    Properties:
      RepositoryName: csv-batch-app
  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: /ecs/csv-batch
      RetentionInDays: 30
  ECSCluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName: csv-batch-cluster
  TaskExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ecs-tasks.amazonaws.com
            Action:
              - sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
  TaskRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ecs-tasks.amazonaws.com
            Action:
              - sts:AssumeRole
      Policies:
        - PolicyName: ReadCsvFromS3
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                Resource:
                  - !Sub '${SalesBucket.Arn}/*'
  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: csv-batch
      RequiresCompatibilities:
        - FARGATE
      Cpu: 256
      Memory: 512
      NetworkMode: awsvpc
      ExecutionRoleArn: !GetAtt TaskExecutionRole.Arn
      TaskRoleArn: !GetAtt TaskRole.Arn
      ContainerDefinitions:
        - Name: csv-batch
          Image: !Sub "${ECRRepository.RepositoryUri}:latest"
          Essential: true
          Environment:
            - Name: BUCKET_NAME
              Value: !Ref SalesBucket
          LogConfiguration:
            LogDriver: awslogs
            Options:
              awslogs-group: !Ref LogGroup
              awslogs-region: !Ref AWS::Region
              awslogs-stream-prefix: ecs
Outputs:
  BucketName:
    Description: S3 Bucket Name
    Value: !Ref SalesBucket
  RepositoryUri:
    Description: ECR Repository URI
    Value: !GetAtt ECRRepository.RepositoryUri
  ClusterName:
    Description: ECS Cluster Name
    Value: !Ref ECSCluster
  TaskDefinitionArn:
    Description: ECS Task Definition ARN
    Value: !Ref TaskDefinition
  PublicSubnetId:
    Description: Public Subnet ID
    Value: !Ref PublicSubnet
  SecurityGroupId:
    Description: Fargate Security Group ID
    Value: !Ref FargateSecurityGroup

この記事は私が書きました

菅野 索

記事一覧

趣味:ジョギング、散歩
最近体重の増加が気になるので、ダイエット頑張ってます。

菅野 索

この記事を共有する

クラウドのご相談

CONTACT

クラウド導入や運用でお悩みの方は、お気軽にご相談ください。
専門家がサポートします。

サービス資料ダウンロード

DOWNLOAD

ビジネスをクラウドで加速させる準備はできていますか?
今すぐサービス資料をダウンロードして、詳細をご確認ください。