Skip to content

Instantly share code, notes, and snippets.

@GitToby
Last active November 14, 2025 21:14
Show Gist options
  • Select an option

  • Save GitToby/04a62382ddd22b464bcd5b54f102110e to your computer and use it in GitHub Desktop.

Select an option

Save GitToby/04a62382ddd22b464bcd5b54f102110e to your computer and use it in GitHub Desktop.
Using Boto, list all resources in an AWS account
# /// script
# https://peps.python.org/pep-0723/
# dependencies = [
# "boto3"
# ]
# ///
import boto3
from botocore.exceptions import ClientError
# uses the currently configured profile or "default"
session = boto3.Session()
regions = session.get_available_regions("ec2")
for region in regions:
print(region)
try:
client = session.client("resourcegroupstaggingapi", region_name=region)
for resource in client.get_resources().get("ResourceTagMappingList"):
print(" - ",resource["ResourceARN"])
for t in resource["Tags"]:
k,v = t.values()
print(f" > {k} = {v}")
except ClientError as e:
print(f"Could not connect to region with error: {e}")
print()
@silviudobrica
Copy link

silviudobrica commented Mar 26, 2025

It can be improved, by the way, to output to a csv file and pretty print it in the console:

from botocore.exceptions import ClientError
import csv
from prettytable import PrettyTable

# uses the currently configured profile or "default"
session = boto3.Session()
regions = session.get_available_regions("ec2")

# Prepare CSV file
csv_file = open('resources.csv', 'w', newline='')
csv_writer = csv.writer(csv_file)
csv_writer.writerow(['Region', 'ResourceARN', 'ResourceName', 'Tags'])

# Prepare PrettyTable
table = PrettyTable()
table.field_names = ['Region', 'ResourceARN', 'ResourceName', 'Tags']

for region in regions:
    print(region)
    try:
        client = session.client("resourcegroupstaggingapi", region_name=region)
        for resource in client.get_resources().get("ResourceTagMappingList"):
            resource_arn = resource["ResourceARN"]
            resource_name = resource_arn.split('/')[-1]
            tags = ', '.join([f"{t['Key']}={t['Value']}" for t in resource["Tags"]])
            
            # Write to CSV
            csv_writer.writerow([region, resource_arn, resource_name, tags])
            
            # Add to PrettyTable
            table.add_row([region, resource_arn, resource_name, tags])
    except ClientError as e:
        print(f"Could not connect to region with error: {e}")
    # print()

# Close CSV file
csv_file.close()

# Print PrettyTable
print(table)```

@silviudobrica
Copy link

silviudobrica commented Mar 26, 2025

Some more improvement, to have some extra IAM files and tables, if you'd like:

# /// script
# https://peps.python.org/pep-0723/
# dependencies = [
#   "boto3"
#   "prettytable"
# ]
# ///

import boto3
from botocore.exceptions import ClientError
import csv
from prettytable import PrettyTable

# uses the currently configured profile or "default"
session = boto3.Session()
regions = session.get_available_regions("ec2")

# Prepare CSV files
resources_csv_file = open('resources.csv', 'w', newline='')
resources_csv_writer = csv.writer(resources_csv_file)
resources_csv_writer.writerow(['Region', 'ResourceARN', 'ResourceName', 'Tags'])

iam_csv_file = open('iam.csv', 'w', newline='')
iam_csv_writer = csv.writer(iam_csv_file)
iam_csv_writer.writerow(['ResourceType', 'ResourceName', 'Details'])

iam_users_csv_file = open('iam_users.csv', 'w', newline='')
iam_users_csv_writer = csv.writer(iam_users_csv_file)
iam_users_csv_writer.writerow(['UserName', 'AccessKeyID', 'ActiveKeyAge', 'PasswordLastUsed', 'MFADevices'])

# Prepare PrettyTables
resources_table = PrettyTable()
resources_table.field_names = ['Region', 'ResourceARN', 'ResourceName', 'Tags']

iam_table = PrettyTable()
iam_table.field_names = ['ResourceType', 'ResourceName', 'Details']

iam_users_table = PrettyTable()
iam_users_table.field_names = ['UserName', 'AccessKeyID', 'ActiveKeyAge', 'PasswordLastUsed', 'MFADevices']

def write_to_resources_csv_and_table(region, resource_arn, resource_name, tags):
    resources_csv_writer.writerow([region, resource_arn, resource_name, tags])
    resources_table.add_row([region, resource_arn, resource_name, tags])

def write_to_iam_csv_and_table(resource_type, resource_name, details):
    iam_csv_writer.writerow([resource_type, resource_name, details])
    iam_table.add_row([resource_type, resource_name, details])

def write_to_iam_users_csv_and_table(user_name, access_key_id, active_key_age, password_last_used, mfa_devices):
    iam_users_csv_writer.writerow([user_name, access_key_id, active_key_age, password_last_used, mfa_devices])
    iam_users_table.add_row([user_name, access_key_id, active_key_age, password_last_used, mfa_devices])

# Fetch general AWS resources
for region in regions:
    print(region)
    try:
        client = session.client("resourcegroupstaggingapi", region_name=region)
        for resource in client.get_resources().get("ResourceTagMappingList"):
            resource_arn = resource["ResourceARN"]
            resource_name = resource_arn.split('/')[-1]
            tags = ', '.join([f"{t['Key']}={t['Value']}" for t in resource["Tags"]])
            
            # Write to CSV and PrettyTable
            write_to_resources_csv_and_table(region, resource_arn, resource_name, tags)
    except ClientError as e:
        print(f"Could not connect to region with error: {e}")

# Fetch IAM resources
iam_client = session.client('iam')
try:
    # Fetch IAM Users
    paginator = iam_client.get_paginator('list_users')
    for response in paginator.paginate():
        users = response['Users']
        for user in users:
            user_name = user['UserName']
            access_keys = iam_client.list_access_keys(UserName=user_name)['AccessKeyMetadata']
            password_last_used = user.get('PasswordLastUsed', 'N/A')
            mfa_devices = iam_client.list_mfa_devices(UserName=user_name)['MFADevices']
            mfa_details = ', '.join([f"SerialNumber={device['SerialNumber']}" for device in mfa_devices]) if mfa_devices else 'N/A'
            access_key_details = ', '.join([f"AccessKeyID={key['AccessKeyId']}, ActiveKeyAge={key['CreateDate']}" for key in access_keys]) if access_keys else 'N/A'
            write_to_iam_csv_and_table('IAM User', user_name, f"AccessKeys=[{access_key_details}], PasswordLastUsed={password_last_used}, MFADevices=[{mfa_details}]")
            if access_keys:
                for key in access_keys:
                    access_key_id = key['AccessKeyId']
                    active_key_age = key['CreateDate']
                    write_to_iam_users_csv_and_table(user_name, access_key_id, active_key_age, password_last_used, mfa_details)
            else:
                write_to_iam_users_csv_and_table(user_name, 'N/A', 'N/A', password_last_used, mfa_details)
except ClientError as e:
    print(f"Could not fetch IAM users with error: {e}")

try:
    # Fetch IAM Groups
    groups = iam_client.list_groups()['Groups']
    for group in groups:
        group_name = group['GroupName']
        details = f"GroupName={group_name}"
        write_to_iam_csv_and_table('IAM Group', group_name, details)
except ClientError as e:
    print(f"Could not fetch IAM groups with error: {e}")

try:
    # Fetch IAM Roles
    roles = iam_client.list_roles()['Roles']
    for role in roles:
        role_name = role['RoleName']
        details = f"RoleName={role_name}"
        write_to_iam_csv_and_table('IAM Role', role_name, details)
except ClientError as e:
    print(f"Could not fetch IAM roles with error: {e}")

try:
    # Fetch IAM Policies
    policies = iam_client.list_policies(Scope='Local')['Policies']
    for policy in policies:
        policy_name = policy['PolicyName']
        details = f"PolicyName={policy_name}"
        write_to_iam_csv_and_table('IAM Policy', policy_name, details)
except ClientError as e:
    print(f"Could not fetch IAM policies with error: {e}")

# Close CSV files
resources_csv_file.close()
iam_csv_file.close()
iam_users_csv_file.close()

# Print PrettyTables
print(resources_table)
print(iam_table)
print(iam_users_table)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment