Python提取AWS SSO账户信息存CSV报错:'Organizations'无对应属性
解决AWS SSO账户信息提取脚本的AttributeError问题
问题根源
- 客户端混用:
list_permission_sets_provisioned_to_account是AWS SSO Admin的API方法,原脚本错误使用了AWS Organizations客户端调用;即便切换到sso-admin客户端,也未区分两个服务的职责——Organizations负责获取账户列表,SSO Admin负责处理权限集与账户分配。 - 缺失必填参数:
list_permission_sets_provisioned_to_account必须传入InstanceArn参数,原脚本定义了该变量但未传入调用。 - API返回值处理错误:
list_permission_sets_provisioned_to_account返回的PermissionSets是权限集ARN数组,并非包含名称的对象,需额外调用describe_permission_set获取名称。 - CSV写入逻辑错误:原脚本用
csv.writer处理字典列表,会导致格式异常,需改用csv.DictWriter。 - 未处理分页:AWS列表类API默认分页返回,原脚本未处理分页会遗漏数据。
修正后的完整脚本
import boto3 import csv # 替换为你的AWS SSO实例ARN INSTANCE_ARN = 'arn:aws:sso:::instance/ssoins-xxxxxxxxxxxxxx' def get_all_accounts(): """从AWS Organizations获取所有账户(处理分页)""" org_client = boto3.client('organizations') accounts = [] next_token = None while True: if next_token: response = org_client.list_accounts(NextToken=next_token) else: response = org_client.list_accounts() accounts.extend(response['Accounts']) next_token = response.get('NextToken') if not next_token: break return accounts def get_permission_sets_for_account(sso_admin_client, account_id): """获取指定账户的所有权限集ARN(处理分页)""" permission_sets = [] next_token = None while True: if next_token: response = sso_admin_client.list_permission_sets_provisioned_to_account( InstanceArn=INSTANCE_ARN, AccountId=account_id, NextToken=next_token ) else: response = sso_admin_client.list_permission_sets_provisioned_to_account( InstanceArn=INSTANCE_ARN, AccountId=account_id ) permission_sets.extend(response['PermissionSets']) next_token = response.get('NextToken') if not next_token: break return permission_sets def get_permission_set_name(sso_admin_client, permission_set_arn): """通过权限集ARN获取名称""" response = sso_admin_client.describe_permission_set( InstanceArn=INSTANCE_ARN, PermissionSetArn=permission_set_arn ) return response['PermissionSet']['Name'] def get_account_assignments(sso_admin_client, permission_set_arn): """获取权限集下的所有账户分配(处理分页)""" assignments = [] next_token = None while True: if next_token: response = sso_admin_client.list_account_assignments( InstanceArn=INSTANCE_ARN, PermissionSetArn=permission_set_arn, NextToken=next_token ) else: response = sso_admin_client.list_account_assignments( InstanceArn=INSTANCE_ARN, PermissionSetArn=permission_set_arn ) assignments.extend(response['AccountAssignments']) next_token = response.get('NextToken') if not next_token: break return assignments def main(): # 初始化客户端 sso_admin_client = boto3.client('sso-admin') accounts = get_all_accounts() account_info = [] # 遍历所有账户 for account in accounts: account_id = account['Id'] print(f"处理账户: {account_id}") # 获取该账户的所有权限集ARN permission_set_arns = get_permission_sets_for_account(sso_admin_client, account_id) # 遍历每个权限集 for ps_arn in permission_set_arns: ps_name = get_permission_set_name(sso_admin_client, ps_arn) # 获取该权限集的账户分配 assignments = get_account_assignments(sso_admin_client, ps_arn) # 提取用户名并整理数据 for assignment in assignments: # 注意:账户分配可能包含UserName或GroupName,这里只处理UserName if 'UserName' in assignment: account_info.append({ "AccountId": account_id, "Username": assignment['UserName'], "PermissionSetName": ps_name }) # 写入CSV文件 with open("sso_accounts.csv", "w", newline='', encoding='utf-8') as csvfile: fieldnames = ["AccountId", "Username", "PermissionSetName"] writer = csv.DictWriter(csvfile, fieldnames=fieldnames) writer.writeheader() writer.writerows(account_info) print("Done! CSV文件已生成。") if __name__ == "__main__": main()
关键修改说明
- 分离客户端职责:用
organizations客户端获取账户列表,sso-admin客户端处理SSO权限相关操作,避免API调用混淆。 - 传入必填参数:所有SSO Admin的API调用都传入了
InstanceArn参数,符合AWS API要求。 - 正确处理权限集数据:通过
describe_permission_set从权限集ARN中提取名称,修正原脚本直接读取Name的错误。 - 修复CSV写入:使用
csv.DictWriter适配字典格式的数据,确保表头与内容对应。 - 添加分页逻辑:所有列表类API都处理了
NextToken,保证获取全量数据,不会遗漏账户、权限集或分配记录。
内容的提问来源于stack exchange,提问作者shubh
相关产品推荐
相关产品推荐

