Yuta NakataのBlog

Python / AWS / ITについて役立つ情報を発信します

dynamoDBのAPIイベントをCloudTrail×S3に集める方法

背景

CloudTrailは、証跡を集めるサービスです。

AWS上の様々なアクセスログを自動的に集めてくれます。

DynamoDBにおいては、

  • CreateTable
  • DeleteTable
  • UpdateTable

などの基本的な挙動はデフォルトで記録してくれます。

しかし、

  • GetItem
  • PutItem
  • Query
  • Scan

などの挙動はデフォルトでは収集してくれません。

Ref.

やりたいこと

上記の背景から、これらのイベントログを収集したいです。

Must

  • CloudFormationを用いてIaC化する
  • APIログのイベントは対象のDynamoDBに限定し、必要以上のログを集めない

Better

  • ライフサイクルルールを用いて、コスト最適化対応を実施する

実装コード

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31

Resources:
  LogBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: My-Bucket
      AccessControl: Private
      PublicAccessBlockConfiguration:
        BlockPublicAcls: True
        BlockPublicPolicy: True
        IgnorePublicAcls: True
        RestrictPublicBuckets: True
      NotificationConfiguration:
        EventBridgeConfiguration:
          EventBridgeEnabled: true
      OwnershipControls:
        Rules:
          - ObjectOwnership: BucketOwnerEnforced
      LifecycleConfiguration:
        Rules:
          - Id: delete-multipart
            Status: Enabled
            AbortIncompleteMultipartUpload:
              DaysAfterInitiation: 1
          - Id: bucket-lifecycle
            Status: Enabled
            Transitions:
              - StorageClass: GLACIER
                TransitionInDays: 30

  LogBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref LogBucket
      PolicyDocument:
        Statement:
          - Action:
              - s3:GetBucketAcl
            Effect: Allow
            Principal:
              Service: cloudtrail.amazonaws.com
            Resource: !Sub arn:aws:s3:::${LogBucket}
          - Action:
              - s3:PutObject
            Effect: Allow
            Principal:
              Service: cloudtrail.amazonaws.com
            Resource: !Sub arn:aws:s3:::${LogBucket}/*
            Condition:
              StringEquals:
                s3:x-amz-acl: bucket-owner-full-control

  DynamoDbModel:
    Type: AWS::DynamoDB::Table
    Properties:
      DeletionProtectionEnabled: true
      TableName: My-DynamoDB
      AttributeDefinitions:
        - AttributeName: key1
          AttributeType: S
        - AttributeName: key2
          AttributeType: S
      KeySchema:
        - AttributeName: key1
          KeyType: HASH
        - AttributeName: key2
          KeyType: RANGE
      BillingMode: PAY_PER_REQUEST
      PointInTimeRecoverySpecification:
        PointInTimeRecoveryEnabled: true
      Tags:
        - Key: BackupPlan
          Value: Critical

  CloudTrail:
    Type: AWS::CloudTrail::Trail
    DependsOn:
      - LogBucketPolicy
      - DynamoDbModel
    Properties:
      IsLogging: true
      TrailName: My-Trail
      S3BucketName: !Ref LogBucket
      EventSelectors:
        - DataResources:
          - Type: AWS::DynamoDB::Table
            Values: DynamoDbModel.Arn
          ReadWriteType: All
          IncludeManagementEvents: false

詰まった点

1. CloudTrailをdeployするためには、最低限必要なBucketPolicyがある

CloudTrailがS3に書き込むためには、最低限必要なPolicyがあるようです。そのため、

        Statement:
          - Action:
              - s3:GetBucketAcl
            Effect: Allow
            Principal:
              Service: cloudtrail.amazonaws.com
            Resource: !Sub arn:aws:s3:::${LogBucket}
          - Action:
              - s3:PutObject
            Effect: Allow
            Principal:
              Service: cloudtrail.amazonaws.com
            Resource: !Sub arn:aws:s3:::${LogBucket}/*
            Condition:
              StringEquals:
                s3:x-amz-acl: bucket-owner-full-control

はマストでいれる必要がありました。

2. 管理イベントをOFFにする

本内容をOFFにしないと管理系イベント(=ルーティングテーブルルールの設定や、デバイス登録ログなど)が色々入ってきてしますため、必須でOFFにしましょう。

IncludeManagementEvents: false

repost.aws

まとめ

これにて、dynamoDBのAPIイベントをCloudTrail×S3で集めることができました。

DynamoDBの詳細なログを残したいニーズはあると思いますので、是非参考にしてみてください。

良ければ、☆やコメント等もらえると、気合の入れた記事を書けます。宜しくお願いします。笑