My Journey to the cloud…

In pursuit of excellence….


Python/boto3 script to dump AWS Subnet information into a CSV File

Script Name – getSubnetInfo.py

import csv
import sys
import os
import boto3
import logging
import argparse
import traceback
from botocore.exceptions import ClientError
from datetime import datetime, timedelta, timezone

date_time_now = datetime.now().strftime('%Y/%m/%d  %H:%M:%S')


DEFAULT_REGION = "us-east-1"
vpcid = tgwFlag = vpcCIDR = ""



def ec2_client(region):
    """
    Connects to EC2, returns a connection object
    """
    try:
        conn = boto3.client('ec2', region_name=region)

    except Exception as e:
        sys.stderr.write(
            'Could not connect to region: %s. Exception: %s\n' % (region, e))
        conn = None

    return conn


def parse_commandline_arguments():
    global REGION
    global ACCOUNT_ID
    global report_filename

    parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter,
                                     description='Create a CSV Report for Subnet Info.')
    parser.add_argument("-id", "--accountID", dest="account_id", type=str,required=True,
                        help="The AWS Account Name for which the Subnet info is neeeded")
    parser.add_argument("-r", "--region", dest="region", type=str,
                        default=DEFAULT_REGION, help="Specify the global region to pull the report")
    parser.add_argument("-f", "--report", dest="reportname", type=str,
                        help="Specify the report file Name with path")
    args = parser.parse_args()

    ACCOUNT_ID= args.account_id
    REGION = args.region
    report_filename = args.reportname


def getvpcinfo(client,awsRegion):
    global vpcid
    global vpcCIDR
    vpcCIDR = vpcid = ""
    # if you want to retrict your list ONLY to any specific VPC Name
    #filtervpc = [{'Name':'tag:Name', 'Values':['vpc-main']}]
    try:
        #response = client.describe_vpcs(Filters=filtervpc)
        response = client.describe_vpcs()
        for vpc in response["Vpcs"]:
            vpcid = vpc["VpcId"]
            vpcCIDR = vpc["CidrBlock"]
            #print("VPC ID and VPC CIDR is - {} , {}" .format(vpcid,vpcCIDR))
            getsubnetinfo(vpcid,vpcCIDR,client,awsRegion)
        #return vpcid,vpcCIDR
        return None
    except Exception as e:
        logging.error(e)


def get_transitgateway_info(client):
    global tgwFlag
    try:
        response = client.describe_transit_gateways()
        if len(response['TransitGateways']) > 0:
            for tgw in response['TransitGateways']:
                tgwID = tgw['TransitGatewayId']
                tgwFlag = "Y"
        else:
            tgwFlag = "N"
        return tgwFlag
    except Exception as e:
        logging.error(e)


def getsubnetinfo(vpcid,vpc_cidr,client,region):
    OwnerId = subnetID = AvailabilityZone = CidrBlock = VpcId = vpcCIDR = ""
    filtersubnet = [{'Name':'vpc-id', 'Values':[vpcid]}]
    vpcCIDR = vpc_cidr
    try:
        tgwFlag = get_transitgateway_info(client)
        responsesubnet = client.describe_subnets(Filters=filtersubnet)
        datalist = responsesubnet["Subnets"]
        for i in range(len(datalist)):
            for key in datalist[i]:
                if key == 'SubnetId':
                    subnetID = datalist[i][key]
                if key == 'AvailabilityZone':
                    AvailabilityZone = datalist[i][key]
                if key == 'CidrBlock':
                    CidrBlock = datalist[i][key]
                if key == 'VpcId':
                    VpcId = datalist[i][key]
                if key == 'OwnerId':
                    OwnerId = datalist[i][key]
            print_string = OwnerId + "," + region + "," + subnetID + "," + AvailabilityZone + "," + CidrBlock + "," + VpcId + "," +  vpcCIDR + "," + tgwFlag + "," + date_time_now
            print(print_string)
            file.write(print_string + "\n")
    except Exception as e:
        logging.error(e)
                
    

if __name__ == '__main__':
    try:
        parse_commandline_arguments()
        client = ec2_client(REGION)
        if not os.path.isfile(report_filename):
            file = open(report_filename, 'w+')
            print_string_hdr = "AccountID,Region,SubnetID,AvailabilityZone,CidrBlock,VpcId,VpcCIDR,TGW_Flag,Reporting_Date_Time\n"
            file.write(print_string_hdr)
        else:
            file = open(report_filename, 'a')
        getvpcinfo(client,REGION)
    except Exception as error:
        print(str(error))

How to run the script:

Make sure you have python3 installed and configured and is in path. Script takes takes 3 arguments.

  • AWS Account ID against which you need to get the list of Security Groups
  • AWS Region
  • & CSV File name with complete path

Usage: python getSubnetInfo.py -id 123456789 -r us-east-1 -f /tmp/subnetnfoList.csv

You can run this python script against all of your AWS Accounts and all of the region by –

Invoking this python script from within a shell script with a control file that has all the AWS Accounts and their corresponding regions.

Shell script will loop through all the AWS accounts and region and hen generate a consolidated CSV file.

Hope this helps.

Keep reading and happy learning.

~Anand M



Leave a comment

About Me

I’m a Hands-On Technical & Entrprise Solutions Architect based out of Houston, TX. I have been working on Oracle ERP, Oracle Database and Cloud technologies for over 20 years and still going strong for learning new things.

You can connect me on Linkedin and also reach out to me

I am certified for 8x AWS, OCP (Oracle Certified Professionals), PMP, ITTL and 6 Sigma.

Disclaimer

This is a personal blog. Any views or opinions represented in this blog are personal and belong solely to the blog owner and do not represent those of people, institutions or organizations that the owner may or may not be associated with in professional or personal capacity, unless explicitly stated.
All content provided on this blog is for informational purposes only. The owner of this blog makes no representations as to the accuracy or completeness of any information on this site or found by following any link on this site.

The owner will not be liable for any errors or omissions in this information nor for the availability of this information. The owner will not be liable for any losses, injuries, or damages from the display or use of this information. Any script available on the blog post MUST be tested before they are run against Production environment.

Newsletter