組織下のAWSアカウントの名前や所属OUを一覧にしてCSV出力したい【Python, Boto3】
AWSアカウントの情報一覧をCSVとして保存したいです。 ここでいう情報はAWSアカウントの名前やID、所属する組織単位(OU)などです。
AWSアカウントの名前、IDだけであれば organizations list-accounts のみで済みますが、 私としては所属するOUの情報もほしいです。 その場合は少しスクリプトを作り込まないと いけません。
今回は Python(Boto3)スクリプトを書いて、 これを実現してみます。
出したいCSV
organizations list-accounts で取得できるAWSアカウント情報に加えて、 所属するOUも付与したいです。 イメージとしては以下のような表になります。
Name | Id | OU Path | OU ID | Status | JoinedMethod | JoinedTimestamp | |
---|---|---|---|---|---|---|---|
Payer-XXX | 111111111111 | /root | r-xxxx | [email protected] | ACTIVE | INVITED | 2023/04/13 18:53:07 |
Infra | 222222222222 | /root/Infra | ou-xxxx-aaaaa | [email protected] | ACTIVE | CREATED | 2023/12/15 10:30:14 |
Workload | 333333333333 | /root/Workloads | ou-xxxx-bbbbb | [email protected] | ACTIVE | CREATED | 2023/11/20 09:44:05 |
Audit | 444444444444 | /root/Security | ou-xxxx-ccccc | [email protected] | ACTIVE | CREATED | 2023/10/13 17:40:18 |
LogArchive | 555555555555 | /root/Security | ou-xxxx-ccccc | [email protected] | ACTIVE | CREATED | 2023/10/13 17:40:25 |
書いたスクリプト
以下に作成した Pythonスクリプトを記載します。 追加で pip install が必要なパッケージは boto3 のみです。
import boto3 import logging from datetime import datetime from operator import itemgetter import csv logging.basicConfig(level=logging.INFO) org_client = boto3.client('organizations') OU_DICT = {} def create_ou_dict (parent_id, parent_name, prefix): ou_path = f'{prefix}/{parent_name}' OU_DICT[parent_id] = ou_path response = org_client.list_organizational_units_for_parent( ParentId=parent_id ) for ou in response.get('OrganizationalUnits'): create_ou_dict(ou.get('Id'), ou.get('Name'), ou_path) def org_root(): response = org_client.list_roots() return response.get('Roots')[0].get('Id') def accounts_for_parent(parent_id): response = org_client.list_accounts_for_parent( ParentId=parent_id ) return response.get('Accounts') def main(): # 実行開始時刻取得と出力ファイル名の確定 datetime_now = datetime.now().strftime('%Y-%m-%d_%H-%M-%S') file_path = f'accounts_{datetime_now}.csv' logging.info(f'[start] timestamp: {datetime_now}') # OUパスの辞書作成 logging.info('# getting OU dictionary...') create_ou_dict(org_root(), 'root', '') logging.info(f'-> number of OUs: {len(OU_DICT)}') # AWSアカウント情報のリスト作成 logging.info('# creating AWS accounts list...') accounts = [] for ou_id, ou_path in OU_DICT.items(): logging.info(f'## searching accounts in {ou_path}...') for account in accounts_for_parent(ou_id): accounts.append([ account.get('Name'), account.get('Id'), ou_path, ou_id, account.get('Email'), account.get('Status'), account.get('JoinedMethod'), account.get('JoinedTimestamp').strftime('%Y/%m/%d %H:%M:%S') ]) logging.info(f'-> number of accounts: {len(accounts)}') # CSV出力 logging.info(f'# generating csv ({file_path})') header = [ 'Name', 'Id', 'OU Path', 'OU ID', 'Email', 'Status', 'JoinedMethod', 'JoinedTimestamp' ] rows = [header] + sorted(accounts, key=itemgetter(0,2)) with open(file_path, 'w', newline='') as csvfile: writer = csv.writer(csvfile, quoting=csv.QUOTE_ALL) writer.writerows(rows) logging.info('[end]') main()
実行例
実行するにあたって、以下AWSアクションの権限が必要です。
Organizations:ListRoots
Organizations:ListOrganizationsUnitsForParent
Organizations:ListAccountsForParent
上記権限を持った認証情報を事前にセットして、 スクリプトを実行します。 以下実行サンプルです。
$ python3 ./org-inventory-accounts.py # INFO:botocore.credentials:Found credentials in environment variables. # INFO:root:[start] timestamp: 2024-03-26_08-44-15 # INFO:root:# getting OU dictionary... # INFO:root:-> number of OUs: 4 # INFO:root:# creating AWS accounts list... # INFO:root:## searching accounts in /root... # INFO:root:## searching accounts in /root/Security... # INFO:root:## searching accounts in /root/Workloads... # INFO:root:## searching accounts in /root/Infrastructure... # INFO:root:-> number of accounts: 5 # INFO:root:# generating csv (accounts_2024-03-26_08-44-15.csv) # INFO:root:[end]
出力されたCSVは以下のとおり。 「出したい出力」章にて記載した表と同じ構成です。
"Name","Id","OUPath","OUID","Email","Status","JoinedMethod","JoinedTimestamp" "Payer-XXX","111111111111","/root","r-xxxx","[email protected]","ACTIVE","INVITED","2023/04/1318:53:07" "Infra","222222222222","/root/Infra","ou-xxxx-aaaaa","[email protected]","ACTIVE","CREATED","2023/12/1510:30:14" "Workload","333333333333","/root/Workloads","ou-xxxx-bbbbb","[email protected]","ACTIVE","CREATED","2023/11/2009:44:05" "Audit","444444444444","/root/Security","ou-xxxx-ccccc","[email protected]","ACTIVE","CREATED","2023/10/1317:40:18" "LogArchive","555555555555","/root/Security","ou-xxxx-ccccc","[email protected]","ACTIVE","CREATED","2023/10/1317:40:25"
おわりに
AWSアカウントの棚卸しスクリプトを書いてみました。 このCSVを使って QuickSight で可視化したり、 アカウント名の lookup で活用したりできそうです。
以上、参考になれば幸いです。
参考
- list_roots - Boto3 1.34.69 documentation
- list_organizational_units_for_parent - Boto3 1.34.69 documentation
- list_accounts_for_parent - Boto3 1.34.69 documentation
- csv — CSV ファイルの読み書き — Python 3.12.2 ドキュメント
補足
実行環境
- OS: macOS Sonoma 14.3.1
- Python: 3.11.7
- boto3: 1.34.54