Jan-06-2020, 09:21 PM
This function lists all the instances in an AWS account. It does that for each region.
For some reason I end up with the total number of instances reported by the function is doubled when the region loop is there. It is duplicating instance IDs when it shouldn't do that. Each region should have it's own unique set of servers.
For example in one account there is 95 servers but when the region loop is there, it reports that there are 190 servers. And the resulting list shows duplicate instance IDs.
For some reason I end up with the total number of instances reported by the function is doubled when the region loop is there. It is duplicating instance IDs when it shouldn't do that. Each region should have it's own unique set of servers.
For example in one account there is 95 servers but when the region loop is there, it reports that there are 190 servers. And the resulting list shows duplicate instance IDs.
def list_instances(aws_account,aws_account_number, interactive, regions, fieldnames, show_details):
today, aws_env_list, output_file, output_file_name, fieldnames = initialize(interactive, aws_account)
options = arguments()
instance_list = ''
session = ''
ec2 = ''
account_found = ''
PrivateDNS = None
block_device_list = None
instance_count = 0
account_type_message = ''
profile_missing_message = ''
region = ''
# Set the ec2 dictionary
ec2info = {}
if 'gov' in aws_account and not 'admin' in aws_account:
session = boto3.Session(profile_name=aws_account,region_name=region)
account_found = 'yes'
else:
session = boto3.Session(profile_name=aws_account,region_name=region)
account_found = 'yes'
for region in regions:
if 'gov' in aws_account and not 'admin' in aws_account:
session = boto3.Session(profile_name=aws_account,region_name=region)
else:
session = boto3.Session(profile_name=aws_account,region_name=region)
ec2 = session.client("ec2")
# Loop through the instances
try:
instance_list = ec2.describe_instances()
except Exception as e:
pass
for reservation in instance_list["Reservations"]:
for instance in reservation.get("Instances", []):
instance_count = instance_count + 1
launch_time = instance["LaunchTime"]
launch_time_friendly = launch_time.strftime("%B %d %Y")
tree = objectpath.Tree(instance)
block_devices = set(tree.execute('$..BlockDeviceMappings[\'Ebs\'][\'VolumeId\']'))
if block_devices:
block_devices = list(block_devices)
block_devices = str(block_devices).replace('[','').replace(']','').replace('\'','')
else:
block_devices = None
private_ips = set(tree.execute('$..PrivateIpAddress'))
if private_ips:
private_ips_list = list(private_ips)
private_ips_list = str(private_ips_list).replace('[','').replace(']','').replace('\'','')
else:
private_ips_list = None
type(private_ips_list)
public_ips = set(tree.execute('$..PublicIp'))
if len(public_ips) == 0:
public_ips = None
if public_ips:
public_ips_list = list(public_ips)
public_ips_list = str(public_ips_list).replace('[','').replace(']','').replace('\'','')
else:
public_ips_list = None
if 'KeyName' in instance:
key_name = instance['KeyName']
else:
key_name = None
name = None
if 'Tags' in instance:
try:
tags = instance['Tags']
name = None
for tag in tags:
if tag["Key"] == "Name":
name = tag["Value"]
if tag["Key"] == "Engagement" or tag["Key"] == "Engagement Code":
engagement = tag["Value"]
except ValueError:
# print("Instance: %s has no tags" % instance_id)
pass
if 'VpcId' in instance:
vpc_id = instance['VpcId']
else:
vpc_id = None
if 'PrivateDnsName' in instance:
private_dns = instance['PrivateDnsName']
else:
private_dns = None
if 'Platform' in instance:
platform = instance['Platform']
else:
platform = None
ec2info[instance['InstanceId']] = {
'AWS Account': aws_account,
'Account Number': aws_account_number,
'Name': name,
'Instance ID': instance['InstanceId'],
'Volumes': block_devices,
'Private IP': private_ips_list,
'Public IP': public_ips_list,
'Private DNS': private_dns,
'Availability Zone': instance['Placement']['AvailabilityZone'],
'VPC ID': vpc_id,
'Type': instance['InstanceType'],
'Platform': platform,
'Key Pair Name': key_name,
'State': instance['State']['Name'],
'Launch Date': launch_time_friendly
}
ec2_info_items = ec2info.items
if show_details == 'y' or show_details == 'yes':
for instance_id, instance in ec2_info_items():
if account_found == 'yes':
print(Fore.RESET + "-------------------------------------")
for key in [
'AWS Account',
'Account Number',
'Name',
'Instance ID',
'Volumes',
'Private IP',
'Public IP',
'Private DNS',
'Availability Zone',
'VPC ID',
'Type',
'Platform',
'Key Pair Name',
'State',
'Launch Date'
]:
print(Fore.GREEN + f"{key}: {instance.get(key)}")
print(Fore.RESET + "-------------------------------------")
else:
pass
ec2info = {}
with open(output_file,'a') as csv_file:
csv_file.close()
report_instance_stats(instance_count, aws_account, account_found)
return output_file
def report_instance_stats(instance_count, aws_account, account_found):
if account_found == 'yes':
print(f"There are: {instance_count} EC2 instances in AWS Account: {aws_account}.")Why is it doing that when the regions loop is there? How do I get it to report the right number of instances in an account when the region loop is present?
