2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CloudFrontの新しいログ出力機能(v2)のCFnテンプレート

Posted at

CloudFrontの新しいログ出力機能(v2)のCFn(CloudFormation)テンプレート

2024年11月にAWSのCloudFrontで新しいログ出力機能が登場しました。
詳しくは下記をご覧ください。

CloudFormationのテンプレートで従来のログ出力(S3 Legacy logging)から、新しいログ出力(S3 logging (v2))に切り替えるのに苦労したので、以下の投稿が参考になれば幸いです。

従来のログ出力設定を削除

S3 Bucket

アクセスログ出力用のS3バケットで(従来利用していた)ACLが無効化できるようになりました。

  • ※ただし無効化する前にバケットのACLで awslogsdelivery (c4c1ede66af53448b93c283ce9448c4ba468c9432aa01d700d3878632f77d2d0) の許可を削除してください。
CloudFormationテンプレートの一部抜粋
   ## S3: Bucket (Access Logs)
   S3BucketAccessLogs:
     Type: AWS::S3::Bucket
     Properties:
       OwnershipControls:
         Rules:
-          - ObjectOwnership: ObjectWriter
+          - ObjectOwnership: BucketOwnerEnforced

CloudFront Distribution

CloudFrontのDistributionで従来のログ出力設定を削除します。

CloudFormationテンプレートの一部抜粋
   ## CloudFront: Distribution
   Distribution:
     Type: AWS::CloudFront::Distribution
     Properties:
       DistributionConfig:
-        Logging:
-          Bucket: !GetAtt S3BucketAccessLogs.DomainName
-          Prefix: logs/
-          IncludeCookies: true

新しいログ出力設定を追加

S3 Bucket Policy

アクセスログ出力用のS3バケットで今度はバケットポリシーを利用することになりました。
※Conditionでバージニア北部リージョン(us-east-1)のリソースARNが指定されていますが、そのリソースは後から作るで問題ありません。

CloudFormationテンプレートの一部抜粋
+  ## S3: Bucket Policy (Access Logs)
+  S3BucketPolicyAccessLogs:
+    Type: AWS::S3::BucketPolicy
+    Properties:
+      Bucket: !Ref S3BucketAccessLogs
+      PolicyDocument:
+        Version: "2012-10-17"
+        Statement:
+          - Effect: Allow
+            Action: s3:PutObject
+            Principal:
+              Service: delivery.logs.amazonaws.com
+            Resource: !Sub ${S3BucketAccessLogs.Arn}/AWSLogs/${AWS::AccountId}/CloudFront/*
+            Condition:
+              StringEquals:
+                aws:SourceAccount: !Ref AWS::AccountId
+                s3:x-amz-acl: bucket-owner-full-control
+              ArnLike:
+                ## Logs delivery resources (CFn stack) need to be created in the us-east-1 region after this CFn stack is created.
+                aws:SourceArn: !Sub arn:aws:logs:us-east-1:${AWS::AccountId}:delivery-source:${SystemName}-${Environment}-cloudfront-delivery-source

Logs Delivery関連 @バージニア北部リージョン(us-east-1)

新しいログ出力にはLogs Delivery関連のリソースが3つ必要になりますが、CloudFrontの場合はLogs Delivery Sourceが東京リージョン(ap-northeast-1)で作成できなかったので、やむを得ずバージニア北部リージョン(us-east-1)で作成しました。

バージニア北部リージョンで追加するCloudFormationテンプレートの全体
---
AWSTemplateFormatVersion: "2010-09-09"
Description: Create Logs Delivery for CloudFront etc.

Mappings:
  EnvironmentMap:
    prod:
      ## [Change CloudFront Distribution Id] Logs Delivery Source needs to be created in the us-east-1 region.
      CloudFrontDistributionId: [xxxxxxxxxxxxx]
    stg:
      CloudFrontDistributionId: [xxxxxxxxxxxxx]
    dev:
      CloudFrontDistributionId: [xxxxxxxxxxxxx]

Parameters:
  SystemName:
    Description: System Name
    Type: String
    Default: rubiconlink
  Environment:
    Description: Environment
    Type: String
    Default: prod
    AllowedValues:
      - prod
      - stg
      - dev

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: "Environment Configuration"
        Parameters:
          - SystemName
          - Environment

Resources:
  ## Logs: Delivery Source
  LogsDeliverySource:
    Type: AWS::Logs::DeliverySource
    Properties:
      Name: !Sub ${SystemName}-${Environment}-cloudfront-delivery-source
      ResourceArn: !Sub
          - arn:aws:cloudfront::${AWS::AccountId}:distribution/${DistributionId}
          - DistributionId:
              !FindInMap [ EnvironmentMap, !Ref Environment, CloudFrontDistributionId ]
      LogType: ACCESS_LOGS

  ## Logs: Delivery Destination
  LogsDeliveryDestination:
    Type: AWS::Logs::DeliveryDestination
    Properties:
      Name: !Sub ${SystemName}-${Environment}-cloudfront-delivery-destination
      DestinationResourceArn: !Sub arn:aws:s3:::${SystemName}-${Environment}-cloudfront-accesslogs-${AWS::AccountId}
      OutputFormat: json

  ## Logs: Delivery
  LogsDelivery:
    Type: AWS::Logs::Delivery
    Properties:
      DeliverySourceName: !Sub ${SystemName}-${Environment}-cloudfront-delivery-source
      DeliveryDestinationArn: !GetAtt LogsDeliveryDestination.Arn
      RecordFields:
        - timestamp
        - DistributionId
        - date
        - time
        - x-edge-location
        - sc-bytes
        - c-ip
        - cs-method
        - cs(Host)
        - cs-uri-stem
        - sc-status
        - cs(Referer)
        - cs(User-Agent)
        - cs-uri-query
        - cs(Cookie)
        - x-edge-result-type
        - x-edge-request-id
        - x-host-header
        - cs-protocol
        - cs-bytes
        - time-taken
        - x-forwarded-for
        - ssl-protocol
        - ssl-cipher
        - x-edge-response-result-type
        - cs-protocol-version
        - fle-status
        - fle-encrypted-fields
        - c-port
        - time-to-first-byte
        - x-edge-detailed-result-type
        - sc-content-type
        - sc-content-len
        - sc-range-start
        - sc-range-end
        - timestamp(ms)
        - origin-fbl
        - origin-lbl
        - asn
      S3SuffixPath: !Sub AWSLogs/${AWS::AccountId}/CloudFront/{yyyy}/{MM}/{dd}/{HH}
      S3EnableHiveCompatiblePath: false

Outputs:
  ## Logs: Delivery Source
  LogsDeliverySourceArn:
    Value: !GetAtt LogsDeliverySource.Arn
    Export:
      Name: !Sub ${AWS::StackName}-LogsDeliverySourceArn

  LogsDeliverySourceResourceArn1:
    Value: !Select [ 0, !GetAtt LogsDeliverySource.ResourceArns ]
    Export:
      Name: !Sub ${AWS::StackName}-LogsDeliverySourceResourceArn1

  LogsDeliverySourceService:
    Value: !GetAtt LogsDeliverySource.Service
    Export:
      Name: !Sub ${AWS::StackName}-LogsDeliverySourceService

  ## Logs: Delivery Destination
  LogsDeliveryDestination:
    Value: !GetAtt LogsDeliveryDestination.Arn
    Export:
      Name: !Sub ${AWS::StackName}-LogsDeliveryDestinationArn

  ## Logs: Delivery
  LogsDeliveryArn:
    Value: !GetAtt LogsDelivery.Arn
    Export:
      Name: !Sub ${AWS::StackName}-LogsDeliveryArn

  LogsDeliveryDestinationType:
    Value: !GetAtt LogsDelivery.DeliveryDestinationType
    Export:
      Name: !Sub ${AWS::StackName}-LogsDeliveryDestinationType

  LogsDeliveryId:
    Value: !GetAtt LogsDelivery.DeliveryId
    Export:
      Name: !Sub ${AWS::StackName}-LogsDeliveryId

参考記事

CloudFront以外でも、新しいログ出力機能(v2)が利用可能なサービスの一覧が公式ドキュメントにありました。
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/AWS-logs-and-resource-policy.html

新しいログ出力機能の料金は料金ページの「その他の機能」タブをご覧ください。
https://aws.amazon.com/jp/cloudfront/pricing/

(再掲)ログ出力できる項目はリアルタイムログと同じようです。
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/real-time-logs.html

(再掲)その他詳細は公式ドキュメントをご覧ください。
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/standard-logging.html

おわりに

参考になれば幸いです!

インフラエンジニア歴17年(AWS利用歴9年)の経験を活かして、私が直接オンラインでAWSを教える塾(現場最強のエンジニアになろう® ルビコン塾)を開講しています。今回のテンプレートもルビコン塾の教材の一部です。

ご興味ある方はX https://x.com/RubiconLink をフォローして、公式LINEにご登録ください!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?