目次

目次

S3イベントで実現するECSバッチ起動について

アバター画像
徐杉
アバター画像
徐杉
最終更新日2025/12/25 投稿日2024/11/29

はじめに

こんにちは!NX開発推進部 次世代プロダクト開発 Gエンジニアをしている徐です。 バックエンドの開発を主に行っております。

好きなプログラミング言語はPythonで、お気に入りのAmazon Web Services(以下、AWS)サービスはAWS Lambdaになります。

今回は、S3イベントで実現するECSバッチ起動についてご紹介します。

背景・課題

現在、開発に携わっているシステムでは、CSVファイルをトリガーとしてECSを起動する仕組みを、一部のバッチ処理で採用しています。しかし、実装当時はS3のPutObjectイベントなど、オブジェクトレベルのイベントを直接キャプチャすることができませんでした。そのため、CloudTrailの証跡を利用してオブジェクトレベルのAPI操作を記録し、そのログをEventBridgeでキャプチャする形で対応していました。

ただし、CloudTrailのトレイルには最大5個までという制限があり、同様の仕組みを利用するECSバッチが増えた場合に対応が困難になるという課題がありました。また、現在ではEventBridgeがS3のオブジェクトレベルイベントを直接キャプチャできるようになったため、S3と直接連携する形での改善を進めていきたいと考えています。

内容に関して

本記事は、AWSの利用経験がある程度ある方を対象としています。記事内では、仕組みの変更点に重点を置いて解説しますが、全ての構築手順や関連AWSサービスの詳細については割愛しています。

内容や手順については、2024年11月15日時点の情報を基に記載しています。また、AWSのアップデートによりUIや仕様が変更になる可能性がありますので、添付した画像などの内容が古くなることもご了承ください。

目次

1.改善前のアーキテクチャ図 2.変更点・改善点 3.CloudFormationのテンプレートサンプル 4.最後に

1.改善前のアーキテクチャ図

スクリーンショット 2024-11-15 11.47.39.png

S3→CloudTrail→EventBridge→ECS

S3バケット内の特定のパス以下にファイルが作成されたことをトリガーとして、ECSを実行する構成を構築していました。この構成では、EventBridgeを介してS3のイベント(PutObject)を検知します。CloudTrailの証跡を利用してオブジェクトレベルのAPI操作をログに記録し、そのログをEventBridgeでキャプチャする必要がありました。

2.変更点・改善点

  1. S3でAWS EventBridgeの「通知」設定をオンにする
    スクリーンショット 2024-11-15 12.02.39.png
  2. S3→CloudTrail→EventBridge→ECSの構成からCloudTrailを削除

    スクリーンショット 2024-11-15 11.48.04.png

3.CloudFormationのテンプレートサンプル

1.S3にAWS EventBridgeの「通知」設定をオンにする設定を追加

 SampleBucket:
    Type: AWS::S3::Bucket
    Properties:
      AccessControl: Private
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256
      BucketName: !Sub sample-bucket
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
      NotificationConfiguration:   # ←設定を追加 
        EventBridgeConfiguration:
          EventBridgeEnabled: true

2.既存のCloudTrail関連設定を削除

Description: >
  This template deploys sample ecs

Parameters:
  EnvironmentName:
    Description: An environment name that will be prefix to resource names
    Type: String
    AllowedValues:
      - dev
      - dvm
      - pro
  OrganizationName:
    Description: Organization name
    Type: String
  AppName:
    Description: An application name
    Type: String
  ECSTaskLogGroupRetentionInDays:
    Type: Number
    Default: 180
  AppImageTag:
    Description: app image tag
    Type: String
  CPUUnits:
    Description: The number of cpu units
    Type: String
    Default: 256
  MemorySize:
    Description: The amount (in MiB) of memory
    Type: String
    Default: 512
  SubnetIds:
    Description: SSM Parameter name
    Type: AWS::SSM::Parameter::Value<List<String>>

CloudTrailLogBucket: # ←ログ保存用S3設定を削除
      dev: sample-cloudtrail-log-dev-bucket 
      dvm: sample-cloudtrail-log-dvm-bucket
      pro: sample-cloudtrail-log-pro-bucket
CloudTrail:   #  ←CloudTrail作成設定を削除
  Type: AWS::CloudTrail::Trail
  Properties:
    EventSelectors:
      - DataResources:
          - Type: AWS::S3::Object
            Values:
              - !Sub arn:aws:s3:::sample-bucket/test
      - IncludeManagementEvents: true
    IsLogging: true
    S3BucketName:
      Fn::FindInMap:
        - EnvMap
        - CloudTrailLogBucket
        - !Ref EnvironmentName
    TrailName: !Sub sample-events

3.S3のイベントを直接指定する構成に変更

<br>EventPattern:
  source:
    - "aws.s3" # ←イベントの発生元
  detail-type:
    - "Object Created" # ←イベントパターン指定
  detail:
    bucket:
      name:
        - !Sub "sample-bucket" # ←イベントが発生するS3バケットの名前を指定
    object:
      key:
        - prefix: "test/aaa/complete.txt" # ←S3オブジェクトのキー(パス)を指定

4.S3イベントから取得したオブジェクトキー情報をECSタスクのコンテナに渡します

Targets:
  - Arn: !Sub arn:aws:ecs:ap-northeast-1:${AWS::AccountId}:cluster/sample-ecs 
    EcsParameters:
      LaunchType: FARGATE
      PlatformVersion: 1.4.0
      NetworkConfiguration:
        AwsVpcConfiguration:
          AssignPublicIp: DISABLED
          SecurityGroups:
            - Fn::ImportValue: Sample:ECSServiceSecurityGroup
          Subnets:
            Fn::FindInMap:
              - EnvMap
              - SubnetIds
              - !Ref EnvironmentName
      TaskDefinitionArn: !Ref ECSTaskDefinition
    Id: ecs
    RoleArn: !Sub arn:aws:iam::${AWS::AccountId}:role/ecsEventsRole
    InputTransformer: #  ←追加 コンテナの環境変数としてオブジェクトキー(OBJECT_KEY)を渡します。
      InputPathsMap:
        key: "$.detail.object.key"
      InputTemplate: '{"containerOverrides":[{"name":"app","environment":[{"name":"OBJECT_KEY","value":"<key>"}]}]}'

最後に

S3バケットの指定したパスにファイルをアップロードする点は修正後も変わりませんが、上記の修正により、S3と直接連携する形でECSを起動できるようになります。

また、CloudTrailのトレイルに最大5個という制限を気にすることなく、必要に応じて作成できるようになります。

最後まで読んでいただき、ありがとうございました!

アバター画像

徐杉

目次