Python Forum
Python function executes twice when region loop is present
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Python function executes twice when region loop is present
#1
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.

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?
Reply
#2
The instance count is reported in report_instance_stats. This is called on line 139, at the end of the 'for instance' loop on line 38. But that's within the 'for reservation' loop on line 37, and you don't reset the count before the next iteration of the 'for reservation' loop. Could that be causing the problem?
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#3
(Jan-06-2020, 11:06 PM)ichabod801 Wrote: The instance count is reported in report_instance_stats. This is called on line 139, at the end of the 'for instance' loop on line 38. But that's within the 'for reservation' loop on line 37, and you don't reset the count before the next iteration of the 'for reservation' loop. Could that be causing the problem?

Thanks, but I don't think so. Because the instance IDs are being duplicated in the output. So, it's not just reporting an incorrect total.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Using locationtagger to extract locations found in a specific country/region lord_of_cinder 1 1,260 Oct-04-2022, 12:46 AM
Last Post: Larz60+
  Check if a value is present in each group Menthix 8 2,691 May-16-2022, 12:25 PM
Last Post: Menthix
  Anaconda pip install mpyc Error pip-script.py is not present Anldra12 2 7,806 Dec-13-2021, 06:59 PM
Last Post: Anldra12
  Exit Function - loop Tetsuo30 2 2,050 Sep-17-2020, 09:58 AM
Last Post: Tetsuo30
  Add new line after finding last string in a region Nigel11 1 1,875 Aug-08-2020, 10:00 PM
Last Post: Larz60+
  No Scripts File present after python installation ag2207 5 4,878 Jul-30-2020, 11:11 AM
Last Post: buran
  pytz: get integer utc offset from Olsen region/city h4tt3n 2 5,209 Jul-30-2020, 06:43 AM
Last Post: h4tt3n
  pyautogui.screenshot region is not working alexlu 6 6,457 Jun-04-2020, 10:46 AM
Last Post: alexlu
  Using Function in a For loop vp1989 5 2,795 May-19-2020, 03:53 PM
Last Post: vp1989
  "usr" directory not present and needed for cmd commands? ajetrumpet 2 2,139 Dec-19-2019, 05:59 PM
Last Post: ajetrumpet

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020