はじめに
こんにちは!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.改善前のアーキテクチャ図

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

S3→CloudTrail→EventBridge→ECSの構成からCloudTrailを削除

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個という制限を気にすることなく、必要に応じて作成できるようになります。
最後まで読んでいただき、ありがとうございました!
徐杉