Firehoseに対応したAPI Gatewayのアクセスログ設定を試してみた

AWSチームのすずきです。

Amazon Kinesis Data Firehose への アクセスログ出力が可能になった Amazon API Gateway。 その設定を試す機会がありましたので、紹介させていただきます。

Amazon API Gateway が Amazon Kinesis Data Firehose へのアクセスログ記録をサポート開始

設定

Firehose

API Gatewayのログ出力先とする Kinesis Data Firehoseのストリームを作成します。

ストリームの名称は「amazon-apigateway-」で始まる名称とします。

Firehoseの出力先はS3としました。

API Gateway のログ設定で利用する「Delivery stream ARN」を確認します。

IAM

API Gateway のサービスロール「AWSServiceRoleForAPIGateway」が存在、 AWS 管理ポリシー「 APIGatewayServiceRolePolicy が適用されている事を確認します。

  • arn:aws:iam::<アカウントID>:role/aws-service-role/ops.apigateway.amazonaws.com/AWSServiceRoleForAPIGateway

「AWSServiceRoleForAPIGateway」が存在しない場合、API GatewayのWeb設定画面で「X-Ray Tracing」の有効化することで、サービスロールが作成されます。

APIGateway

ログを有効とするAPIのステージを指定、「Log/Tracing」ので 「Custom Access Logging」を有効、

Access Log Destination ARN は、API Gateway用に作成した 名称「amazon-apigateway-」で始まる FirehoseのARNを指定します。

ログの形式、今回は「JSON」の設定例をそのまま利用しました。

確認

Firehose の出力先として指定した S3配下に API Gatewayのアクセスログが出力されている事を確認します。

「S3 Select」を利用して、JSON形式 で API Gatewayのアクセスログが保存されている事を確認できました。

まとめ

API Gateway のアクセスログ、従来から利用できた CloudWatch Logs に加え、Kinesis Data Firehose 経由で S3 を 出力先として利用する事が可能となりました。

CloudWatch Logs は、CloudWatch Logs Insights といった便利な分析機能を備えますが、東京リージョンでは、収集したログ1GBあたり 0.76 USD の費用が課題となる事がありました。

Kinesis Data Firehose は、1GBあたり0.036 USD、CloudWatch Logs の 1/20の費用で利用可能です。

これまで コストが課題となり API Gateway アクセスログの取得を見送っていた場合、今回のアップデートをぜひお試しください。

Firehose設定テンプレート

API Gateway ログ用の S3バケット、 Firehose を設置する CloudFormationテンプレート例です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
S3BucketFirehose:
  Type: AWS::S3::Bucket
  DeletionPolicy: Delete
  Properties:
    BucketName: !Sub '${AWS::StackName}-firehose-${AWS::Region}-${AWS::AccountId}'
    LifecycleConfiguration:
      Rules:
        - Id: AutoDelete
          Status: Enabled
          ExpirationInDays: 14
    PublicAccessBlockConfiguration:
      BlockPublicAcls: true
      BlockPublicPolicy: true
      IgnorePublicAcls: true
      RestrictPublicBuckets: true
    Tags:
      - Key: StackId
        Value: !Sub '${AWS::StackId}'
    VersioningConfiguration:
      Status: Enabled
FirehoseStreamRole:
  Type: AWS::IAM::Role
  Properties:
    AssumeRolePolicyDocument:
      Version: '2012-10-17'
      Statement:
        - Sid: ''
          Effect: Allow
          Principal:
            Service: firehose.amazonaws.com
          Action: sts:AssumeRole
          Condition:
            StringEquals:
              sts:ExternalId: !Ref 'AWS::AccountId'
FirehoseStreamPolicy:
  Type: AWS::IAM::Policy
  Properties:
    PolicyName: firehose_delivery_policy
    PolicyDocument:
      Version: '2012-10-17'
      Statement:
        - Effect: Allow
          Action:
            - s3:AbortMultipartUpload
            - s3:GetBucketLocation
            - s3:GetObject
            - s3:ListBucket
            - s3:ListBucketMultipartUploads
            - s3:PutObject
          Resource:
            - !Sub 'arn:aws:s3:::${S3BucketFirehose}'
            - !Sub 'arn:aws:s3:::${S3BucketFirehose}/*'
    Roles:
      - !Ref 'FirehoseStreamRole'
FirehoseStreamApigw:
  Type: AWS::KinesisFirehose::DeliveryStream
  Properties:
    DeliveryStreamName: !Sub 'amazon-apigateway-${AWS::StackName}'
    ExtendedS3DestinationConfiguration:
      BucketARN: !Sub 'arn:aws:s3:::${S3BucketFirehose}'
      Prefix: !Sub 'apigw/dt=!{timestamp:YYYY}-!{timestamp:MM}-!{timestamp:dd}/'
      ErrorOutputPrefix: !Sub 'apigw-error/!{firehose:error-output-type}/dt=!{timestamp:YYYY}-!{timestamp:MM}-!{timestamp:dd}/'
      BufferingHints:
        IntervalInSeconds: '300'
        SizeInMBs: '10'
      CompressionFormat: GZIP
      RoleARN: !GetAtt 'FirehoseStreamRole.Arn'
      ProcessingConfiguration:
        Enabled: 'false'

PR11月1日にオフラインイベント・Developers.IO 東京開催します
PRもっと安く使いたい