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テンプレート例です。
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'