👏

AWS学びなおし(+TF)_S3

2025/02/24に公開

Amazon S3(Simple Storage Service)は、AWSが提供するオブジェクトストレージサービスです。オブジェクトストレージとは、データを「オブジェクト」という単位で管理するストレージ方式であり、ファイルシステムのように階層構造を持たず、フラットな構造でデータを格納します。S3は、事実上無限のストレージ容量と高い可用性、耐久性を誇り、インターネット経由でどこからでもアクセスできるため、様々な用途で活用されています。

S3の基本的な構成要素

  • バケット (Bucket): オブジェクトを格納するためのコンテナです。バケット名はグローバルに一意である必要があり、DNS名前空間に似た形で管理されます。バケットはリージョン(地理的な場所)に紐づけられ、作成時にリージョンを選択します。
  • オブジェクト (Object): 実際に格納されるデータの実体です。ファイル、画像、動画、ドキュメントなど、あらゆる種類のデータをオブジェクトとしてS3に保存できます。オブジェクトは、データ自体とメタデータで構成されます。
  • キー (Key): バケット内でオブジェクトを一意に識別するための名前です。ファイルパスのような形式で指定でき、オブジェクトへのアクセスに使用されます。
  • リージョン (Region): AWSのインフラストラクチャが物理的に存在する場所です。S3バケットは特定のリージョンに作成され、データはそのリージョン内に保存されます。リージョンを選択する際には、レイテンシ、コスト、法令遵守などを考慮する必要があります。
  • ストレージクラス (Storage Class): オブジェクトのアクセス頻度や可用性要件に応じて選択できるストレージの種類です。代表的なストレージクラスには、Standard、Intelligent-Tiering、Standard-IA、One Zone-IA、Glacier、Deep Archiveなどがあります。ストレージクラスによって、料金、可用性、耐久性、データ取り出し時間などが異なります。

S3の主な機能

  • データストレージ: あらゆる種類のデータを安全かつ耐久性高く保存できます。
  • データバックアップと復元: 重要なデータのバックアップ先として利用でき、災害対策やデータ復旧に役立ちます。
  • コンテンツ配信 (CDN): 静的コンテンツ(画像、動画、Webサイトファイルなど)を高速に配信するためのオリジンストレージとして利用できます (CloudFrontと連携)。
  • ビッグデータ分析: 大量のデータを格納し、分析基盤 (Amazon EMR, Athenaなど) からアクセスすることで、データ分析を効率的に行えます。
  • アーカイブ: 長期間保管が必要なデータを低コストで安全に保管できます (Glacier, Deep Archive)。
  • 静的ウェブサイトホスティング: S3バケットをWebサーバーとして設定し、静的なWebサイトを公開できます。
  • アクセス制御: IAM (Identity and Access Management) ポリシー、バケットポリシー、ACL (Access Control List) などを用いて、オブジェクトやバケットへのアクセスを細かく制御できます。
  • バージョニング: オブジェクトのバージョン管理機能です。誤ってオブジェクトを削除したり、上書きした場合でも、以前のバージョンを復元できます。
  • 暗号化: 保存時暗号化 (SSE-S3, SSE-KMS, SSE-C) および転送時暗号化 (HTTPS) をサポートし、データを保護します。
  • ライフサイクル管理: オブジェクトの経過時間やストレージクラスに基づいて、自動的にストレージクラスを移行したり、オブジェクトを削除したりするルールを設定できます。コスト最適化に有効です。
  • イベント通知: S3内のオブジェクトに対する変更(作成、削除など)をトリガーとして、Lambda関数やSQSキューなどを実行できます。
  • S3 Storage Lens: S3の使用状況とアクティビティに関する組織全体の可視性を提供する分析ツールです。ストレージコストの最適化やデータ保護に役立ちます。
  • S3 Object Lambda: S3からデータを取得する際に、アプリケーションコードを自動的に実行し、データを変換・加工してからアプリケーションに返す機能です。

【実務レベルの内容と重要事項】

S3を実務で利用する上で、以下の点が重要になります。

  • セキュリティ:

    • アクセス制御: IAMポリシー、バケットポリシー、ACLを適切に設定し、必要最小限のアクセス許可のみを付与する。特に、パブリックアクセス設定には注意が必要です。
    • 暗号化: 重要なデータは必ず保存時暗号化 (SSE-KMS推奨) を有効にする。転送時暗号化 (HTTPS) も必須です。
    • VPCエンドポイント: VPC内のEC2インスタンスなどからS3へアクセスする場合、VPCエンドポイント (Gateway Endpoint for S3) を利用することで、インターネットを経由せずにセキュアにアクセスできます。
    • S3アクセスログ、監査ログ: S3へのアクセスログを記録し、不正アクセスやセキュリティインシデントの早期発見に役立てる。AWS CloudTrailと連携して監査ログを取得することも重要です。
    • バケットポリシーの定期的な見直し: バケットポリシーは定期的に見直し、不要なアクセス許可がないか確認する。
  • パフォーマンス:

    • プレフィックス設計: 大量のオブジェクトを格納する場合、プレフィックス (キーの先頭部分) を適切に設計することで、GetObjectやListObjectsなどのパフォーマンスを向上させることができます。
    • 並列処理: 大量のデータをS3にアップロード/ダウンロードする場合は、並列処理を活用することで処理時間を短縮できます (例: AWS CLIのs3 cp --recursive --sse aws:kms --region <リージョン> --source-region <リージョン> --acl bucket-owner-full-control --expected-bucket-owner <アカウントID> --storage-class STANDARD_IA --grants read=uri=http://acs.amazonaws.com/groups/global/AuthenticatedUsers s3://<送信元バケット名> s3://<送信先バケット名> コマンド)。
    • CloudFront連携: 静的コンテンツ配信を高速化するために、CloudFrontなどのCDNと連携する。
    • Transfer Acceleration: 長距離間のデータ転送を高速化する機能。
  • 可用性と耐久性:

    • S3は非常に高い可用性 (99.99%) と耐久性 (99.999999999%) を誇りますが、ストレージクラスによっては可用性や耐久性が異なる場合があります。要件に応じて適切なストレージクラスを選択する。
    • クロスリージョンレプリケーション: 災害対策 (DR) のために、異なるリージョンにデータをレプリケーションする。
  • コスト最適化:

    • ストレージクラスの適切な選択: アクセス頻度に応じて最適なストレージクラスを選択し、コストを削減する (例: 低頻度アクセスデータはStandard-IA, 長期アーカイブデータはGlacier)。
    • ライフサイクルポリシー: ライフサイクルポリシーを設定し、不要になったオブジェクトを自動的に削除したり、低コストなストレージクラスに移行したりする。
    • S3 Storage Lens: S3 Storage Lensを活用してストレージ使用状況を分析し、コスト削減の機会を見つける。
    • データ削除: 不要になったデータは定期的に削除する。
  • 運用管理:

    • モニタリング: CloudWatchメトリクスやS3 Storage Lensを用いて、S3の利用状況やパフォーマンスを監視する。
    • バックアップとリストア: バージョニングやクロスリージョンレプリケーションをバックアップ戦略に取り入れ、データ損失に備える。
    • 災害対策 (DR): クロスリージョンレプリケーションを活用したDR計画を策定し、定期的にDR訓練を実施する。

【実務でどの程度使用されるのか】

S3は、AWSの中でも最も基本的かつ重要なサービスの一つであり、実務での利用頻度は非常に高いです。ほぼ全てのAWSサービスがS3と連携しており、様々なユースケースで活用されています。

実務での具体的な利用例:

  • Webサイト/アプリケーションの静的コンテンツ配信: 画像、CSS、JavaScriptファイルなどの静的コンテンツをS3に格納し、Webサイトやアプリケーションから配信する。CloudFrontと連携することで、高速かつスケーラブルな配信基盤を構築できます。
  • データレイク/ビッグデータ分析基盤: 大量の構造化/非構造化データをS3に集約し、データレイクとして活用する。Amazon EMR, Athena, Redshift Spectrumなどの分析サービスと連携することで、データ分析基盤を構築できます。
  • バックアップ/アーカイブストレージ: データベース、ファイルサーバー、EC2インスタンスなどのバックアップデータをS3に格納する。GlacierやDeep Archiveなどの低コストなストレージクラスを活用することで、長期アーカイブストレージとしても利用できます。
  • ファイル共有/コンテンツ共有: 社内外のファイル共有基盤としてS3を利用する。プレサインURLを発行することで、一時的なアクセス権限を付与することも可能です。
  • ソフトウェア/メディアファイルの配布: ソフトウェアのインストールファイルや動画ファイルなどの配布基盤としてS3を利用する。

S3は、クラウドネイティブなシステムを構築する上で不可欠なサービスと言えます。あらゆる規模の企業、様々な業界で、S3はデータストレージ、データ管理、データ活用の中核的な役割を担っています。

【terraformのコードで記述する場合の基本的内容と実務レベルの内容】

基本的なS3バケット作成 (Terraform)

resource "aws_s3_bucket" "example" {
  bucket = "my-unique-bucket-name" # バケット名はグローバルに一意である必要があります
  acl    = "private" # デフォルトはprivateを推奨
  region = "ap-northeast-1" # リージョンを指定 (例: 東京リージョン)

  tags = {
    Name        = "example-bucket"
    Environment = "production"
  }
}

解説:

  • resource "aws_s3_bucket" "example": aws_s3_bucketリソースを定義し、exampleという名前を付けています (Terraform内部での識別名)。
  • bucket = "my-unique-bucket-name": 作成するバケットの名前を指定します。グローバルに一意である必要があります。
  • acl = "private": ACL (Access Control List) を private に設定しています。デフォルトでは private を推奨し、必要に応じてバケットポリシーなどでアクセス許可を付与します。
  • region = "ap-northeast-1": バケットを作成するリージョンを指定します。
  • tags = { ... }: バケットにタグを付与します。リソース管理やコスト管理に役立ちます。

実務レベルのS3バケット作成 (Terraform)

resource "aws_s3_bucket" "example" {
  bucket = "my-production-bucket-name"
  acl    = "private"
  region = "ap-northeast-1"

  versioning {
    enabled = true # バージョニングを有効化 (データ保護のために推奨)
  }

  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "AES256" # SSE-S3 (S3マネージドキーによる暗号化) を有効化
      }
    }
  }

  lifecycle_rule {
    id = "glacier-transition"
    enabled = true
    transition {
      days          = 30 # 作成後30日経過したら
      storage_class = "GLACIER" # GLACIERストレージクラスに移行
    }
    noncurrent_version_transition { # バージョニング有効時の設定
      days          = 90 # 非現行バージョンになってから90日経過したら
      storage_class = "GLACIER" # GLACIERストレージクラスに移行
    }
  }

  logging { # アクセスログ設定
    target_bucket = aws_s3_bucket.log_bucket.id # ログ出力先バケット
    target_prefix = "example-bucket-logs/" # ログのプレフィックス
  }

  tags = {
    Name        = "production-bucket"
    Environment = "production"
    CostCenter  = "it-department" # コストセンタータグ
  }
}

resource "aws_s3_bucket" "log_bucket" { # ログ出力先バケット (別途作成が必要)
  bucket = "my-log-bucket-name"
  acl    = "log-delivery-write" # ログ書き込み権限を付与
  region = "ap-northeast-1"

  policy = data.aws_iam_policy_document.log_bucket_policy.json # バケットポリシーでログ書き込み許可を設定

  tags = {
    Name        = "log-bucket"
    Environment = "production"
  }
}

data "aws_iam_policy_document" "log_bucket_policy" { # ログ出力先バケットのポリシー
  statement {
    sid = "AWSLogDeliveryWrite"
    effect = "Allow"
    principals {
      type = "Service"
      identifiers = ["logging.s3.amazonaws.com"]
    }
    actions = ["s3:PutObject", "s3:GetBucketAcl"]
    resources = [
      "arn:aws:s3:::${aws_s3_bucket.log_bucket.id}/*",
      "arn:aws:s3:::${aws_s3_bucket.log_bucket.id}",
    ]
    condition {
      test = "StringEquals"
      variable = "aws:SourceAccount"
      values = [data.aws_caller_identity.current.account_id] # 自身のアカウントID
    }
  }
  statement {
    sid = "AWSLogDeliveryCheck"
    effect = "Allow"
    principals {
      type = "Service"
      identifiers = ["logging.s3.amazonaws.com"]
    }
    actions = ["s3:GetBucketPolicy"]
    resources = ["arn:aws:s3:::${aws_s3_bucket.log_bucket.id}"]
    condition {
      test = "StringEquals"
      variable = "aws:SourceAccount"
      values = [data.aws_caller_identity.current.account_id] # 自身のアカウントID
    }
  }
}

data "aws_caller_identity" "current" {} # 現在のアカウントIDを取得

実務レベルのコード解説:

  • versioning { enabled = true }: バージョニングを有効化しています。データ保護の観点から、実務環境では有効化を強く推奨します。
  • server_side_encryption_configuration { ... }: 保存時暗号化 (SSE-S3) を有効化しています。セキュリティ要件に応じて、SSE-KMS (AWS KMSによる暗号化) や SSE-C (顧客提供キーによる暗号化) を選択することも可能です。
  • lifecycle_rule { ... }: ライフサイクルルールを設定しています。ここでは、作成後30日経過したオブジェクトをGLACIERストレージクラスに移行するルールと、バージョニング有効時の非現行バージョンを90日後にGLACIERに移行するルールを設定しています。ストレージコスト最適化に有効です。
  • logging { ... }: アクセスログ設定を有効化しています。S3へのアクセス状況をログとして記録し、セキュリティ監査やトラブルシューティングに役立てます。ログ出力先バケット (aws_s3_bucket.log_bucket) は別途作成する必要があります。
  • tags = { ... }: より詳細なタグ (例: コストセンタータグ) を付与しています。コスト管理やリソース管理を高度化するために重要です。
  • ログ出力先バケット (aws_s3_bucket.log_bucket):
    • ログ出力先バケットもTerraformで定義しています。
    • acl = "log-delivery-write": ACLでログ書き込み権限を付与しています。
    • policy = data.aws_iam_policy_document.log_bucket_policy.json: バケットポリシーでログ書き込み許可を設定しています。AWSのログ配信サービス (logging.s3.amazonaws.com) からの書き込みを許可する必要があります。
  • data "aws_iam_policy_document" "log_bucket_policy" { ... }: ログ出力先バケットのバケットポリシーを定義しています。IAMポリシーDocumentデータソースを利用してJSON形式のポリシーを生成し、policy引数に渡しています。
  • data "aws_caller_identity" "current" {}: 現在のAWSアカウントIDを取得するために、aws_caller_identityデータソースを利用しています。バケットポリシーで自身のアカウントIDを指定するために使用します。

Terraform 実務レベルのポイント:

  • モジュール化: S3バケットの設定をモジュール化することで、コードの再利用性、可読性、保守性を向上させることができます。
  • 変数 (Variables) の活用: バケット名、リージョン、ストレージクラスなどの設定値を変数として定義し、柔軟性を高めます。
  • バックエンド設定: Terraform State ファイルをS3で管理することで、チームでのTerraform運用を安全かつ効率的に行うことができます。
  • CI/CDパイプラインへの組み込み: TerraformコードをCI/CDパイプラインに組み込み、Infrastructure as Code (IaC) を実現します。

上記Terraformコードはあくまで一例です。実際の環境では、セキュリティ要件、可用性要件、コスト要件、運用要件などを考慮し、適切な設定を行う必要があります。

Discussion