diff --git a/README.md b/README.md index 99b15e6..57a0231 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,7 @@ Scripts to collect AWS resource inventory in all regions. ## Requirements - bash -- awscli -- gnu parallel -- miller -- python 3.13+ +- python 3.13+ with boto3 and openpyxl ## Usage -Run run-inventory-scripts.sh which will invoke a collection of scripts. TSV is returned for visibility. -Individual script can be ran to produce inventory of specific service. CSV is returned for programatic use. +Run run-inventory-scripts.sh which will invoke a collection of scripts. Output will be written to aws-inventory.xlsx \ No newline at end of file diff --git a/aws-apigw.py b/aws-apigw.py index a9d3cad..d016d7a 100755 --- a/aws-apigw.py +++ b/aws-apigw.py @@ -7,16 +7,22 @@ License: This program is released under the MIT License # Imports import boto3 - +from openpyxl import load_workbook # Main function def main() -> None: + # Open spreadsheet and add a sheet + wb = load_workbook('aws-inventory.xlsx') + ws = wb.create_sheet("ApiGateway") + client = boto3.client('apigateway') response = client.get_rest_apis() - print("RestAPIName,Scope") + ws.append(["RestAPIName","Scope"]) for i in response['items']: - print(f'{i["name"]}, {i["endpointConfiguration"]["types"][0]}') + ws.append([i["name"], i["endpointConfiguration"]["types"][0]]) + + wb.save('aws-inventory.xlsx') # Call main function if __name__ == '__main__': diff --git a/aws-cloudfront.py b/aws-cloudfront.py index e1ec59c..c875da1 100755 --- a/aws-cloudfront.py +++ b/aws-cloudfront.py @@ -7,16 +7,22 @@ License: This program is released under the MIT License # Imports import boto3 - +from openpyxl import load_workbook # Main function def main() -> None: + # Open spreadsheet and add a sheet + wb = load_workbook('aws-inventory.xlsx') + ws = wb.create_sheet("Cloudfront") + client = boto3.client('cloudfront') response = client.list_distributions() - print("Distribution, Alias, OriginId") + ws.append(["Distribution", "Alias", "OriginId"]) for i in response['DistributionList']['Items']: - print(f'{i["Id"]}, {i["Aliases"]["Items"][0]}, {i["Origins"]["Items"][0]["Id"]}') + ws.append([i["Id"],i["Aliases"]["Items"][0], i["Origins"]["Items"][0]["Id"]]) + + wb.save('aws-inventory.xlsx') # Call main function if __name__ == '__main__': diff --git a/aws-ddb-inventory.sh b/aws-ddb-inventory.sh deleted file mode 100755 index 1a3ebd5..0000000 --- a/aws-ddb-inventory.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -function listDdbTable() { - aws dynamodb describe-table --table-name $1 | jq -cr '.Table | [.TableName, .TableStatus, .TableSizeBytes, .ItemCount] | @csv' -} - -export -f listDdbTable - -echo "TableName, TableStatus, TableSizeBytes, ItemCount" -aws dynamodb list-tables --query TableNames --output text | tr '\t' '\n' | while read i; do - sem -j6 listDdbTable $i -done - -sem --wait diff --git a/aws-ddb.py b/aws-ddb.py new file mode 100755 index 0000000..e6c2d34 --- /dev/null +++ b/aws-ddb.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +r""" +Documentation + +License: This program is released under the MIT License +""" + +# Imports +import boto3 +import concurrent.futures +from openpyxl import load_workbook +from openpyxl.worksheet.worksheet import Worksheet + +def getRegions(all_regions=False): + ec2 = boto3.client('ec2') + response = ec2.describe_regions(AllRegions=all_regions) + return [region['RegionName'] for region in response['Regions']] + +def getResources(region_name: str) -> list[list[str | int]]: + return_data = [] + client = boto3.client('dynamodb', region_name=region_name) + paginator = client.get_paginator('list_tables') + for page in paginator.paginate(): + table_names = page.get('TableNames', []) + for t in table_names: + resp2 = client.describe_table(TableName=t) + i = resp2['Table'] + return_data.append([i['TableName'], i['TableStatus'], i['TableSizeBytes'], i['ItemCount'], region_name]) + return return_data + +# Main function +def main() -> None: + # Open spreadsheet and add a sheet + wb = load_workbook('aws-inventory.xlsx') + ws = wb.create_sheet("DynamoDB") + + final_data = [] + ws.append(["TableName", "TableStatus", "TableSizeBytes", "ItemCount", "Region"]) + with concurrent.futures.ProcessPoolExecutor(max_workers=6) as executor: + futures = [executor.submit(getResources, region_name=r) for r in getRegions()] + for future in concurrent.futures.as_completed(futures): + region_data = future.result() + final_data.extend(region_data) + + clean_data = [row for row in final_data if row] + for row in clean_data: + ws.append(row) + + wb.save('aws-inventory.xlsx') + +# Call main function +if __name__ == '__main__': + main() diff --git a/aws-ec2-inventory.sh b/aws-ec2-inventory.sh deleted file mode 100755 index de88b6b..0000000 --- a/aws-ec2-inventory.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash - -function formatprint() { - cat - > /tmp/formatprint.tmp - echo "# $1 ($(cat /tmp/formatprint.tmp | wc -l))" - #cat /tmp/formatprint.tmp | sed -e 's/^/ /g' - cat /tmp/formatprint.tmp | column -t -s, | sed -e 's/^/ /g' - rm -f /tmp/formatprint.tmp -} - -function listEc2() { - aws --region=$1 ec2 describe-instances --query 'Reservations[*].Instances[*].[InstanceId, Tags[?Key==`Name`].Value[] | [0], PlatformDetails, InstanceType,PrivateIpAddress, Placement.AvailabilityZone]' --output json | jq -cr '.[][] | @csv' | tr -d '[\" ' -} - -export -f formatprint -export -f listEc2 - -# Generate inventory of ec2 in all regions - -echo "InstanceId,NameTag,OsPlatform,InstanceType,PrivateIp,AZ" -aws --region=us-east-1 ec2 describe-regions --query Regions[].RegionName --output text | sed -e 's/\t/\n/g' | while read r; do - sem -j6 listEc2 $r -done - -sem --wait diff --git a/aws-ec2.py b/aws-ec2.py new file mode 100755 index 0000000..a317cfe --- /dev/null +++ b/aws-ec2.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +r""" +Documentation + +License: This program is released under the MIT License +""" + +# Imports +import boto3 +import concurrent.futures +from openpyxl import load_workbook +from openpyxl.worksheet.worksheet import Worksheet + +def getRegions(all_regions=False): + ec2 = boto3.client('ec2') + response = ec2.describe_regions(AllRegions=all_regions) + return [region['RegionName'] for region in response['Regions']] + +def printResources(region_name: str) -> list[list[str | int]]: + return_data = [] + client = boto3.client('ec2', region_name=region_name) + response = client.describe_instances() + for r in response['Reservations']: + for i in r['Instances']: + name_tag = 'Unset' + for tag in i['Tags']: + if tag['Key'] == "Name": + name_tag = tag['Value'] + break + osPlatform = "Linux" + if i.get('Platform') == "Windows": + osPlatform = "Windows" + return_data.append([i['InstanceId'], name_tag, osPlatform, i['InstanceType'], i['PrivateIpAddress'], i['Placement']['AvailabilityZone']]) + return return_data + +# Main function +def main() -> None: + # Open spreadsheet and add a sheet + wb = load_workbook('aws-inventory.xlsx') + ws = wb.create_sheet("Ec2") + + final_data = [] + ws.append(["InstanceId","NameTag","Platform","InstanceType","PrivateIpAddress","AZ"]) + with concurrent.futures.ProcessPoolExecutor(max_workers=6) as executor: + futures = [executor.submit(printResources, region_name=r) for r in getRegions()] + for future in concurrent.futures.as_completed(futures): + region_data = future.result() + final_data.extend(region_data) + + clean_data = [row for row in final_data if row] + for row in clean_data: + ws.append(row) + + wb.save('aws-inventory.xlsx') + +# Call main function +if __name__ == '__main__': + main() diff --git a/aws-ecs-inventory.sh b/aws-ecs-inventory.sh deleted file mode 100755 index 921684c..0000000 --- a/aws-ecs-inventory.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -function listRes() { - aws --region $1 ecs list-clusters | jq -cr '.clusterArns[]' | parallel aws --region $1 ecs describe-clusters --clusters {} | jq -cr '.clusters[] | [.clusterName, .runningTasksCount, .capacityProviders[0]] | @csv' | tr -d \" -} - -export -f listRes - -# Generate inventory of ec2 in all regions - -echo "ClusterName, TasksCount, CapacityProvider" -aws --region=us-east-1 ec2 describe-regions --query Regions[].RegionName --output text | sed -e 's/\t/\n/g' | while read r; do - sem -j6 listRes $r -done - -sem --wait diff --git a/aws-ecs.py b/aws-ecs.py new file mode 100755 index 0000000..dbcb5db --- /dev/null +++ b/aws-ecs.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +r""" +Documentation + +License: This program is released under the MIT License +""" + +# Imports +import boto3 +import concurrent.futures +from openpyxl import load_workbook +from openpyxl.worksheet.worksheet import Worksheet + + +def getRegions(all_regions=False): + ec2 = boto3.client('ec2') + response = ec2.describe_regions(AllRegions=all_regions) + return [region['RegionName'] for region in response['Regions']] + +def printResources(region_name: str) -> list[list[str | int]]: + return_data = [] + client = boto3.client('ecs', region_name=region_name) + response = client.list_clusters() + for arn in response['clusterArns']: + resp2 = client.describe_cluster(clusters=arn) + for i in resp2['clusters']: + return_data.append([i['clusterName'], i['runningTasksCount'], i['capacityProviders'], region_name]) + return return_data + +# Main function +def main() -> None: + # Open spreadsheet and add a sheet + wb = load_workbook('aws-inventory.xlsx') + ws = wb.create_sheet("Ecs") + + final_data = [] + ws.append(["clusterName", "runningTasksCount", "capacityProviders", "Region"]) + with concurrent.futures.ProcessPoolExecutor(max_workers=6) as executor: + futures = [executor.submit(printResources, region_name=r) for r in getRegions()] + for future in concurrent.futures.as_completed(futures): + region_data = future.result() + final_data.extend(region_data) + + clean_data = [row for row in final_data if row] + for row in clean_data: + ws.append(row) + + wb.save('aws-inventory.xlsx') + +# Call main function +if __name__ == '__main__': + main() diff --git a/aws-efs-inventory.sh b/aws-efs-inventory.sh deleted file mode 100755 index 7dbd4d4..0000000 --- a/aws-efs-inventory.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -function listRes() { - aws --region $1 efs describe-file-systems | jq -cr '.FileSystems[] | [.FileSystemId, .Name, .PerformanceMode, (.SizeInBytes.Value/1024/1024)] | @csv' | tr -d \" -} - -export -f listRes - -# Generate inventory in all regions - -echo "FilesystemId, Name, PerformanceMode, SizeMb" -aws --region=us-east-1 ec2 describe-regions --query Regions[].RegionName --output text | sed -e 's/\t/\n/g' | while read r; do - sem -j6 listRes $r -done - -sem --wait diff --git a/aws-efs.py b/aws-efs.py new file mode 100755 index 0000000..9c87b06 --- /dev/null +++ b/aws-efs.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +r""" +Documentation + +License: This program is released under the MIT License +""" + +# Imports +import boto3 +import concurrent.futures +from openpyxl import load_workbook +from openpyxl.worksheet.worksheet import Worksheet + + +def getRegions(all_regions=False): + ec2 = boto3.client('ec2') + response = ec2.describe_regions(AllRegions=all_regions) + return [region['RegionName'] for region in response['Regions']] + +def printResources(region_name: str) -> list[list[str | int]]: + return_data = [] + client = boto3.client('efs', region_name=region_name) + response = client.describe_file_systems() + for i in response['FileSystems']: + return_data.append([i['FileSystemId'], i['Name'], i['PerformanceMode'], i['SizeInBytes']['Value']/1024/1024, i['AvailabilityZoneName']]) + return return_data + +# Main function +def main() -> None: + # Open spreadsheet and add a sheet + wb = load_workbook('aws-inventory.xlsx') + ws = wb.create_sheet("EFS") + + final_data = [] + ws.append(["FileSystemId", "Name", "PerformanceMode", "SizeMB", "AZ"]) + with concurrent.futures.ProcessPoolExecutor(max_workers=6) as executor: + futures = [executor.submit(printResources, region_name=r) for r in getRegions()] + for future in concurrent.futures.as_completed(futures): + region_data = future.result() + final_data.extend(region_data) + + clean_data = [row for row in final_data if row] + for row in clean_data: + ws.append(row) + + wb.save('aws-inventory.xlsx') + +# Call main function +if __name__ == '__main__': + main() diff --git a/aws-eks-inventory.sh b/aws-eks-inventory.sh deleted file mode 100755 index 165635c..0000000 --- a/aws-eks-inventory.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -function listRes() { - aws --region $1 eks list-clusters --query clusters[] --output text | sed -e 's/\t/\n/g' | while read i; do - aws --region $1 eks describe-cluster --name $i | jq -cr '.cluster | [.name, .version] | @csv' | tr -d \" - done -} - -export -f listRes - -# Generate inventory of ec2 in all regions - -echo "ClusterName,ClusterVersion" -aws --region=us-east-1 ec2 describe-regions --query Regions[].RegionName --output text | sed -e 's/\t/\n/g' | while read r; do - sem -j6 listRes $r -done - -sem --wait diff --git a/aws-eks.py b/aws-eks.py new file mode 100755 index 0000000..225b835 --- /dev/null +++ b/aws-eks.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 +r""" +Documentation + +License: This program is released under the MIT License +""" + +# Imports +import boto3 +import concurrent.futures +from openpyxl import load_workbook +from openpyxl.worksheet.worksheet import Worksheet + + +def getRegions(all_regions=False): + ec2 = boto3.client('ec2') + response = ec2.describe_regions(AllRegions=all_regions) + return [region['RegionName'] for region in response['Regions']] + +def printResources(region_name: str) -> list[list[str | int]]: + return_data = [] + client = boto3.client('eks', region_name=region_name) + response = client.list_clusters() + for c in response['clusters']: + i = client.describe_cluster(name=c) + return_data.append([i['name'], i['version'], region_name]) + return return_data + +# Main function +def main() -> None: + # Open spreadsheet and add a sheet + wb = load_workbook('aws-inventory.xlsx') + ws = wb.create_sheet("EKS") + + final_data = [] + ws.append(["name", "version", "Region"]) + with concurrent.futures.ProcessPoolExecutor(max_workers=6) as executor: + futures = [executor.submit(printResources, region_name=r) for r in getRegions()] + for future in concurrent.futures.as_completed(futures): + region_data = future.result() + final_data.extend(region_data) + + clean_data = [row for row in final_data if row] + for row in clean_data: + ws.append(row) + + wb.save('aws-inventory.xlsx') + +# Call main function +if __name__ == '__main__': + main() diff --git a/aws-elasticache.py b/aws-elasticache.py index a2e9b1c..e551162 100755 --- a/aws-elasticache.py +++ b/aws-elasticache.py @@ -8,24 +8,42 @@ License: This program is released under the MIT License # Imports import boto3 import concurrent.futures +from openpyxl import load_workbook +from openpyxl.worksheet.worksheet import Worksheet + def getRegions(all_regions=False): ec2 = boto3.client('ec2') response = ec2.describe_regions(AllRegions=all_regions) return [region['RegionName'] for region in response['Regions']] -def printResources(region_name: str): +def printResources(region_name: str) -> list[list[str | int]]: + return_data = [] client = boto3.client('elasticache', region_name=region_name) response = client.describe_cache_clusters() for i in response['CacheClusters']: - print(f"{i['CacheClusterId']}, {i['CacheNodeType']}, {i['Engine']}, {i['EngineVersion']}, {i['NumCacheNodes']}, {i['PreferredAvailabilityZone']}") + return_data.append([i['CacheClusterId'], i['CacheNodeType'], i['Engine'], i['EngineVersion'], i['NumCacheNodes'], i['PreferredAvailabilityZone']]) + return return_data # Main function def main() -> None: - print("CacheClusterId, CacheNodeType, Engine, EngineVersion, NumCacheNodes, AZ") + # Open spreadsheet and add a sheet + wb = load_workbook('aws-inventory.xlsx') + ws = wb.create_sheet("Elasticache") + + final_data = [] + ws.append(["CacheClusterId", "CacheNodeType", "Engine", "EngineVersion", "NumCacheNodes", "AZ"]) with concurrent.futures.ProcessPoolExecutor(max_workers=6) as executor: futures = [executor.submit(printResources, region_name=r) for r in getRegions()] - results = [future.result() for future in concurrent.futures.wait(futures).done] + for future in concurrent.futures.as_completed(futures): + region_data = future.result() + final_data.extend(region_data) + + clean_data = [row for row in final_data if row] + for row in clean_data: + ws.append(row) + + wb.save('aws-inventory.xlsx') # Call main function if __name__ == '__main__': diff --git a/aws-elbv2-inventory.sh b/aws-elbv2-inventory.sh deleted file mode 100755 index 8b15c06..0000000 --- a/aws-elbv2-inventory.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -function listRes() { - aws --region $1 elbv2 describe-load-balancers | jq -cr '.LoadBalancers[] | [.LoadBalancerName, .Scheme, .Type, .AvailabilityZones[0].ZoneName] | @csv' | tr -d \" -} - -export -f listRes - -# Generate inventory in all regions - -echo "LbName,Scheme,Type,AZ1" -aws --region=us-east-1 ec2 describe-regions --query Regions[].RegionName --output text | sed -e 's/\t/\n/g' | while read r; do - sem -j6 listRes $r -done - -sem --wait diff --git a/aws-emr.py b/aws-emr.py index 85beae3..81620f0 100755 --- a/aws-emr.py +++ b/aws-emr.py @@ -8,24 +8,41 @@ License: This program is released under the MIT License # Imports import boto3 import concurrent.futures +from openpyxl import load_workbook +from openpyxl.worksheet.worksheet import Worksheet def getRegions(all_regions=False): ec2 = boto3.client('ec2') response = ec2.describe_regions(AllRegions=all_regions) return [region['RegionName'] for region in response['Regions']] -def printResources(region_name: str): +def printResources(region_name: str) -> list[list[str | int]]: + return_data = [] client = boto3.client('emr', region_name=region_name) response = client.list_clusters() for i in response['Clusters']: - print(f"{i['Name']}, {i['Status']}, {i['NormalizedInstanceHours']}, {region_name}") + return_data.append([i['Name'], i['Status'], i['NormalizedInstanceHours'], region_name]) + return return_data # Main function def main() -> None: - print("Name, Status, NormalizedInstanceHours, Region") + # Open spreadsheet and add a sheet + wb = load_workbook('aws-inventory.xlsx') + ws = wb.create_sheet("EMR") + + final_data = [] + ws.append(["Name", "Status", "NormalizedInstanceHours", "Region"]) with concurrent.futures.ProcessPoolExecutor(max_workers=6) as executor: futures = [executor.submit(printResources, region_name=r) for r in getRegions()] - results = [future.result() for future in concurrent.futures.wait(futures).done] + for future in concurrent.futures.as_completed(futures): + region_data = future.result() + final_data.extend(region_data) + + clean_data = [row for row in final_data if row] + for row in clean_data: + ws.append(row) + + wb.save('aws-inventory.xlsx') # Call main function if __name__ == '__main__': diff --git a/aws-lambda.py b/aws-lambda.py index c7e8542..3d6496b 100755 --- a/aws-lambda.py +++ b/aws-lambda.py @@ -8,25 +8,43 @@ License: This program is released under the MIT License # Imports import boto3 import concurrent.futures - +from openpyxl import load_workbook +from openpyxl.worksheet.worksheet import Worksheet def getRegions(all_regions=False): ec2 = boto3.client('ec2') response = ec2.describe_regions(AllRegions=all_regions) return [region['RegionName'] for region in response['Regions']] -def printResources(region_name: str): +def printResources(region_name: str) -> list[list[str | int]]: + return_data = [] client = boto3.client('lambda', region_name=region_name) - response = client.list_functions() - for i in response['Functions']: - print(f"{i['FunctionName']}, {i['Runtime']}, {i['Architectures'][0]}, {region_name}") + paginator = client.get_paginator('list_functions') + for page in paginator.paginate(): + functions = page.get('Functions', []) + for i in functions: + return_data.append([i['FunctionName'], i['Runtime'], i['Architectures'][0], region_name]) + return return_data # Main function def main() -> None: - print("FunctionName,Runtime,Architectures,region") + # Open spreadsheet and add a sheet + wb = load_workbook('aws-inventory.xlsx') + ws = wb.create_sheet("Lambda") + + final_data = [] + ws.append(["FunctionName","Runtime","Architectures","region"]) with concurrent.futures.ProcessPoolExecutor(max_workers=6) as executor: futures = [executor.submit(printResources, region_name=r) for r in getRegions()] - results = [future.result() for future in concurrent.futures.wait(futures).done] + for future in concurrent.futures.as_completed(futures): + region_data = future.result() + final_data.extend(region_data) + + clean_data = [row for row in final_data if row] + for row in clean_data: + ws.append(row) + + wb.save('aws-inventory.xlsx') # Call main function if __name__ == '__main__': diff --git a/aws-lb.py b/aws-lb.py new file mode 100755 index 0000000..ccf6329 --- /dev/null +++ b/aws-lb.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +r""" +Documentation + +License: This program is released under the MIT License +""" + +# Imports +import boto3 +import concurrent.futures +from openpyxl import load_workbook +from openpyxl.worksheet.worksheet import Worksheet + + +def getRegions(all_regions=False): + ec2 = boto3.client('ec2') + response = ec2.describe_regions(AllRegions=all_regions) + return [region['RegionName'] for region in response['Regions']] + +def printResources(region_name: str) -> list[list[str | int]]: + return_data = [] + client = boto3.client('elbv2', region_name=region_name) + response = client.describe_load_balancers() + for i in response['LoadBalancers']: + return_data.append([i['LoadBalancerName'], i['Scheme'], i['Type'], region_name]) + return return_data + +# Main function +def main() -> None: + # Open spreadsheet and add a sheet + wb = load_workbook('aws-inventory.xlsx') + ws = wb.create_sheet("LoadBalancers") + + final_data = [] + ws.append(["LoadBalancerName", "Scheme", "Type", "Region"]) + with concurrent.futures.ProcessPoolExecutor(max_workers=6) as executor: + futures = [executor.submit(printResources, region_name=r) for r in getRegions()] + for future in concurrent.futures.as_completed(futures): + region_data = future.result() + final_data.extend(region_data) + + clean_data = [row for row in final_data if row] + for row in clean_data: + ws.append(row) + + wb.save('aws-inventory.xlsx') + +# Call main function +if __name__ == '__main__': + main() diff --git a/aws-logs.py b/aws-logs.py index 079ab79..96c06f7 100755 --- a/aws-logs.py +++ b/aws-logs.py @@ -8,25 +8,40 @@ License: This program is released under the MIT License # Imports import boto3 import concurrent.futures - +from openpyxl import load_workbook +from openpyxl.worksheet.worksheet import Worksheet def getRegions(all_regions=False): ec2 = boto3.client('ec2') response = ec2.describe_regions(AllRegions=all_regions) return [region['RegionName'] for region in response['Regions']] -def printResources(region_name: str): +def printResources(region_name: str) -> list[list[str | int]]: + return_data = [] client = boto3.client('logs', region_name=region_name) response = client.describe_log_groups() for logGroup in response['logGroups']: - print(f"{logGroup['logGroupName']}, {logGroup.get('retentionInDays')}, {logGroup['storedBytes']}, {region_name}") + return_data.append([logGroup['logGroupName'], logGroup.get('retentionInDays'), logGroup['storedBytes'], region_name]) + return return_data # Main function def main() -> None: - print("logGroupName,retentionInDays,storedBytes,region") + # Open spreadsheet and add a sheet + wb = load_workbook('aws-inventory.xlsx') + ws = wb.create_sheet("CloudwatchLogs") + + final_data = [] + ws.append(["logGroupName","retentionInDays","storedBytes","region"]) with concurrent.futures.ProcessPoolExecutor(max_workers=6) as executor: futures = [executor.submit(printResources, region_name=r) for r in getRegions()] - results = [future.result() for future in concurrent.futures.wait(futures).done] + for future in concurrent.futures.as_completed(futures): + region_data = future.result() + final_data.extend(region_data) + + clean_data = [row for row in final_data if row] + for row in clean_data: + ws.append(row) + wb.save('aws-inventory.xlsx') # Call main function if __name__ == '__main__': diff --git a/aws-opensearch.py b/aws-opensearch.py index 66460df..c4ab979 100755 --- a/aws-opensearch.py +++ b/aws-opensearch.py @@ -8,24 +8,41 @@ License: This program is released under the MIT License # Imports import boto3 import concurrent.futures +from openpyxl import load_workbook +from openpyxl.worksheet.worksheet import Worksheet def getRegions(all_regions=False): ec2 = boto3.client('ec2') response = ec2.describe_regions(AllRegions=all_regions) return [region['RegionName'] for region in response['Regions']] -def printResources(region_name: str): +def printResources(region_name: str) -> list[list[str | int]]: + return_data = [] client = boto3.client('opensearch', region_name=region_name) response = client.list_domain_names() for i in response['DomainNames']: - print(f"{i['DomainName']}, {i['EngineType']}, {region_name}") + return_data.append([i['DomainName'], i['EngineType'], region_name]) + return return_data # Main function def main() -> None: - print("DomainName,EngineType,region") + # Open spreadsheet and add a sheet + wb = load_workbook('aws-inventory.xlsx') + ws = wb.create_sheet("OpenSearch") + + final_data = [] + ws.append(["DomainName","EngineType","region"]) with concurrent.futures.ProcessPoolExecutor(max_workers=6) as executor: futures = [executor.submit(printResources, region_name=r) for r in getRegions()] - results = [future.result() for future in concurrent.futures.wait(futures).done] + for future in concurrent.futures.as_completed(futures): + region_data = future.result() + final_data.extend(region_data) + + clean_data = [row for row in final_data if row] + for row in clean_data: + ws.append(row) + + wb.save('aws-inventory.xlsx') # Call main function if __name__ == '__main__': diff --git a/aws-r53.py b/aws-r53.py new file mode 100755 index 0000000..4149e94 --- /dev/null +++ b/aws-r53.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 +r""" +Documentation + +License: This program is released under the MIT License +""" + +# Imports +import boto3 +from openpyxl import load_workbook + +# Main function +def main() -> None: + # Open spreadsheet and add a sheet + wb = load_workbook('aws-inventory.xlsx') + ws = wb.create_sheet("route53") + + client = boto3.client('route53') + # Get the list of all buckets + response = client.list_hosted_zones() + + # Print the names of the buckets + ws.append(['Name', 'PrivateZone', 'ResourceRecordSetCount']) + for i in response['HostedZones']: + ws.append([i["Name"], i['Config']['PrivateZone'], i["ResourceRecordSetCount"]]) + + wb.save('aws-inventory.xlsx') + + +# Call main function +if __name__ == '__main__': + main() diff --git a/aws-rds.py b/aws-rds.py index 15f993c..a9ba612 100755 --- a/aws-rds.py +++ b/aws-rds.py @@ -8,24 +8,42 @@ License: This program is released under the MIT License # Imports import boto3 import concurrent.futures +from openpyxl import load_workbook +from openpyxl.worksheet.worksheet import Worksheet + def getRegions(all_regions=False): ec2 = boto3.client('ec2') response = ec2.describe_regions(AllRegions=all_regions) return [region['RegionName'] for region in response['Regions']] -def printResources(region_name: str): +def printResources(region_name: str) -> list[list[str | int]]: + return_data = [] client = boto3.client('rds', region_name=region_name) response = client.describe_db_instances() for i in response['DBInstances']: - print(f"{i['DBInstanceIdentifier']}, {i['DBInstanceClass']}, {i['Engine']}, {i['EngineVersion']}, {i['MultiAZ']}, {region_name}") + return_data.append([i['DBInstanceIdentifier'], i['DBInstanceClass'], i['Engine'], i['EngineVersion'], i['MultiAZ'], region_name]) + return return_data # Main function def main() -> None: - print("DBInstanceIdentifier, DBInstanceClass, Engine, EngineVersion, MultiAZ, Region") + # Open spreadsheet and add a sheet + wb = load_workbook('aws-inventory.xlsx') + ws = wb.create_sheet("RDS") + + final_data = [] + ws.append(["DBInstanceIdentifier", "DBInstanceClass", "Engine", "EngineVersion", "MultiAZ", "Region"]) with concurrent.futures.ProcessPoolExecutor(max_workers=6) as executor: futures = [executor.submit(printResources, region_name=r) for r in getRegions()] - results = [future.result() for future in concurrent.futures.wait(futures).done] + for future in concurrent.futures.as_completed(futures): + region_data = future.result() + final_data.extend(region_data) + + clean_data = [row for row in final_data if row] + for row in clean_data: + ws.append(row) + + wb.save('aws-inventory.xlsx') # Call main function if __name__ == '__main__': diff --git a/aws-route53-inventory.sh b/aws-route53-inventory.sh deleted file mode 100755 index 330974a..0000000 --- a/aws-route53-inventory.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -echo "ZoneName, IsPrivate, RecordCount" -aws route53 list-hosted-zones | jq -cr '.HostedZones[] | [.Name, .Config.PrivateZone, .ResourceRecordSetCount] | @csv' | tr -d \" diff --git a/aws-s3.py b/aws-s3.py index 5d88cc5..b913209 100755 --- a/aws-s3.py +++ b/aws-s3.py @@ -7,19 +7,26 @@ License: This program is released under the MIT License # Imports import boto3 - +from openpyxl import load_workbook # Main function def main() -> None: + # Open spreadsheet and add a sheet + wb = load_workbook('aws-inventory.xlsx') + ws = wb.create_sheet("S3") + s3_client = boto3.client('s3') # Get the list of all buckets response = s3_client.list_buckets() # Print the names of the buckets - print('Buckets') + ws.append(['Buckets']) for bucket in response['Buckets']: - print(f'{bucket["Name"]}') + ws.append([bucket["Name"]]) + + wb.save('aws-inventory.xlsx') + # Call main function if __name__ == '__main__': diff --git a/aws-subnets.py b/aws-subnets.py index 568be0a..6dcb336 100755 --- a/aws-subnets.py +++ b/aws-subnets.py @@ -8,26 +8,43 @@ License: This program is released under the MIT License # Imports import boto3 import concurrent.futures +from openpyxl import load_workbook +from openpyxl.worksheet.worksheet import Worksheet def getRegions(all_regions=False): ec2 = boto3.client('ec2') response = ec2.describe_regions(AllRegions=all_regions) return [region['RegionName'] for region in response['Regions']] -def printResources(region_name: str): +def printResources(region_name: str) -> list[list[str | int]]: + return_data = [] client = boto3.client('ec2', region_name=region_name) response = client.describe_subnets() for i in response['Subnets']: default_vpc_check = client.describe_vpcs(VpcIds=[i['VpcId']]) for v in default_vpc_check['Vpcs']: - print(f"{i['SubnetId']}, {i['VpcId']}, {i['CidrBlock']}, {i['AvailabilityZone']}, {v['IsDefault']}") + return_data.append([i['SubnetId'], i['VpcId'], i['CidrBlock'], i['AvailabilityZone'], v['IsDefault']]) + return return_data # Main function def main() -> None: - print("SubnetId, VpcId, CidrBlock, AvailabilityZone, InDefaultVpc") + # Open spreadsheet and add a sheet + wb = load_workbook('aws-inventory.xlsx') + ws = wb.create_sheet("Subnets") + + final_data = [] + ws.append(["SubnetId", "VpcId", "CidrBlock", "AvailabilityZone", "InDefaultVpc"]) with concurrent.futures.ProcessPoolExecutor(max_workers=6) as executor: futures = [executor.submit(printResources, region_name=r) for r in getRegions()] - results = [future.result() for future in concurrent.futures.wait(futures).done] + for future in concurrent.futures.as_completed(futures): + region_data = future.result() + final_data.extend(region_data) + + clean_data = [row for row in final_data if row] + for row in clean_data: + ws.append(row) + + wb.save('aws-inventory.xlsx') # Call main function if __name__ == '__main__': diff --git a/init_workbook.py b/init_workbook.py new file mode 100755 index 0000000..27f1cae --- /dev/null +++ b/init_workbook.py @@ -0,0 +1,24 @@ +#!/usr/bin/python3 +r""" +Documentation + +License: This program is released under the MIT License +""" + +# Imports +from openpyxl import Workbook +from datetime import datetime + +# Main function +def main() -> None: + wb = Workbook() + ws = wb.active + ws['A1'] = "AWS Inventory" + ws['A2'] = "Created on" + ws['B2'] = datetime.now() + wb.save('aws-inventory.xlsx') + + +# Call main function +if __name__ == '__main__': + main() diff --git a/run-inventory-scripts.sh b/run-inventory-scripts.sh index 72c1777..dd45a9a 100755 --- a/run-inventory-scripts.sh +++ b/run-inventory-scripts.sh @@ -1,6 +1,9 @@ #!/bin/bash -for i in aws*.{py,sh}; do +rm -f aws-inventory.xlsx +./init_workbook.py + +for i in aws*.py; do echo "# $i" ./"$i" | mlr --c2t cat | column -t wait $!