- Newest
- Most votes
- Most comments
To generate a report of all enabled and not enabled Service Control Policies (SCPs) across all accounts in an AWS Organization, you indeed need to use the AWS Organizations SDK. Here's a Python script using Boto3 that iterates through your organization's accounts and organizational units (OUs) to gather information about the SCPs applied.
import boto3
import csv
org_client = boto3.client('organizations')
def list_organizational_units(parent_id):
ous = []
paginator = org_client.get_paginator('list_organizational_units_for_parent')
for page in paginator.paginate(ParentId=parent_id):
ous.extend(page['OrganizationalUnits'])
return ous
def list_accounts_for_ou(ou_id):
accounts = []
paginator = org_client.get_paginator('list_accounts_for_parent')
for page in paginator.paginate(ParentId=ou_id):
accounts.extend(page['Accounts'])
return accounts
def list_scps_for_target(target_id):
scps = []
paginator = org_client.get_paginator('list_policies_for_target')
for page in paginator.paginate(TargetId=target_id, Filter='SERVICE_CONTROL_POLICY'):
scps.extend(page['Policies'])
return scps
def get_scps_status(scp_ids):
scp_status = {}
for scp_id in scp_ids:
response = org_client.describe_policy(PolicyId=scp_id)
scp_status[scp_id] = response['Policy']['PolicySummary']['AwsManaged']
return scp_status
def main():
root_id = org_client.list_roots()['Roots'][0]['Id']
all_ous = list_organizational_units(root_id)
all_accounts = []
for ou in all_ous:
accounts = list_accounts_for_ou(ou['Id'])
all_accounts.extend(accounts)
scp_report = []
for account in all_accounts:
scps = list_scps_for_target(account['Id'])
scp_ids = [scp['Id'] for scp in scps]
scp_status = get_scps_status(scp_ids)
for scp in scps:
scp_report.append({
'AccountId': account['Id'],
'AccountName': account['Name'],
'SCPName': scp['Name'],
'SCPId': scp['Id'],
'Enabled': scp['Status'] == 'ENABLED',
'AwsManaged': scp_status[scp['Id']]
})
# Write the report to a CSV file
with open('scp_report.csv', 'w', newline='') as csvfile:
fieldnames = ['AccountId', 'AccountName', 'SCPName', 'SCPId', 'Enabled', 'AwsManaged']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for row in scp_report:
writer.writerow(row)
if __name__ == '__main__':
main()
I think that'll work, but with any substantial number of accounts, repeatedly calling
get_scps_status()for the same SCP policy IDs over and over again may waste a lot of time. It'd be more efficient to enumerate all the SCPs once at the start, store the status by policy ID in a dictionary, and use the dictionary for hyper-quick lookups when receiving the SCP policy IDs attached to individual accounts in the all_accounts for loop.

please accept the answer if it was helpful