AWS 3層アーキテクチャ設計・実装ガイド

3層アーキテクチャは、Webアプリケーションを構築する際の基本的な設計パターンです。プレゼンテーション層、アプリケーション層、データ層という3つの層に機能を分離することで、システムの管理が楽になり、将来的な拡張も容易になります。AWS上で構築する場合、各層に適したサービスを組み合わせることで、高可用性とコストパフォーマンスの両方を実現できるでしょう。

本記事では、3層アーキテクチャの基本概念から、AWS上での具体的な実装方法、さらに運用時のベストプラクティスまでを網羅的に解説します。

3層アーキテクチャの基本概念

アーキテクチャ全体像

3層アーキテクチャは名前の通り、3つの層に機能を分けて構築するアプローチです。各層が独立して動作するため、どこか一部分に問題が発生しても全体への影響を最小限に抑えることができます。

各層の役割と特徴

1. プレゼンテーション層(表示層)

  • ユーザーが直接触れる部分を担当します
  • Webページの表示や静的ファイルの配信が主な役割
  • AWSでは主にCloudFront、S3、ALBを使用

2. アプリケーション層(処理層)

  • ビジネスロジックや計算処理を実行する中核部分
  • ユーザーからのリクエストを受けて、適切な処理を行います
  • AWSではEC2、Lambda、ECS、API Gatewayなどを活用

3. データ層(データ保存層)

  • アプリケーションで使用するデータを管理・保存
  • データベースやキャッシュシステムが配置されます
  • AWSではRDS、DynamoDB、ElastiCacheなどを利用

設計原則と設計時の考慮事項

3層アーキテクチャを設計する際は、次の4つの重要な原則を念頭に置く必要があります。

分離性(責務の分離) 各層が持つべき役割を明確にし、他の層の責務を担わないよう設計します。これにより、システム全体の複雑性が下がり、保守性が向上します。

スケーラビリティ(拡張性) アクセス数やデータ量の増加に対応できるよう、水平方向の拡張を前提とした設計を行います。AWSのオートスケーリング機能との組み合わせが効果的です。

可用性(障害耐性) 単一障害点をなくし、システム全体の稼働率を高めるための設計が必要です。複数のアベイラビリティゾーンへの配置が基本となります。

セキュリティ(安全性) 各層間での適切なアクセス制御と、データ保護のための暗号化を実装します。ネットワークレベルでの分離も重要な要素です。

AWS サービス選択の比較

各層で使用する主要なAWSサービスの特徴と使い分けについて整理します。

サービス概要優位性注意点適用場面
プレゼンテーション層CloudFrontグローバルCDN高速配信、DDoS保護設定変更の反映に時間静的コンテンツ配信
S3オブジェクトストレージ高耐久性、低コスト動的処理不可静的ファイル保存
ALBアプリケーション負荷分散L7負荷分散、WAF連携料金が高めHTTP/HTTPS通信
アプリケーション層EC2仮想サーバー柔軟性、フルコントロール運用負荷大カスタム環境が必要
ECSコンテナオーケストレーションスケールアウトが容易コンテナ知識必要マイクロサービス
Lambdaサーバーレス関数運用不要、従量課金実行時間制限ありイベント駆動処理
データ層RDSリレーショナルDB運用自動化、バックアップベンダーロックイン一般的なWebアプリ
DynamoDBNoSQLデータベース高いスケーラビリティSQL不可大量データ、高速アクセス
ElastiCacheインメモリキャッシュ超高速アクセスエンジンによる(Memcachedは永続化不可、Redisは可能)セッション、キャッシュ

プレゼンテーション層の設計と実装

フロントエンド配信の基本構成

プレゼンテーション層では、ユーザーに高速で安全なWebコンテンツを提供することが最も重要です。AWSでは主に3つのサービスを組み合わせて構築します。

CloudFrontとS3による高速配信

CloudFront CDN の役割 CloudFrontは世界中に配置されたエッジロケーションから、ユーザーに最も近い場所からコンテンツを配信します。これにより、地理的な距離に関係なく高速なレスポンスを実現できます。

S3での静的コンテンツ管理 HTML、CSS、JavaScript、画像などの静的ファイルはS3に保存し、CloudFront経由で配信するのが基本的なパターンです。S3の高い耐久性により、ファイルの消失リスクを大幅に軽減できます。

Infrastructure as Code での管理

インフラの設定をコードで管理することで、次のような利点があります。

  • 環境間の設定差異をなくせる
  • 設定変更の履歴を追跡できる
  • 新しい環境を短時間で構築できる
  • 人的ミスによる設定間違いを防げる

CloudFormationテンプレートの主要部分を抜粋して示します。

yaml
Resources:
  # S3バケット - 静的コンテンツ配信用
  FrontendBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub '${Environment}-app-frontend'
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256

  # CloudFront Origin Access Control (OAC)
  # S3バケットへのアクセスをCloudFrontに限定します
  OriginAccessControl:
    Type: AWS::CloudFront::OriginAccessControl
    Properties:
      OriginAccessControlConfig:
        Name: !Sub '${Environment}-frontend-oac'
        OriginAccessControlOriginType: s3
        SigningBehavior: always
        SigningProtocol: sigv4

  # S3バケットポリシー
  # OAC経由でのCloudFrontからのアクセスのみを許可します
  FrontendBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref FrontendBucket
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Sid: AllowCloudFrontServicePrincipal
            Effect: Allow
            Principal:
              Service: cloudfront.amazonaws.com
            Action: 's3:GetObject'
            Resource: !Sub 'arn:aws:s3:::${FrontendBucket}/*'
            Condition:
              StringEquals:
                'AWS:SourceArn': !Sub 'arn:aws:cloudfront::${AWS::AccountId}:distribution/${CloudFrontDistribution}'

  # CloudFront Distribution - グローバル配信
  CloudFrontDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Enabled: true
        Comment: 'Webアプリケーション配信用CDN'
        Origins:
          - Id: S3-Origin
            DomainName: !GetAtt FrontendBucket.RegionalDomainName
            S3OriginConfig:
              OriginAccessIdentity: '' # OACを使用するため空にします
            OriginAccessControlId: !GetAtt OriginAccessControl.Id
        DefaultCacheBehavior:
          TargetOriginId: S3-Origin
          ViewerProtocolPolicy: redirect-to-https
          Compress: true

セキュリティとパフォーマンスの最適化

WAF(Web Application Firewall)の活用 CloudFrontと組み合わせることで、SQLインジェクションやクロスサイトスクリプティング(XSS)攻撃を自動的に防ぐことができます。また、特定の国からのアクセスを制限する地理的ブロック機能も利用できます。

キャッシュ戦略の設定 静的ファイルは長時間キャッシュし、動的なAPIレスポンスは短時間のキャッシュまたはキャッシュなしに設定することで、パフォーマンスとデータの新鮮さのバランスを取ります。

アプリケーション層の設計と実装

アプリケーション処理の中核部分

アプリケーション層は、ユーザーからの要求を受けて実際の処理を行う、システムの心臓部です。ここでビジネスロジックを実行し、必要に応じてデータ層とやり取りを行います。

負荷分散とスケーリング戦略

Application Load Balancer(ALB)の役割 ALBは入ってくるリクエストを複数のサーバーに振り分けることで、一つのサーバーに負荷が集中することを防ぎます。また、異常なサーバーを自動的に検出して、正常なサーバーにのみトラフィックを送る機能も備えています。

オートスケーリングの活用 アクセス数の増減に応じて、自動的にサーバーの台数を調整する仕組みです。夜間や休日などアクセスが少ない時間帯はサーバー数を減らし、逆にアクセスが集中する時間帯は自動でサーバーを追加します。

コンテナとサーバーレスの使い分け

コンテナ化のメリット

  • アプリケーションを軽量でポータブルな形にパッケージ化
  • 開発環境と本番環境で同じ動作を保証
  • マイクロサービスアーキテクチャとの親和性が高い

サーバーレス(Lambda)の適用場面

  • リクエスト数が不定期で変動が大きい処理
  • バッチ処理やデータ変換などのイベント駆動型処理
  • サーバー運用負荷を極限まで下げたい場合

基本的な設定例を示します。

yaml
Resources:
  # Application Load Balancer - トラフィック分散
  ApplicationLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: !Sub '${Environment}-app-alb'
      Scheme: internet-facing
      Type: application
      Subnets: !Ref PublicSubnetIds
      SecurityGroups:
        - !Ref ALBSecurityGroup # セキュリティグループの指定を推奨

  # ECS Cluster - コンテナ管理
  ECSCluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName: !Sub '${Environment}-app-cluster'
      CapacityProviders:
        - FARGATE
      
  # ECS Service - アプリケーション実行
  AppECSService:
    Type: AWS::ECS::Service
    Properties:
      ServiceName: !Sub '${Environment}-app-service'
      Cluster: !Ref ECSCluster
      TaskDefinition: !Ref AppTaskDefinition # 実行するタスク定義のARN
      DesiredCount: 2
      LaunchType: FARGATE
      NetworkConfiguration:
        AwsvpcConfiguration:
          Subnets: !Ref PrivateSubnetIds
          SecurityGroups:
            - !Ref ECSSecurityGroup
          AssignPublicIp: DISABLED
      LoadBalancers:
        - ContainerName: your-container-name
          ContainerPort: 8080
          TargetGroupArn: !Ref YourTargetGroupArn

セキュリティグループの設定

アプリケーション層では、適切なネットワークアクセス制御が重要です。セキュリティグループを使って、必要最小限の通信のみを許可します。

  • ALB: インターネットからのHTTP/HTTPS(80,443番ポート)のみ許可
  • ECS/EC2: ALBからのアプリケーションポート(8080等)のみ許可
  • Lambda: VPC内からの必要な通信のみ許可

データ層の設計と実装

データ管理の基盤設計

データ層では、アプリケーションが必要とする全てのデータを安全かつ効率的に管理します。用途に応じて複数のデータストアを使い分けることで、最適なパフォーマンスとコストバランスを実現できます。

データベース選択のポイント

RDS(リレーショナルデータベース) 従来のWebアプリケーションで使われる、表形式でデータを管理するデータベースです。SQL言語を使ってデータの操作を行うため、多くの開発者にとって馴染みがあります。

  • 複雑な関連性を持つデータの管理に適している
  • ACID特性による高い整合性を保証
  • 既存のアプリケーションからの移行が容易

DynamoDB(NoSQLデータベース) 従来のデータベースとは異なり、より柔軟なデータ構造を扱えるデータベースです。大量のデータを高速に処理できるのが特徴です。

  • 秒間数百万のリクエストを処理可能
  • 自動的なスケーリングでコスト最適化
  • シンプルなデータ構造の高速処理に最適

ElastiCache(インメモリキャッシュ) よく使われるデータをメモリ上に一時保存することで、データベースへの負荷を軽減し、応答速度を大幅に向上させます。

  • ミリ秒未満の超高速レスポンス
  • セッション情報の共有に最適
  • データベース負荷の大幅軽減

データの暗号化とバックアップ戦略

保存時の暗号化 全てのデータストアでAWS KMS(Key Management Service)を使用した暗号化を実施します。これにより、仮にストレージデバイスが盗まれても、データを読み取ることは困難になります。

転送時の暗号化 アプリケーションとデータベース間の通信は、TLS/SSLプロトコルによる暗号化を行います。ネットワーク上でデータが傍受されても、内容を解読することはできません。

自動バックアップの設定 各データストアで自動バックアップを設定し、万が一のデータ消失に備えます。RDSでは日次バックアップとポイントインタイムリカバリ、DynamoDBでは継続的バックアップを利用します。

基本的な設定例を示します。

yaml
Resources:
  # RDS Aurora クラスター - メインデータベース
  AuroraCluster:
    Type: AWS::RDS::DBCluster
    Properties:
      DBClusterIdentifier: !Sub '${Environment}-aurora-cluster'
      Engine: aurora-postgresql
      MasterUsername: !Ref MasterUsername
      MasterUserPassword: !Ref MasterPassword
      DBSubnetGroupName: !Ref YourDBSubnetGroup # DBサブネットグループを指定
      VpcSecurityGroupIds:
        - !Ref DatabaseSecurityGroup # セキュリティグループの指定を推奨
      BackupRetentionPeriod: 30
      StorageEncrypted: true
      DeletionProtection: true # 削除保護を有効化

  # DynamoDB テーブル - 高速NoSQLデータベース
  UserProfilesTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: !Sub '${Environment}-UserProfiles'
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: user_id
          AttributeType: S
      KeySchema:
        - AttributeName: user_id
          KeyType: HASH
      SSESpecification:
        SSEEnabled: true

統合監視と運用管理

CloudWatch による包括監視

システム全体の健全性を把握するため、各層のメトリクスを統合的に監視します。CloudWatchダッシュボードを使用することで、運用チームは一目でシステム状況を把握できます。

重要な監視項目

プレゼンテーション層

  • CloudFrontエラー率とレスポンス時間
  • ALBの健全なターゲット数
  • WAFによるブロック数

アプリケーション層

  • EC2/ECSのCPU・メモリ使用率
  • ALBのリクエスト数とレスポンス時間
  • オートスケーリングの実行状況

データ層

  • RDSの接続数とCPU使用率
  • DynamoDBの読み取り・書き込み容量
  • ElastiCacheのキャッシュヒット率

アラート設定の考え方

緊急度に応じてアラートを分類し、適切な対応を促します。

緊急度対象メトリクス通知方法対応時間
Criticalサービス停止、エラー率急増即時メール・SMS15分以内
Warning性能劣化、容量不足予兆メール通知1時間以内
Info定期メンテナンス、設定変更ログ記録のみ翌営業日

セキュリティ実装のポイント

多層防御アプローチ

3層アーキテクチャでは、各層でセキュリティ対策を実施することで、単一のセキュリティ機能が突破されても他の層で脅威を阻止できます。

ネットワークレベル

  • VPCによる論理的分離
  • プライベートサブネットでデータ層を保護
  • セキュリティグループで最小限のアクセス許可

アプリケーションレベル

  • WAFによるWebアプリケーション攻撃の防御
  • IAMロールによる最小権限アクセス
  • アプリケーション間通信の暗号化

データレベル

  • 保存時暗号化(KMS使用)
  • 転送時暗号化(TLS/SSL)
  • データベースレベルでのアクセス制御

まとめ

3層アーキテクチャ導入の効果

AWS上での3層アーキテクチャは、以下のような効果をもたらします。

開発効率の向上

  • 層ごとの独立した開発が可能
  • 専門知識を活かした分業体制の構築
  • 部分的な修正・改善の実施

運用負荷の軽減

  • 層ごとの独立したスケーリング
  • 障害影響範囲の局所化
  • 段階的なアップデートの実施

セキュリティの強化

  • 多層防御による脅威への対応
  • データへのアクセス経路の制限
  • 各層での適切なセキュリティ対策

実装時の重要ポイント

3層アーキテクチャを成功させるためのポイントを再度まとめます。

  1. 明確な責務分離 - 各層の役割を明確にし、越境しない設計
  2. 適切なサービス選択 - 用途に応じた最適なAWSサービスの選択
  3. スケーラビリティ設計 - 将来の成長を見据えた柔軟な設計
  4. セキュリティファースト - 設計段階からのセキュリティ考慮
  5. 運用を意識した設計 - 監視・保守のしやすさを重視

3層アーキテクチャは、現代のWebアプリケーション開発における基本パターンです。AWSの豊富なサービス群を活用することで、高品質かつ効率的なシステムを構築することができるでしょう。