AWS CDKによる【S3・VPCフローログ・ALBアクセスログ】の構築

皆様こんにちは。
AWS CDKを利用してマルチAZ3層アーキテクチャ構築をしていきます。
この記事ではS3・VPCフローログ・ALBアクセスログの作成を行います。

目次はこちら

1.S3とは

Amazon S3(Simple Storage Service)は、Amazon Web Services(AWS)が提供するオブジェクトストレージサービスです。高い耐久性と可用性を持ち、インターネット上でデータを保存および取得するためのサービスです。以下に、Amazon S3 の主な特徴と機能を紹介します。

主な特徴

  1. スケーラブル
    Amazon S3 は、ストレージ容量を自動的にスケールします。ストレージのサイズに制限はなく、必要なだけデータを保存できます。

  2. 高い耐久性
    データは複数のデータセンターに分散して保存され、高い耐久性を提供します。AWS は、データの耐久性が 99.999999999%(11 9’s)であると保証しています。

  3. 高可用性
    データは複数のアベイラビリティーゾーン(AZ)にレプリケートされ、システムの故障に対して高い可用性を提供します。

  4. データのセキュリティ
    データは暗号化可能で、保存中および転送中のデータの保護ができます。アクセス制御リスト(ACL)やバケットポリシー、IAM ポリシーを使ってアクセス権限を管理できます。

  5. 簡単なデータ管理
    データは「バケット」というコンテナに格納され、各バケットには一意の名前が付けられます。オブジェクトはバケット内に保存され、オブジェクトにはキー(名前)とメタデータが付けられます。

  6. データのライフサイクル管理
    データのライフサイクルを管理するためのポリシーを設定できます。例えば、データを一定期間後に自動的に削除したり、異なるストレージクラスに移動することができます。

  7. 多様なストレージクラス
    データアクセスの頻度や耐久性の要件に応じて、異なるストレージクラス(標準、低頻度アクセス、グレイシャーなど)を選択できます。

主要な用途

  • バックアップとアーカイブ: 重要なデータのバックアップやアーカイブのためのストレージ。
  • データ共有と配信: 大量のデータを簡単に共有したり、コンテンツ配信ネットワーク(CDN)を使用して配信するためのストレージ。
  • アプリケーションデータストレージ: ウェブアプリケーションやモバイルアプリケーションのデータストレージ。
  • ビッグデータ分析: データレイクとしてビッグデータを格納し、分析ツールと連携してデータを処理する。

基本的な操作

  • バケットの作成: データを保存するためのコンテナを作成します。
  • オブジェクトのアップロード: ファイルをバケットにアップロードします。
  • オブジェクトの取得: バケットからファイルをダウンロードまたは取得します。
  • オブジェクトの削除: バケットからファイルを削除します。

Amazon S3 は、クラウドストレージの中でも非常に人気があり、広範囲な用途に対応できるため、AWS の基盤サービスの中でも重要な位置を占めています。

詳細は公式ドキュメントを参照ください。

2.目的

VPCフローログ、ALBアクセスログを格納するS3構築する。
その後、VPCフローログの設定を追加する。

※ALBアクセスログについてはALB構築時に設定。

3.構成図

4.全体構築ソースコード

        # ALBアクセスログ用のS3バケットの作成
        self.alb_access_logs_bucket = s3.Bucket(self, "AlbAccessLogsBucket",
            bucket_name="kitaya-s3-alb-accesslog",
            removal_policy=RemovalPolicy.DESTROY,
            auto_delete_objects=True,
            encryption=s3.BucketEncryption.S3_MANAGED,
            block_public_access=s3.BlockPublicAccess.BLOCK_ALL
        )

        # バケットポリシーの追加(ALBアクセスログ)
        self.alb_access_logs_bucket.add_to_resource_policy(
            iam.PolicyStatement(
                sid="AllowALBAccessLogs",
                effect=iam.Effect.ALLOW,
                actions=["s3:PutObject", "s3:GetBucketAcl", "s3:GetObject", "s3:ListBucket"],
                resources=[
                    self.alb_access_logs_bucket.bucket_arn,
                    f"{self.alb_access_logs_bucket.bucket_arn}/*"
                ],
                principals=[iam.ArnPrincipal("arn:aws:iam::600734575887:root")]
            )
        )

        # VPCフローログ用S3バケットの作成
        self.vpc_flow_logs_bucket = s3.Bucket(self, "VpcFlowLogsBucket",
            bucket_name="kitaya-s3-vpcflowlog",
            removal_policy=RemovalPolicy.DESTROY,
            auto_delete_objects=True,
            encryption=s3.BucketEncryption.S3_MANAGED,
            block_public_access=s3.BlockPublicAccess.BLOCK_ALL
        )

        # バケットポリシーの追加(VPCフローログ)
        self.vpc_flow_logs_bucket.add_to_resource_policy(
            iam.PolicyStatement(
                sid="AllowVPCFlowLogsAccess",
                effect=iam.Effect.ALLOW,
                actions=["s3:PutObject", "s3:GetBucketAcl", "s3:GetObject", "s3:ListBucket"],
                resources=[
                    f"arn:aws:s3:::{self.vpc_flow_logs_bucket.bucket_name}",
                    f"arn:aws:s3:::{self.vpc_flow_logs_bucket.bucket_name}/*"
                ]
                principals=[iam.ArnPrincipal("arn:aws:iam::アカウントID:root")],
            )
        )

        self.vpc_flow_logs_bucket.add_to_resource_policy(
            iam.PolicyStatement(
                sid="AWSLogDeliveryWrite",
                effect=iam.Effect.ALLOW,
                actions=["s3:PutObject"],
                resources=[f"arn:aws:s3:::{self.vpc_flow_logs_bucket.bucket_name}/AWSLogs/アカウントID/*"],
                principals=[iam.ServicePrincipal("delivery.logs.amazonaws.com")],
                conditions={
                    "StringEquals": {
                        "aws:SourceAccount": "アカウントID",
                        "s3:x-amz-acl": "bucket-owner-full-control"
                    },
                    "ArnLike": {
                        "aws:SourceArn": "arn:aws:logs:ap-northeast-2:アカウントID:*"
                    }
                }
            )
        )

        # VPCフローログの設定
        vpc_flow_log = ec2.CfnFlowLog(self, "VpcFlowLog",
            resource_id=vpc.vpc_id,
            resource_type="VPC",
            traffic_type="ALL",
            log_destination_type="s3",
            log_destination=self.vpc_flow_logs_bucket.bucket_arn
        )

        # VPCフローログの作成がバケットとポリシーの作成後に実行されるように依存関係を設定
        vpc_flow_log.node.add_dependency(self.vpc_flow_logs_bucket)

5.ソースコード詳細

5-1.バケットの作成

ALBアクセスログ用、VPCフローログ用のバケットをそれぞれ作成します。

  • "s3.Bucket"を使用
    論理ID(テンプレート内で一意)の指定をしたのち、詳細のプロパティを指定しています。
    ※デバッグしやすくするために削除の設定を入れています。要件に応じて変更してください。

プロパティは下記

使用するプロパティ 設定値 説明
bucket_name "ソースコード参照" バケットの名前。S3バケットはAWS全体でユニークでなければなりません。
removal_policy RemovalPolicy.DESTROY スタックが削除されるときにバケットも削除されるように設定します。
auto_delete_objects True バケット削除時にバケット内のオブジェクトも自動的に削除します。
encryption s3.BucketEncryption.S3_MANAGED バケットのデータはS3が管理する暗号化(SSE-S3)で保護されます。
block_public_access s3.BlockPublicAccess.BLOCK_ALL バケットのすべてのパブリックアクセスをブロックします。
  • ソースコード
        # ALBアクセスログ用のS3バケットの作成
        self.alb_access_logs_bucket = s3.Bucket(self, "AlbAccessLogsBucket",
            bucket_name="kitaya-s3-alb-accesslog",
            removal_policy=RemovalPolicy.DESTROY,
            auto_delete_objects=True,
            encryption=s3.BucketEncryption.S3_MANAGED,
            block_public_access=s3.BlockPublicAccess.BLOCK_ALL
        )

        # VPCフローログ用S3バケットの作成
        self.vpc_flow_logs_bucket = s3.Bucket(self, "VpcFlowLogsBucket",
            bucket_name="kitaya-s3-vpcflowlog",
            removal_policy=RemovalPolicy.DESTROY,
            auto_delete_objects=True,
            encryption=s3.BucketEncryption.S3_MANAGED,
            block_public_access=s3.BlockPublicAccess.BLOCK_ALL
        )

5-2.バケットポリシー追加

作成したそれぞれのバケットにバケットポリシーを追加します。

  • "add_to_resource_policy"メソッドを使用してポリシー追加(書式は下記)

"対象のバケット".add_to_resource_policy("設定内容")

  • "iam.PolicyStatement"クラスを使用してポリシーを定義
    それぞれのバケットのプロパティを説明します。

ALBアクセスログ

使用するプロパティ 設定値 説明
sid "AllowALBAccessLogs" ステートメントの識別子
effect iam.Effect.ALLOW ポリシーの効果(許可)
actions ["s3:PutObject","s3:GetBucketAcl","s3:GetObject","s3:ListBucket"] 許可するアクションのリスト。指定されたアクションに対して権限が付与されます。
resources [self.alb_access_logs_bucket.bucket_arn,f"{self.alb_access_logs_bucket.bucket_arn}/*"] ポリシーが適用されるリソース。バケットそのものとバケット内のすべてのオブジェクトが含まれます。
principals [iam.ArnPrincipal("arn:aws:iam::600734575887:root")] ポリシーの対象となるプリンシパル(エンティティ)。リージョンごとに指定されたELBアカウント ID に許可を付与します。
※詳細は公式ドキュメントを参照ください。

VPCフローログ①

使用するプロパティ 設定値 説明
sid "AllowVPCFlowLogsAccess" ステートメントの識別子
effect iam.Effect.ALLOW ポリシーの効果(許可)
actions ["s3:PutObject","s3:GetBucketAcl","s3:GetObject","s3:ListBucket"] 許可するアクションのリスト。指定されたアクションに対して権限が付与されます。
resources [f"arn:aws:s3:::{self.vpc_flow_logs_bucket.bucket_name}",f"arn:aws:s3:::{self.vpc_flow_logs_bucket.bucket_name}/*"] ポリシーが適用されるリソース。バケットそのものとバケット内のすべてのオブジェクトが含まれます。
principals [iam.ArnPrincipal("arn:aws:iam::アカウントID:root")] ポリシーの対象となるプリンシパル(エンティティ)。自分のAWSアカウントのルートユーザーを指定。

VPCフローログ②

使用するプロパティ 設定値 説明
sid "AWSLogDeliveryWrite" ステートメントの識別子
effect iam.Effect.ALLOW ポリシーの効果(許可)
actions ["s3:PutObject"] 許可されるアクションのリスト。指定されたアクションに対して権限が付与されます。
resources [f"arn:aws:s3:::{self.vpc_flow_logs_bucket.bucket_name}/AWSLogs/アカウントID/*"] アクセスが許可されるリソース
principals [iam.ServicePrincipal("delivery.logs.amazonaws.com")] アクセスを許可するプリンシパル
VPCフローログの配信サービス
conditions {
  "StringEquals":{
    "aws:SourceAccount":"アカウントID",
    "s3:x-amz-acl":"bucket-owner-full-control"
  },
  "ArnLike":{
    "aws:SourceArn":"arn:aws:logs:ap-northeast-2:アカウントID:*"
  }
}
条件のリスト
  • ソースコード
        # バケットポリシーの追加(ALBアクセスログ)
        self.alb_access_logs_bucket.add_to_resource_policy(
            iam.PolicyStatement(
                sid="AllowALBAccessLogs",
                effect=iam.Effect.ALLOW,
                actions=["s3:PutObject", "s3:GetBucketAcl", "s3:GetObject", "s3:ListBucket"],
                resources=[
                    self.alb_access_logs_bucket.bucket_arn,
                    f"{self.alb_access_logs_bucket.bucket_arn}/*"
                ],
                principals=[iam.ArnPrincipal("arn:aws:iam::600734575887:root")]
            )
        )

        # バケットポリシーの追加(VPCフローログ)
        self.vpc_flow_logs_bucket.add_to_resource_policy(
            iam.PolicyStatement(
                sid="AllowVPCFlowLogsAccess",
                effect=iam.Effect.ALLOW,
                actions=["s3:PutObject", "s3:GetBucketAcl", "s3:GetObject", "s3:ListBucket"],
                resources=[
                    f"arn:aws:s3:::{self.vpc_flow_logs_bucket.bucket_name}",
                    f"arn:aws:s3:::{self.vpc_flow_logs_bucket.bucket_name}/*"
                ]
                principals=[iam.ArnPrincipal("arn:aws:iam::アカウントID:root")],
            )
        )

        self.vpc_flow_logs_bucket.add_to_resource_policy(
            iam.PolicyStatement(
                sid="AWSLogDeliveryWrite",
                effect=iam.Effect.ALLOW,
                actions=["s3:PutObject"],
                resources=[f"arn:aws:s3:::{self.vpc_flow_logs_bucket.bucket_name}/AWSLogs/アカウントID/*"],
                principals=[iam.ServicePrincipal("delivery.logs.amazonaws.com")],
                conditions={
                    "StringEquals": {
                        "aws:SourceAccount": "アカウントID",
                        "s3:x-amz-acl": "bucket-owner-full-control"
                    },
                    "ArnLike": {
                        "aws:SourceArn": "arn:aws:logs:ap-northeast-2:アカウントID:*"
                    }
                }
            )
        )

5-3.VPCフローログの設定

作成したバケットを指定し、VPCフローログを収集する設定の追加を行います。

  • "ec2.CfnFlowLog"を使用して作成
    論理ID(テンプレート内で一意)の指定をしたのち、詳細のプロパティを指定しています。

プロパティは下記

使用するプロパティ 設定値 説明
resource_id vpc.vpc_id VPCフローログを適用するリソースのID。ここでは、VPCのIDを指定。
resource_type "VPC" リソースのタイプ。VPCフローログを作成するためのリソースタイプが指定されています。
traffic_type "ALL" フローログでキャプチャするトラフィックの種類。ALLはすべてのトラフィック(受信および送信)をキャプチャします。
log_destination_type "s3" フローログのログデスティネーションタイプ。ここでは、ログがS3バケットに送信されることを指定しています。
log_destination self.vpc_flow_logs_bucket.bucket_arn ログを送信する先のS3バケットのARNを指定。
  • ソースコード
        # VPCフローログの作成
        vpc_flow_log = ec2.CfnFlowLog(self, "VpcFlowLog",
            resource_id=vpc.vpc_id,
            resource_type="VPC",
            traffic_type="ALL",
            log_destination_type="s3",
            log_destination=self.vpc_flow_logs_bucket.bucket_arn
        )

5-4.依存関係の設定

依存関係を設定することにより、リソースが正しい順序で作成されるようにします。リソースの作成順序を自動で決定する場合もありますが、明示的に依存関係を設定することで、リソース間の関係性を正確に制御できます。これにより、スタック作成時や更新時にリソースが期待通りの順序で処理され、エラーの発生を防ぐことができます。

今回はVPCフローログの設定がバケットとポリシーの作成後に実行されるように依存関係を設定。

  • "node.add_dependency"を使用してリスナーを作成(書式は下記)
    "依存関係が設定されるリソース".node.add_dependency("依存先のリソース")

  • ソースコード

        # VPCフローログの作成がバケットとポリシーの作成後に実行されるように依存関係を設定
        vpc_flow_log.node.add_dependency(self.vpc_flow_logs_bucket)

6.検証

  • ALBアクセスログが作成したバケットに格納されていることを確認

  • VPCフローログが作成したバケットに格納されていることを確認

7.感想

特に問題なく構築できた。
S3のバケットポリシーの詳細など復習になった。

Last modified: 2024-08-14

Author