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 | payer@example.com | ACTIVE | INVITED | 2023/04/13 18:53:07 |
Infra | 222222222222 | /root/Infra | ou-xxxx-aaaaa | infra@example.com | ACTIVE | CREATED | 2023/12/15 10:30:14 |
Workload | 333333333333 | /root/Workloads | ou-xxxx-bbbbb | workload@example.com | ACTIVE | CREATED | 2023/11/20 09:44:05 |
Audit | 444444444444 | /root/Security | ou-xxxx-ccccc | audit@example.com | ACTIVE | CREATED | 2023/10/13 17:40:18 |
LogArchive | 555555555555 | /root/Security | ou-xxxx-ccccc | logarchive@example.com | ACTIVE | CREATED | 2023/10/13 17:40:25 |
書いたスクリプト
以下に作成した Pythonスクリプトを記載します。 追加で pip install が必要なパッケージは boto3 のみです。
org-inventory-accounts.py
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","payer@example.com","ACTIVE","INVITED","2023/04/1318:53:07"
"Infra","222222222222","/root/Infra","ou-xxxx-aaaaa","infra@example.com","ACTIVE","CREATED","2023/12/1510:30:14"
"Workload","333333333333","/root/Workloads","ou-xxxx-bbbbb","workload@example.com","ACTIVE","CREATED","2023/11/2009:44:05"
"Audit","444444444444","/root/Security","ou-xxxx-ccccc","audit@example.com","ACTIVE","CREATED","2023/10/1317:40:18"
"LogArchive","555555555555","/root/Security","ou-xxxx-ccccc","logarchive@example.com","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