Service Screener v2 — Full AWS Organization Scan Guide

Infographic of Service Screener v2 showing a central AWS Management Account scanning multiple member accounts with a magnifying glass, highlighting security and reliability checks.

Run Service Screener across all accounts in your AWS Organization from a clean CloudShell session.

Prerequisites

  • You are logged in to the management account
  • Your IAM user/role has:
  • ReadOnlyAccess
  • AWSCloudShellFullAccess
  • organizations:ListAccounts
  • organizations:EnableAWSServiceAccess
  • sts:AssumeRole
  • iam:SetSecurityTokenServicePreferences (required if scanning non-default or ALL regions)
  • cloudformation:CreateStack / cloudformation:DeleteStack
  • cloudformation:CreateStackSet / cloudformation:CreateStackInstances

Step 1 — Launch CloudShell

  1. Log in to the AWS Management Console on your management account
  2. Click the CloudShell icon (top navigation bar) or go to: https://console.aws.amazon.com/cloudshell/
  3. Wait for the shell to initialize

Step 2 — Deploy the Cross-Account Role to All Member Accounts

Use CloudFormation StackSets to create a ServiceScreenerReadOnlyRole in every member account.

Get your root OU ID:

aws organizations list-roots --query 'Roots[0].Id' --output text

Enable StackSets trusted access (one-time):

aws organizations enable-aws-service-access \
--service-principal member.org.stacksets.cloudformation.amazonaws.com

Upload the template and create the StackSet:

Download service-screener-cross-account-role.yaml from https://github.com/monstack/service-screener-v2/blob/main/service-screener-cross-account-role.yaml

aws cloudformation create-stack-set \
--stack-set-name ServiceScreenerRole \
--template-body file://service-screener-cross-account-role.yaml \
--parameters \
ParameterKey=ManagementAccountId,ParameterValue=YOUR_MGMT_ACCOUNT_ID \
ParameterKey=RoleName,ParameterValue=ServiceScreenerReadOnlyRole \
ParameterKey=ExternalId,ParameterValue="" \
--permission-model SERVICE_MANAGED \
--auto-deployment Enabled=true,RetainStacksOnAccountRemoval=false \
--capabilities CAPABILITY_NAMED_IAM

Deploy to all member accounts:

aws cloudformation create-stack-instances \
--stack-set-name ServiceScreenerRole \
--deployment-targets OrganizationalUnitIds=YOUR_ROOT_OU_ID \
--regions ap-southeast-1

Replace YOUR_MGMT_ACCOUNT_ID and YOUR_ROOT_OU_ID with your actual values.

Wait for deployment to complete:

aws cloudformation list-stack-set-operations \
--stack-set-name ServiceScreenerRole \
--query 'Summaries[0].Status'

Wait until it shows SUCCEEDED.

Verify (optional):

aws sts assume-role \
--role-arn arn:aws:iam::MEMBER_ACCOUNT_ID:role/ServiceScreenerReadOnlyRole \
--role-session-name test \
--query 'Credentials.AccessKeyId'

Note: StackSets with SERVICE_MANAGED deploys to member accounts only, not the management account. This is fine — Service Screener scans the management account directly via IncludeThisAccount: true. New accounts added to the Organization will automatically get the role via auto-deployment.


Step 3 — Install Service Screener

cd /tmp
python3 -m venv .
source bin/activate
python3 -m pip install --upgrade pip
rm -rf service-screener-v2
git clone https://github.com/aws-samples/service-screener-v2.git
cd service-screener-v2
pip install -r requirements.txt
pip install simple-term-menu
python3 unzip_botocore_lambda_runtime.py
alias screener='python3 $(pwd)/main.py'

Step 4 — Generate the Cross-Accounts Config

Option A: Interactive (Recommended)

python3 organizationAccountsInit.py

When prompted:

  1. Use Space to select accounts, Enter to confirm
  2. Enter ServiceScreenerReadOnlyRole when asked for the role name
  3. Press Enter to skip External ID (leave blank)

Option B: Manual

cat > crossAccounts.json << 'EOF'
{
"general": {
"IncludeThisAccount": true,
"RoleName": "ServiceScreenerReadOnlyRole",
"ExternalId": ""
},
"accountLists": {
"111111111111": {},
"222222222222": {},
"333333333333": {}
}
}
EOF

Replace the account IDs with your actual member account IDs.

FieldDescription
IncludeThisAccounttrue to also scan the management account you are running from
RoleNameMust be ServiceScreenerReadOnlyRole (matching the deployed StackSet role)
ExternalIdOptional. Leave "" if not required
accountListsEach key is a member account ID. Use {} to inherit general settings

Step 5 — Run the Scan

Scan all services in all regions:

screener --regions ALL --crossAccounts 1

Scan all services in specific regions:

screener --regions ap-southeast-1,us-east-1 --crossAccounts 1

Scan specific services only:

screener --regions ALL --services s3,iam,ec2 --crossAccounts 1

Enable beta features (concurrent evaluator, API buttons):

screener --regions ALL --crossAccounts 1 --beta 1

With Well-Architected Tool integration:

screener --regions ALL --crossAccounts 1 --others '{"WA": {"region": "ap-southeast-1", "reportName": "OrgScan", "newMileStone": 1}}'

Step 6 — Download the Report

  1. The scan produces output.zip in the project directory
  2. In CloudShell, click Actions (top-right) → Download file
  3. Enter the path:
   /tmp/service-screener-v2/output.zip
  1. Unzip locally and open index.html in your browser
  2. Use the account dropdown in the report to switch between scanned accounts

The report also includes:

  • api-raw.json — raw findings per account
  • api-full.json — full structured results per account

Cleanup

To remove the cross-account role from all member accounts:

aws cloudformation delete-stack-instances \
--stack-set-name ServiceScreenerRole \
--deployment-targets OrganizationalUnitIds=YOUR_ROOT_OU_ID \
--regions ap-southeast-1 \
--no-retain-stacks
# Wait for deletion to complete, then:
aws cloudformation delete-stack-set \
--stack-set-name ServiceScreenerRole

Reset / Clear Previous Scan Results

If a scan failed or you want to start fresh:

rm -rf /tmp/service-screener-v2/__fork/*
rm -rf /tmp/service-screener-v2/adminlte/aws/[0-9]*
rm -f /tmp/service-screener-v2/output.zip

If you exited the venv, re-activate before scanning again:

cd /tmp
source bin/activate
cd service-screener-v2
alias screener='python3 $(pwd)/main.py'

Troubleshooting

IssueSolution
Unable to assume roleVerify the StackSet deployed successfully to that account
Role already exists (StackSet)Accounts created by Organizations may already have OrganizationAccountAccessRole. This won’t happen with ServiceScreenerReadOnlyRole
InvalidClientTokenIdThe STS token may not have propagated yet. The tool retries automatically for v2 tokens. Wait and retry
AccessDenied on ListAccountsYour management account IAM user/role needs organizations:ListAccounts permission
GlobalEndpointTokenVersion warningExpected when using --regions ALL. The tool temporarily switches to v2 tokens and resets after validation
CloudShell times out mid-scanLarge orgs may take a while. Consider scanning in batches by region or by groups of accounts
simple-term-menu not foundRun pip install simple-term-menu before running organizationAccountsInit.py

Stay in the Stack

รับสรุปเทคนิคและอัปเดตใหม่ๆ จาก monstack ส่งตรงถึง Email คุณ

MonStack

Stack knowledge and built with ❤️