Python function executes twice when region loop is present - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Python function executes twice when region loop is present (/thread-23581.html) |
Python function executes twice when region loop is present - bluethundr - Jan-06-2020 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? RE: Python function executes twice when region loop is present - ichabod801 - Jan-06-2020 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? RE: Python function executes twice when region loop is present - bluethundr - Jan-07-2020 (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. |