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?