はじめに
AWS環境を運用していると、「この設定はベストプラクティスに沿っているだろうか?」「セキュリティリスクは無いだろうか?」といった疑問が常に付きまといます。Well-Architected Frameworkに基づいた環境構築を心がけていても、実際にすべての環境を手動でチェックするのは大変な作業です。
そこで役立つのが、AWSが公式で公開しているService Screenerです。このツールを使うと、AWS環境を自動的にスキャンし、ベストプラクティスに基づいた改善提案を受け取ることができます。
本記事では、Service Screenerの基本的な使い方を解説します。
Service Screenerとは
Service Screenerは、AWS環境の設定をAWSおよびコミュニティのベストプラクティスに基づいて評価するオープンソースツールです。AWS Well-Architected Toolの補完的な役割を目指しています。
主な特徴
- 複数フレームワーク対応: Well-Architected Framework、CIS、NIST、その他基準に対応
- 自動スキャン: AWS CloudShellから簡単に実行可能で、API経由で環境を自動評価
- 詳細なレポート: HTMLレポートで視覚的に分かりやすく、改善すべき点を明確に提示
- 低コスト: 基本的に無料枠内で動作し、仮に超過しても1回の実行あたり1ドル未満
Well-Architected Toolとの違い
AWS Well-Architected Toolは、アーキテクチャの設計原則に関する質問に回答していく形式のツールです。一方、Service Screenerは実際の設定をスキャンして自動的に問題点を発見します。両者を併用することで、より迅速な環境評価が可能になります。
| 特徴 | Service Screener | Well-Architected Tool |
|---|---|---|
| 評価方法 | 自動スキャン | 手動の質問回答 |
| 実施時間 | 数分 | 数時間〜数日 |
| 詳細度 | 具体的な設定項目 | アーキテクチャ全般 |
| 使用場面 | 定期的な設定チェック | 設計レビュー |
前提条件
Service Screenerを実行する前に、以下の要件を満たしていることを確認してください:
免責事項の確認
Service Screenerを使用する前に、必ずGitHubリポジトリの免責事項をお読みください。
必要な環境
- AWSアカウント: スキャン対象のAWSアカウントへのアクセス
- AWS CloudShellまたはローカル環境:
- AWS CloudShell(推奨)- AWSマネジメントコンソールから利用可能
- ローカル環境の場合: Pythonがインストールされていること
必要な権限
Service Screenerを実行するには、各AWSサービスに対する読み取り権限が必要です。最も簡単な方法は、以下のAWS管理ポリシーと権限を許可することです。
ReadOnlyAccess– 各サービスの読み取り専用アクセスcloudformation:CreateStackcloudformation:DeleteStack
インストール方法
Service Screenerは、AWS CloudShell上で実行するのが最も簡単です。CloudShellはAWSマネジメントコンソールから無料で利用できるブラウザベースのシェルです。
AWS CloudShellでのセットアップ
以下のコマンドを順番に実行してください:
# 1. /tmpディレクトリに移動 cd /tmp # 2. Python仮想環境を作成して有効化 python3 -m venv . source bin/activate # 3. pipを最新版にアップグレード python3 -m pip install --upgrade pip # 4. GitHubから最新版のService Screener v2をクローン rm -rf service-screener-v2 git clone https://github.com/aws-samples/service-screener-v2.git cd service-screener-v2 # 5. 必要な依存パッケージをインストール pip install -r requirements.txt # 6. botocore Lambda runtimeを解凍(Lambda関数での実行に必要) python3 unzip_botocore_lambda_runtime.py # 7. `screener`というエイリアスを設定して、簡単に実行できるようにする alias screener="python3 $(pwd)/main.py"
セットアップの実行例
実際にCloudShellで実行すると、以下のような出力が表示されます:
~ $ cd /tmp
tmp $ python3 -m venv .
tmp $ source bin/activate
(tmp) tmp $ python3 -m pip install --upgrade pip
Requirement already satisfied: pip in ./lib/python3.9/site-packages (21.3.1)
Collecting pip
Using cached pip-25.2-py3-none-any.whl (1.8 MB)
Installing collected packages: pip
Attempting uninstall: pip
Found existing installation: pip 21.3.1
Uninstalling pip-21.3.1:
Successfully uninstalled pip-21.3.1
Successfully installed pip-25.2
(tmp) tmp $ rm -rf service-screener-v2
(tmp) tmp $ git clone https://github.com/aws-samples/service-screener-v2.git
Cloning into 'service-screener-v2'...
remote: Enumerating objects: 4758, done.
remote: Counting objects: 100% (1044/1044), done.
remote: Compressing objects: 100% (194/194), done.
remote: Total 4758 (delta 917), reused 858 (delta 850), pack-reused 3714 (from 2)
Receiving objects: 100% (4758/4758), 3.92 MiB | 18.39 MiB/s, done.
Resolving deltas: 100% (2750/2750), done.
(tmp) tmp $ cd service-screener-v2
(tmp) service-screener-v2 $ pip install -r requirements.txt
Obtaining file:///tmp/service-screener-v2 (from -r requirements.txt (line 9))
Installing build dependencies ... done
Checking if build backend supports build_editable ... done
Getting requirements to build editable ... done
Preparing editable metadata (pyproject.toml) ... done
Collecting boto3>=1.35 (from -r requirements.txt (line 1))
Using cached boto3-1.40.55-py3-none-any.whl.metadata (6.6 kB)
Collecting packaging>=23.1 (from -r requirements.txt (line 2))
Using cached packaging-25.0-py3-none-any.whl.metadata (3.3 kB)
Collecting XlsxWriter>=3.1.0 (from -r requirements.txt (line 3))
Using cached xlsxwriter-3.2.9-py3-none-any.whl.metadata (2.7 kB)
Collecting netaddr>=0.9.0 (from -r requirements.txt (line 4))
Using cached netaddr-1.3.0-py3-none-any.whl.metadata (5.0 kB)
Collecting requests>=2.31.0 (from -r requirements.txt (line 5))
Using cached requests-2.32.5-py3-none-any.whl.metadata (4.9 kB)
Collecting openpyxl>=3.1.2 (from -r requirements.txt (line 6))
Using cached openpyxl-3.1.5-py2.py3-none-any.whl.metadata (2.5 kB)
Collecting multiprocess>=0.70 (from -r requirements.txt (line 7))
Using cached multiprocess-0.70.18-py39-none-any.whl.metadata (7.5 kB)
Collecting simple-term-menu>=1.6.4 (from -r requirements.txt (line 8))
Using cached simple_term_menu-1.6.6-py3-none-any.whl.metadata (29 kB)
Collecting botocore=1.40.55 (from boto3>=1.35->-r requirements.txt (line 1))
Using cached botocore-1.40.55-py3-none-any.whl.metadata (5.7 kB)
Collecting jmespath=0.7.1 (from boto3>=1.35->-r requirements.txt (line 1))
Using cached jmespath-1.0.1-py3-none-any.whl.metadata (7.6 kB)
Collecting s3transfer=0.14.0 (from boto3>=1.35->-r requirements.txt (line 1))
Using cached s3transfer-0.14.0-py3-none-any.whl.metadata (1.7 kB)
Collecting python-dateutil=2.1 (from botocore=1.40.55->boto3>=1.35->-r requirements.txt (line 1))
Using cached python_dateutil-2.9.0.post0-py2.py3-none-any.whl.metadata (8.4 kB)
Collecting urllib3=1.25.4 (from botocore=1.40.55->boto3>=1.35->-r requirements.txt (line 1))
Using cached urllib3-1.26.20-py2.py3-none-any.whl.metadata (50 kB)
Collecting six>=1.5 (from python-dateutil=2.1->botocore=1.40.55->boto3>=1.35->-r requirements.txt (line 1))
Using cached six-1.17.0-py2.py3-none-any.whl.metadata (1.7 kB)
Collecting charset_normalizer=2 (from requests>=2.31.0->-r requirements.txt (line 5))
Using cached charset_normalizer-3.4.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (37 kB)
Collecting idna=2.5 (from requests>=2.31.0->-r requirements.txt (line 5))
Using cached idna-3.11-py3-none-any.whl.metadata (8.4 kB)
Collecting certifi>=2017.4.17 (from requests>=2.31.0->-r requirements.txt (line 5))
Using cached certifi-2025.10.5-py3-none-any.whl.metadata (2.5 kB)
Collecting et-xmlfile (from openpyxl>=3.1.2->-r requirements.txt (line 6))
Using cached et_xmlfile-2.0.0-py3-none-any.whl.metadata (2.7 kB)
Collecting dill>=0.4.0 (from multiprocess>=0.70->-r requirements.txt (line 7))
Using cached dill-0.4.0-py3-none-any.whl.metadata (10 kB)
Using cached boto3-1.40.55-py3-none-any.whl (139 kB)
Using cached botocore-1.40.55-py3-none-any.whl (14.1 MB)
Using cached jmespath-1.0.1-py3-none-any.whl (20 kB)
Using cached python_dateutil-2.9.0.post0-py2.py3-none-any.whl (229 kB)
Using cached s3transfer-0.14.0-py3-none-any.whl (85 kB)
Using cached urllib3-1.26.20-py2.py3-none-any.whl (144 kB)
Using cached packaging-25.0-py3-none-any.whl (66 kB)
Using cached xlsxwriter-3.2.9-py3-none-any.whl (175 kB)
Using cached netaddr-1.3.0-py3-none-any.whl (2.3 MB)
Using cached requests-2.32.5-py3-none-any.whl (64 kB)
Using cached charset_normalizer-3.4.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (153 kB)
Using cached idna-3.11-py3-none-any.whl (71 kB)
Using cached openpyxl-3.1.5-py2.py3-none-any.whl (250 kB)
Using cached multiprocess-0.70.18-py39-none-any.whl (133 kB)
Using cached simple_term_menu-1.6.6-py3-none-any.whl (27 kB)
Using cached certifi-2025.10.5-py3-none-any.whl (163 kB)
Using cached dill-0.4.0-py3-none-any.whl (119 kB)
Using cached six-1.17.0-py2.py3-none-any.whl (11 kB)
Using cached et_xmlfile-2.0.0-py3-none-any.whl (18 kB)
Building wheels for collected packages: ServiceScreenerV2
Building editable for ServiceScreenerV2 (pyproject.toml) ... done
Created wheel for ServiceScreenerV2: filename=servicescreenerv2-2.0-0.editable-py3-none-any.whl size=7849 sha256=e60512a8adcc6d1548e3a100587b67e52952ae6ee72df198cbf771a933b4faee
Stored in directory: /tmp/pip-ephem-wheel-cache-u4vu6h_4/wheels/48/b9/16/c34a56b58d7bc2beab3cdb804fa9bf2bc6b66b6796c3db032d
Successfully built ServiceScreenerV2
Installing collected packages: ServiceScreenerV2, XlsxWriter, urllib3, six, simple-term-menu, packaging, netaddr, jmespath, idna, et-xmlfile, dill, charset_normalizer, certifi, requests, python-dateutil, openpyxl, multiprocess, botocore, s3transfer, boto3
Successfully installed ServiceScreenerV2-2.0 XlsxWriter-3.2.9 boto3-1.40.55 botocore-1.40.55 certifi-2025.10.5 charset_normalizer-3.4.4 dill-0.4.0 et-xmlfile-2.0.0 idna-3.11 jmespath-1.0.1 multiprocess-0.70.18 netaddr-1.3.0 openpyxl-3.1.5 packaging-25.0 python-dateutil-2.9.0.post0 requests-2.32.5 s3transfer-0.14.0 simple-term-menu-1.6.6 six-1.17.0 urllib3-1.26.20
(tmp) service-screener-v2 $ python3 unzip_botocore_lambda_runtime.py
(tmp) service-screener-v2 $ alias screener="python3 $(pwd)/main.py"
(tmp) service-screener-v2 $
これで準備完了です。
CloudeShelで実行する場合の注意
CloudShellでは、/tmpディレクトリはセッション終了時に削除されます。そのため、CloudShellのセッションを終了した後に再度ツールを実行する場合は、上記のセットアップコマンドを最初から実行し直す必要があります。
一方、ホームディレクトリ(~)の内容は永続化されますが、容量制限が1GBと小さいため注意が必要です。
基本的な使い方
単一リージョンでの実行
最も基本的な使い方は、特定のリージョンをスキャンする方法です:
screener --regions ap-northeast-1 --beta 1
--regions: スキャン対象のリージョンを指定--beta 1: ベータ機能を有効化(並列処理による高速化など)
複数リージョンでの実行
複数のリージョンを同時にスキャンすることも可能です:
# 複数リージョンを指定 screener --regions ap-northeast-1,us-east-1,eu-west-1 --beta 1 # すべてのリージョンをスキャン screener --regions ALL --beta 1
特定のサービスのみスキャン
すべてのサービスではなく、特定のサービスだけをチェックしたい場合:
# S3とIAMのみスキャン screener --regions ap-northeast-1 --services s3,iam --beta 1 # EC2とRDSのみスキャン screener --regions ap-northeast-1 --services ec2,rds --beta 1
実行例とその出力
実際にService Screener v2を実行すると、以下のような流れで処理が進みます。
(tmp) service-screener-v2 $ screener --regions ap-northeast-1 --beta 1 -- Acquiring identify info... ================================================= Processing the following account id: AWS_ACCOUNT_ID ================================================= [info] Empty CF stacked created successfully, name:ssv2-ef5c544ea643 PREPARING -- IAM::us-east-1 PREPARING -- CLOUDFRONT::us-east-1 PREPARING -- LAMBDA::ap-northeast-1 PREPARING -- EC2::ap-northeast-1 ... (Lambda) - test-lambda ... (CloudFront::Distribution) - XXXXXXXX ... (IAM::User) -... (IAM::User) - admin COMPLETED -- CLOUDFRONT::us-east-1 (1.136s) PREPARING -- CLOUDTRAIL::ap-northeast-1 ... (Lambda) - abc-lambda ... (Cloudtrail) - example-trail ... (Lambda) - bcd-lambda ... (Compute Optimizer Recommendations) ... (Cost Explorer Recommendations) -- Unable to capture Public Access Block settings: AccessDenied -- Unable to capture S3 MFA settings: AccessDenied -- Unable to capture S3 Logging settings: AccessDenied ... (CloudTrail:Common) COMPLETED -- CLOUDTRAIL::ap-northeast-1 (1.414s) PREPARING -- ELASTICACHE::ap-northeast-1 ... (Lambda) - test-lambda COMPLETED -- ELASTICACHE::ap-northeast-1 (0.142s) PREPARING -- EKS::ap-northeast-1 ... (IAM::User) - xxx COMPLETED -- EKS::ap-northeast-1 (0.234s) PREPARING -- DYNAMODB::ap-northeast-1 ... (EBS::Snapshots) ... (Dynamodb::Generic) 一部省略 [info] Empty CF stacked deleted successfully, name:ssv2-ef5c544ea643 Total Resources scanned: 106.00 | No. Rules executed: 420.00 Time consumed (seconds): 78.63 ElasticachepageBuilder class not found, using default pageBuilder LambdapageBuilder class not found, using default pageBuilder DynamodbpageBuilder class not found, using default pageBuilder CloudfrontpageBuilder class not found, using default pageBuilder RdspageBuilder class not found, using default pageBuilder ApigatewaypageBuilder class not found, using default pageBuilder CloudtrailpageBuilder class not found, using default pageBuilder EfspageBuilder class not found, using default pageBuilder KmspageBuilder class not found, using default pageBuilder IampageBuilder class not found, using default pageBuilder EkspageBuilder class not found, using default pageBuilder CloudwatchpageBuilder class not found, using default pageBuilder OpensearchpageBuilder class not found, using default pageBuilder RedshiftpageBuilder class not found, using default pageBuilder S3pageBuilder class not found, using default pageBuilder Ec2pageBuilder class not found, using default pageBuilder SqspageBuilder class not found, using default pageBuilder Generating Framework - MSR Generating Framework - FTR Generating Framework - SSB Generating Framework - WAFS *** [WATool] Attempting to deploy WA Tools in this region: ap-northeast-1 Generating Framework - CIS Generating Framework - NIST Generating Framework - RMiT Generating Framework - SPIP ###########: UsageStat Generating Framework - RBI ... Running CP - TA, it can takes up to 60 seconds Pages generated, download output.zip to view CloudShell user, you may use this path: =====> /tmp/service-screener-v2/output.zip 実行が完了すると、
output.zipというファイルが生成されます。結果レポートの確認方法
レポートのダウンロード
CloudShellから結果レポートをダウンロードするには、以下の手順で行います:
- CloudShellのメニューから「アクション」→「ファイルのダウンロード」を選択
- ファイルパスに
/tmp/service-screener-v2/output.zipを入力- ダウンロードボタンをクリック
または、コマンドラインで以下のメッセージが表示されるので、そのパスをコピーしてダウンロードすることもできます:
Pages generated, download output.zip to view CloudShell user, you may use this path: =====> /tmp/service-screener-v2/output.zipレポートの構造
ダウンロードした
output.zipを解凍すると、以下のようなフォルダ構造になっています。aws/ ├── AWS_ACCOUNT_ID # アカウントIDごとの結果フォルダ │ ├── index.html # メインファイル。こちらを開きます │ ├── ec2.html # EC2に関するスキャン結果のページ │ └── ... # その他サービスごとのレポート等 └── res/ # CSS、JavaScript等の静的ファイル
レポートの見方
index.htmlをブラウザで開くと、ダッシュボードが表示されます。左側のナビゲーションバーにサマリーや各種コンプライアンス・フレームワーク、AWSサービス一覧が表示されますので、その中から確認したい項目を選択します。以下の画面はWell-Architected Frameworkのセキュリティの柱に関する画面です。
緑色が満たしている項目、赤色が対応が必要な項目、青色はService Screenerが対応していない項目です。
高度な使い方
Well-Architected Toolとの統合
Service Screenerの結果をAWS Well-Architected Toolに統合することも可能です。
screener --regions ap-northeast-1 --beta 1 --others '{"WA": {"region": "ap-northeast-1", "reportName": "SS_Report", "newMileStone": 1}}'このオプションを使うと、スキャン結果がWell-Architected Toolに「SS_Report」という名前で、ワークロードが新しいマイルストーンと共に作成されます。ただし、全ての設問には対応していませんので注意してください。
タグによるフィルタリング
特定のタグが付いたリソースのみをスキャンすることも可能です。この例は、タグの名前が「Environment」、値が「Production」の場合の値です。
screener --regions ap-northeast-1 --tags Environment=Production --beta 1特定のチェック項目を除外する
誤検知や意図的に無視したいチェック項目がある場合、抑制ファイルを使用できます。
{ "metadata": { "version": "1.0", "description": "Your suppression description" }, "suppressions": [ { "service": "s3", "rule": "BucketReplication" }, { "service": "s3", "rule": "BucketVersioning", "resource_id": ["Bucket::my-bucket-name"] } ] }この設定ファイルを
suppress.jsonとして保存し、以下のように実行します。screener --regions ap-northeast-1 --suppress-file ./suppress.json --beta 1まとめ
Service Screenerは、AWS環境のベストプラクティスチェックを簡単かつ包括的に実行できる強力なツールです。
定期的にService Screenerを実行することで、AWS環境の健全性を保ち、セキュリティリスクを低減し、コストを最適化することができます。Well-Architected Toolと併用することで、より包括的な環境評価が可能になるでしょう。
ぜひ、あなたのAWS環境でもService Screenerを活用してみてください。
参考リンク



