🏔️

生成AIでAWS Well-Architectedレビューを自動化:IaC Analyzerの可能性と注意点を考察

はじめに

AWS Well-Architected Frameworkは、AWSのベストプラクティスに照らしてアーキテクチャを評価し、改善すべき分野を特定する一貫した方法を提供します。しかし、従来の手動レビューには課題がありました:

  • 時間がかかる:複数の関係者を集めて長時間のレビューセッションが必要
  • 主観的な解釈:レビュアーによって同じワークロードの評価が異なる可能性
  • 限定的なスコープ:高レベルのアーキテクチャに焦点が当たり、実装の詳細まで踏み込めない
  • ポイントインタイム評価:インフラの進化に伴い、結果がすぐに古くなる

これらの課題を解決するため、AWSは生成AIを活用したWell-Architected IaC Analyzerを公開しました。本記事では、公式ワークショップで提供されているサンプルコードとアーキテクチャ図を使って、このツールの分析結果を詳しく考察します。

重要: 生成AIツールはレビュープロセスを強化しますが、人間の専門知識に取って代わるものではありません。最終的な判断には、常に人間の判断とビジネス要件の理解が必要です。

Well-Architected IaC Analyzerとは

Well-Architected IaC Analyzerは、AWSが公開しているサンプルプロジェクトで、生成AIを使ってインフラストラクチャコードをAWS Well-Architectedベストプラクティスに照らして評価するツールです。

アーキテクチャ概要

主な特徴

  • 多様な入力形式に対応

    • CloudFormation(YAML/JSON)
    • Terraform(.tf)
    • AWS CDK(全対応言語)
    • アーキテクチャ図(PNG、JPEG)
    • PDFドキュメント
  • 生成AI技術の活用

    • Amazon Bedrock(Claude 3.5 Sonnet v2)
    • RAG(Retrieval-Augmented Generation)による高精度な推奨
    • OpenSearch Serverlessによるナレッジベース
  • 包括的な評価

    • Well-Architectedフレームワーク(6つの柱)
    • 専門レンズ(Serverless、IoT、SaaS、Machine Learning、Generative AIなど)
    • Well-Architectedツールとの統合
  • Analyzer Assistantチャットボット

    • 分析結果について質問可能
    • Well-Architectedベストプラクティスの詳細説明
    • 実装のためのガイダンス
  • その他の機能

    • アーキテクチャ図からIaCテンプレート生成
    • 多言語対応
    • 分析結果のエクスポート

検証環境のセットアップ

デプロイ方法

今回は公式ワークショップに従い、CloudFormationテンプレートを使用してデプロイしました。

詳しい手順はこちらをご参照ください。

デプロイ後のアプリケーション画面は以下のイメージです。IaCファイルやアーキテクチャ図をアップロードし、評価したい柱を選択して「Start Review」で分析を開始します。

分析パターン1:CloudFormationテンプレート分析

分析対象

ワークショップで提供されている3層WebアプリケーションのCloudFormationテンプレート(three-tier-app.yaml)を、セキュリティ柱で分析しました。

three-tier-app.yaml コード

(クリックして展開)
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Sample three-tier application'

Resources:
  # VPC and Network Configuration
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: ThreeTierVPC

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: ThreeTierIGW

  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  # Public Subnets (Web Tier)
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: PublicSubnet1

  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.2.0/24
      AvailabilityZone: !Select [1, !GetAZs '']
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: PublicSubnet2

  # Private Subnets (App Tier)
  AppSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.3.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      Tags:
        - Key: Name
          Value: AppSubnet1

  AppSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.4.0/24
      AvailabilityZone: !Select [1, !GetAZs '']
      Tags:
        - Key: Name
          Value: AppSubnet2

  # Private Subnets (DB Tier)
  DBSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.5.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      Tags:
        - Key: Name
          Value: DBSubnet1

  DBSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.6.0/24
      AvailabilityZone: !Select [1, !GetAZs '']
      Tags:
        - Key: Name
          Value: DBSubnet2

  # Route Tables
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: PublicRouteTable

  PublicRoute:
    Type: AWS::EC2::Route
    DependsOn: AttachGateway
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  PublicSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet1
      RouteTableId: !Ref PublicRouteTable

  PublicSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet2
      RouteTableId: !Ref PublicRouteTable

  # NAT Gateway for private subnets
  NatGatewayEIP:
    Type: AWS::EC2::EIP
    DependsOn: AttachGateway
    Properties:
      Domain: vpc

  NatGateway:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatGatewayEIP.AllocationId
      SubnetId: !Ref PublicSubnet1

  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: PrivateRouteTable

  PrivateRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGateway

  AppSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref AppSubnet1
      RouteTableId: !Ref PrivateRouteTable

  AppSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref AppSubnet2
      RouteTableId: !Ref PrivateRouteTable

  DBSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref DBSubnet1
      RouteTableId: !Ref PrivateRouteTable

  DBSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref DBSubnet2
      RouteTableId: !Ref PrivateRouteTable

  # Security Groups
  WebTierSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for web tier
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0  # SSH open to the world
      Tags:
        - Key: Name
          Value: WebTierSG

  AppTierSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for application tier
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 8080
          ToPort: 8080
          SourceSecurityGroupId: !Ref WebTierSecurityGroup
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0  # SSH open to the world
      Tags:
        - Key: Name
          Value: AppTierSG

  DBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for database tier
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          SourceSecurityGroupId: !Ref AppTierSecurityGroup
      Tags:
        - Key: Name
          Value: DBSecurityGroup

  # DB Subnet Group
  DBSubnetGroup:
    Type: AWS::RDS::DBSubnetGroup
    Properties:
      DBSubnetGroupDescription: Subnet group for RDS database
      SubnetIds:
        - !Ref DBSubnet1
        - !Ref DBSubnet2

  # Database Instance
  Database:
    Type: AWS::RDS::DBInstance
    Properties:
      AllocatedStorage: 20
      DBInstanceClass: db.t3.micro
      Engine: mysql
      EngineVersion: 8.0
      MasterUsername: admin
      MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBSecret}:SecretString:password}}'
      DBName: applicationdb
      VPCSecurityGroups:
        - !GetAtt DBSecurityGroup.GroupId
      DBSubnetGroupName: !Ref DBSubnetGroup
      MultiAZ: false
      StorageEncrypted: false  # Database storage not encrypted

  # Secret for database credentials
  DBSecret:
    Type: AWS::SecretsManager::Secret
    Properties:
      Name: !Sub '${AWS::StackName}-db-credentials'
      Description: RDS database credentials
      GenerateSecretString:
        SecretStringTemplate: '{"username": "admin"}'
        GenerateStringKey: password
        PasswordLength: 16
        ExcludeCharacters: '"@/\'

  # Web Tier Load Balancer
  WebTierALB:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Subnets:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2
      SecurityGroups:
        - !Ref WebTierSecurityGroup
      Scheme: internet-facing
      Tags:
        - Key: Name
          Value: WebTierALB

  WebTierTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      VpcId: !Ref VPC
      Port: 80
      Protocol: HTTP  # Using HTTP instead of HTTPS
      HealthCheckPath: /
      HealthCheckIntervalSeconds: 30
      HealthCheckTimeoutSeconds: 5
      HealthyThresholdCount: 2
      UnhealthyThresholdCount: 5
      TargetType: instance

  WebTierListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref WebTierTargetGroup
      LoadBalancerArn: !Ref WebTierALB
      Port: 80
      Protocol: HTTP  # Using HTTP instead of HTTPS

  # App Tier Load Balancer (Internal)
  AppTierALB:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Subnets:
        - !Ref AppSubnet1
        - !Ref AppSubnet2
      SecurityGroups:
        - !Ref AppTierSecurityGroup
      Scheme: internal
      Tags:
        - Key: Name
          Value: AppTierALB

  AppTierTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      VpcId: !Ref VPC
      Port: 8080
      Protocol: HTTP
      HealthCheckPath: /health
      HealthCheckIntervalSeconds: 30
      HealthCheckTimeoutSeconds: 5
      HealthyThresholdCount: 2
      UnhealthyThresholdCount: 5
      TargetType: instance

  AppTierListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: forward
          TargetGroupArn: !Ref AppTierTargetGroup
      LoadBalancerArn: !Ref AppTierALB
      Port: 8080
      Protocol: HTTP

  # Web Tier Auto Scaling Group
  WebTierLaunchConfig:
    Type: AWS::AutoScaling::LaunchConfiguration
    Properties:
      ImageId: ami-0c55b159cbfafe1f0  # Amazon Linux 2 AMI
      InstanceType: t3.micro
      SecurityGroups:
        - !Ref WebTierSecurityGroup
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          yum update -y
          yum install -y httpd
          systemctl start httpd
          systemctl enable httpd
          echo "<html><body><h1>Web Tier</h1></body></html>" > /var/www/html/index.html

  WebTierASG:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      LaunchConfigurationName: !Ref WebTierLaunchConfig
      MinSize: 2
      MaxSize: 4
      DesiredCapacity: 2
      VPCZoneIdentifier:
        - !Ref PublicSubnet1
        - !Ref PublicSubnet2
      TargetGroupARNs:
        - !Ref WebTierTargetGroup
      Tags:
        - Key: Name
          Value: WebTierInstance
          PropagateAtLaunch: true

  # App Tier Auto Scaling Group
  AppTierLaunchConfig:
    Type: AWS::AutoScaling::LaunchConfiguration
    Properties:
      ImageId: ami-0c55b159cbfafe1f0  # Amazon Linux 2 AMI
      InstanceType: t3.micro
      SecurityGroups:
        - !Ref AppTierSecurityGroup
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          yum update -y
          yum install -y java-1.8.0-openjdk
          mkdir -p /opt/app
          echo "#!/bin/bash" > /opt/app/start.sh
          echo "while true; do echo 'App server running' >> /var/log/app.log; sleep 10; done" >> /opt/app/start.sh
          chmod +x /opt/app/start.sh
          /opt/app/start.sh &
          echo '{"status":"healthy"}' > /opt/app/health

  AppTierASG:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      LaunchConfigurationName: !Ref AppTierLaunchConfig
      MinSize: 2
      MaxSize: 4
      DesiredCapacity: 2
      VPCZoneIdentifier:
        - !Ref AppSubnet1
        - !Ref AppSubnet2
      TargetGroupARNs:
        - !Ref AppTierTargetGroup
      Tags:
        - Key: Name
          Value: AppTierInstance
          PropagateAtLaunch: true

  # S3 Bucket for application logs
  LogBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub '${AWS::StackName}-logs-${AWS::AccountId}'

Outputs:
  WebsiteURL:
    Description: URL for the web application
    Value: !Sub http://${WebTierALB.DNSName}
  VPCId:
    Description: VPC ID
    Value: !Ref VPC

↓図で表すとこのようなアーキテクチャ(この図は読み込ませておらず、three-tier-app.yamlを読み込ませてレビューしている)

↓分析中の様子

分析結果サマリー

項目 数 割合
評価されたベストプラクティス 63 100%
適用済み (Applied) 5 8%
未適用 (Not Applied) 45 71%
該当なし (Not Relevant) 13 21%

適用済み項目(5件)の詳細分析

まず、ツールが「適用済み」と評価した5件を見てみます。これらは適切に評価されています。

ベストプラクティス 評価理由
セキュリティ管理範囲を縮小する RDS、ALB、Auto Scaling、Secrets Managerなどマネージドサービスを使用
標準セキュリティコントロールのデプロイを自動化する CloudFormationで全リソースをコード化
シークレットを安全に保存・使用する DBマスターパスワードをSecrets Managerに保存。動的参照構文で実行時に取得
ネットワーク層を作成する パブリック/プライベート/分離サブネットで3層構成を実装
ソフトウェアをプログラマティックにデプロイする インフラ全体がCloudFormation IaCで定義・デプロイ

検出された問題の分類

45件の指摘を、筆者が独自に3つのカテゴリに分類しました。
それぞれいくつかの例を挙げます。

1.確実な問題

テンプレートに明示的に記載されている設定不備です。

問題 検出内容 リスク
SSH 0.0.0.0/0公開 セキュリティグループで0.0.0.0/0からポート22を許可 全世界からSSHアクセス可能
RDS暗号化なし StorageEncrypted: falseが明示的に設定 データ漏洩リスク
HTTPのみ ALBがHTTPプロトコルを使用。コメントに「Using HTTP instead of HTTPS」と記載 通信内容の盗聴リスク
S3暗号化なし LogBucketにBucketEncryption設定なし ログデータの漏洩リスク
EC2にIAMロールなし App層EC2がSecrets Manager経由でRDSパスワードを取得する設計だが、IAMロールがないとアクセスできない アプリケーションが動作しない

特筆すべきは、ツールがテンプレート内のコメント(# Using HTTP instead of HTTPS)まで読み取って判断している点です。

2.設定欠如から推測された問題

リソースや設定が「存在しない」ことから推測された問題です。IaCテンプレートの外で対応済みの可能性があります。

ツールの指摘 問題でない可能性
CloudTrail未設定 アカウントレベルで既に有効化済み(Organizations証跡など)
GuardDuty未設定 アカウント作成時に自動有効化される設定の組織も多い
デフォルトEBS暗号化なし アカウント設定でデフォルト暗号化が有効な可能性

3.IaCの範囲外

組織プロセスやアカウントレベルの設定など、CloudFormationテンプレートでは判断できない項目です。

ベストプラクティス 判断できない理由
ルートユーザーとプロパティを保護する ツール自身が「IaCデプロイの範囲外であり、このテンプレートだけでは判断できない」と記載
脅威モデルを使用してリスクを特定する 組織プロセスのためIaCで判断不可
セキュリティトレーニングを行う 組織プロセスのためIaCで判断不可
コードレビューを実施する 組織プロセスのためIaCで判断不可

CloudFormation分析で分かったこと

優れている点

1. 明示的な設定不備の検出精度が高い

  • StorageEncrypted: false、CidrIp: 0.0.0.0/0など、テンプレートに書かれている問題は確実に検出
  • コメントまで読み取る精度

2. 修正箇所の特定が具体的

  • どのリソースのどのプロパティを変更すべきか明示
  • YAMLスニペット付きの修正提案

注意点

1. IaCで判断できない項目も指摘される

  • 組織プロセスやアカウントレベル設定は判断不可
  • ツール自身が「判断できない」と認めている項目もある

2. アカウントレベルの設定は考慮されない

  • CloudTrail、GuardDuty、デフォルト暗号化などはアカウントレベルで有効化済みの可能性がある
  • テンプレートに記載がないだけで「未適用」と判定される

分析パターン2:アーキテクチャ図分析

分析対象

AWS上でWordPressをホスティングするリファレンスアーキテクチャの画像(sample-architecture.png)を、信頼性柱で分析しました。

※分析を開始する前に、AI分析に効果的なアーキテクチャ図の要素を確認してください:

  • AWSアーキテクチャ図標準に従った明確なサービスアイコン
  • サービス間の可視的な接続
  • サービスとコンポーネントの読みやすいテキストラベル
  • 適切な画像解像度(少なくとも800x600ピクセル)
  • PNGまたはJPEG形式

分析結果サマリー

項目 数 割合
評価されたベストプラクティス 65 100%
適用済み (Applied) 14 22%
未適用 (Not Applied) 46 71%
該当なし (Not Relevant) 5 8%

適用済み項目(14件)の詳細分析

CloudFormation分析(5件)と比較して、アーキテクチャ図分析では14件が適用済みと評価されました。図から読み取れるアーキテクチャレベルの設計判断が評価されています。

ベストプラクティス 評価理由
アーキテクチャを通じて固定サービスクォータと制約に対応する マルチAZデプロイ、Auto Scaling、分散コンポーネント(ALB、ElastiCache、リードレプリカ付きAurora、複数NAT Gateway)を使用。固定ストレージ制限のないEFSを採用し、AZごとのリソース制約内で動作するよう負荷を分散
ワークロードのパブリックエンドポイントに高可用性ネットワーク接続を使用する Route 53(DNS管理)、CloudFront(コンテンツ配信)、2AZのパブリックサブネットに分散したALB、Internet Gatewayを実装。ALBとAuto Scalingにより正常なターゲットにトラフィック分散
IPサブネット割り当てが拡張と可用性を考慮していることを確認する パブリックサブネット(NAT Gateway、Bastion、ALB)、プライベートサブネット(WordPress)、データ層サブネット(ElastiCache、Aurora、EFS)で明確に分離し、2AZに分散配置
接続されているすべてのプライベートアドレス空間で重複しないプライベートIPアドレス範囲を強制する 他VPC・オンプレミス・外部ネットワークへの接続がない単一VPC構成のため、IPアドレス範囲の重複が発生し得ない
ワークロードをどのようにセグメント化するかを選択する プレゼンテーション層(CloudFront、S3)、アプリケーション層(WordPress + Auto Scaling)、キャッシュ層(ElastiCache)、データベース層(Aurora + リードレプリカ)、共有ストレージ(EFS)の5層に分離
可能な限りシステムをステートレスにする ElastiCacheでセッション状態管理、Auroraで永続データ保存、EFSで共有ファイル管理。
応答を自動化する(リアルタイム処理とアラーム) 両AZにAuto Scalingグループを設定。需要メトリクスに基づいてEC2インスタンスを自動スケールし、手動介入なしでキャパシティ管理
リソースの取得またはスケーリング時に自動化を使用する Auto Scalingによる自動プロビジョニングに加え、自動スケーリング機能を持つマネージドサービス(S3、CloudFront、Aurora、ElastiCache、EFS)を活用
ワークロードを複数のロケーションにデプロイする 2AZにWordPress、ElastiCache(マスター/レプリカ)、Aurora(マスター/リードレプリカ)、NAT Gatewayを分散配置し、障害分離と高可用性を実現
正常なリソースにフェイルオーバーする ALBが正常なWordPressインスタンスに自動ルーティング。Auroraはマスター/リードレプリカ構成でDBフェイルオーバー。各AZにNAT GatewayとEFSマウントターゲットを配置し、Auto Scalingが異常インスタンスを自動置換
すべてのレイヤーで修復を自動化する Auto Scalingがヘルスチェックに基づき障害インスタンスを自動置換。ALBが異常ターゲットへのルーティングを停止。Auroraが自動フェイルオーバー。ElastiCacheのマスター/レプリカ構成で自動リカバリ
リカバリ中はコントロールプレーンではなくデータプレーンに依存する NAT Gateway、EFSマウントターゲット、DBレプリカを2AZに事前プロビジョニング。ALBのヘルスチェック・ルーティング、Auroraのフェイルオーバー、Route 53のDNSルーティングはすべてデータプレーンで動作する
静的安定性を使用してバイモーダル動作を防止する 通常運用時から両AZにNAT Gateway、EFSマウントターゲット、DBレプリカを事前配置。障害時に新規リソース作成が不要なため、通常時と障害時で動作が変わらない(バイモーダル動作を回避)
可用性目標とアップタイムSLAを満たすように製品を設計する マルチAZ、ALB、Auto Scaling、Aurora、ElastiCache、EFS、CloudFront、Route 53による多層冗長化で高可用性を実現

検出された問題の分類

46件の指摘を、筆者が独自に3つのカテゴリに分類しました。
それぞれいくつかの例を挙げます。

1.図に描かれていないことによる指摘

アーキテクチャ図分析の最大の特徴は、図に描かれていないものは「未実装」と判定される点です。

ツールの指摘 実際には問題でない可能性
CloudWatch未設定 図に描いていないだけで、実際には設定済みの可能性が高い
X-Ray未設定 同上
CloudTrail未設定 同上
SNS通知未設定 同上

これらは「図に描かれていない」だけであり、実装されていないとは限りません。

2.設計判断として妥当な指摘

一方で、図から読み取れる設計判断に対する妥当な指摘もあります。

ツールの指摘 検出内容
DR戦略なし 単一リージョン構成のみ。リージョン障害時の復旧不可

3.運用プロセスのため評価対象外

ベストプラクティス 判断できない理由
監視スコープとメトリクスを定期的にレビューする 運用プロセスのため図から判断不可
プレイブックを使用して障害を調査する 運用プロセスのため図から判断不可
インシデント後の分析を実行する 運用プロセスのため図から判断不可
ゲームデーを定期的に実施する 運用プロセスのため図から判断不可
ダウンタイムとデータ損失の目標を定義する 運用プロセスのため図から判断不可

アーキテクチャ図分析で分かったこと

優れている点

1. アーキテクチャレベルの設計判断を評価できる

  • マルチAZ構成、高可用性設計、ネットワーク分離などを正確に検出
  • CloudFormation分析では見えにくい「全体像」を評価

2. 早期フィードバックが可能

  • 図を描くだけで分析できる手軽さ。コード実装前にアーキテクチャの方向性を確認できる
  • 設計段階で大きな問題を発見し、手戻りを防止

注意点

1. 図に描かれていないものは全て「未実装」と判定される

  • CloudWatch、X-Ray、SNSなど、図に描かないことが多いサービスは「未設定」と判定される
  • これはツールの限界であり、実際の実装状況とは異なる可能性が高い

2. 詳細設定の評価が不可能

  • セキュリティグループの具体的なルール(ポート番号、送信元IP)は不明
  • 暗号化設定の有無は推測のみ
  • 「SSH 0.0.0.0/0公開」のような具体的な問題は検出できない
アマゾン ウェブ サービス ジャパン (有志)

Discussion