In this article, we are presenting an AWS Boto Python script that lists all load balancers and their Target group along with the Instances associated and their health check status
This script helps you in various ways
- Get the list of load balancers and their target group and instance mapping along with their health
- Find out the load balancers with no backend target group or listeners which can simply be removed for cost saving
- Find how many Elastic Load balancer or Target groups, a Specific instance is associated with and receive traffic from
- Instance to ELB Mapping auditing - helping to remove unwanted instances
- A Health Check and Monitoring script for your entire Elastic Load Balancers and Target Groups, and Instances.
- This script helps you to find Unused Elastic Load Balancers ALBs and ELBs.
As you know there are three major types of load balances in AWS ELB. such as
- Classic Load Balancer
- Application Load Balancer
- Network Load Balancer
While Classic Load Balancer and Application Load Balancer are widely used and they differ in the way they are configured/designed.
I had to create two scripts one for each of them.
- clb-list.py - For Classic Load Balancer
- alb-list.py - For Application Load Balancer & Network Load Balancer
We have update our scripts with JSON output format. Check it out.
Prerequisites
- AWS CLI must be installed and configured with API Key and Secret
- Named Profile (Optional) or use
default
as profile name in the script - Boto3 must be installed
If you are new to AWS CLI refer to our previous article before proceeding
Wondering what is Named Profile
in AWS, refer to this article from AWS here
Besides that, you must have proper IAM permissions for you to be able to list these resources and configurations. You can try with Administrator Access IAM role if possible.
You can simply install boto3 by executing pip install boto3
Refer to this article for more details
To List Classic Load Balancer Configuration and Instances
This is a named profile
based script where I have used prod
as my profile name, you can refer to the previous article and use named profiles for managing multiple AWS accounts.
Update the script profile=default
instead of PROD, If you are not using Named Profile,
For the Named Profile setup, you have to update this profile
variable anyway with your profile name before executing.
Also the region_name
must be updated in both cases.
clb-list.py
import boto3 import pprint region_name = "us-east-1" profile = "prod" session = boto3.session.Session(profile_name=profile) elb = session.client('elb') ec2 = session.client('ec2') def getinstancename(instanceid): instances=ec2.describe_instances(Filters=[ { 'Name': 'instance-id', 'Values': [ instanceid ] }, ],) resultset = {} for instance in instances["Reservations"]: for inst in instance["Instances"]: resultset["State"]=inst["State"]["Name"] for tag in inst["Tags"]: if tag['Key'] == 'Name': resultset["Name"]=tag['Value'] # print (resultset) return resultset def getinstancehealth(lbname,instanceid): instancestate=elb.describe_instance_health( LoadBalancerName=lbname, Instances = [{ 'InstanceId' : instanceid }] ) return instancestate['InstanceStates'][0]['State'] lbs = elb.describe_load_balancers(PageSize=400) for lb in lbs["LoadBalancerDescriptions"]: print("\n"*2) print ("-"*6) print("Name:",lb["LoadBalancerName"]) print("HealthCheck:",lb["HealthCheck"]) print("Instance Info:") if len(lb["Instances"]) > 0: for instance in lb["Instances"]: instance.update(getinstancename(instance["InstanceId"])) instance['Health']=getinstancehealth(lb["LoadBalancerName"], instance["InstanceId"]) print (instance) else: print("Instance List is Empty, Or no Instance is mapped")
Sample Output
------ Name: test-elb HealthCheck: {'Target': 'HTTP:80/index.html', 'Interval': 30, 'Timeout': 5, 'UnhealthyThreshold': 2, 'HealthyThreshold': 10} Instance Info: {'InstanceId': 'i-somestring', 'State': 'running', 'Name': 'test.gritfy.io', 'Health': 'InService'} ------ Name: service-elb HealthCheck: {'Target': 'HTTP:80/index.html', 'Interval': 30, 'Timeout': 5, 'UnhealthyThreshold': 2, 'HealthyThreshold': 5} Instance Info: {'InstanceId': 'i-somestring', 'Health': 'OutOfService'} {'InstanceId': 'i-somestring', 'State': 'running', 'Name': 'service.gritfy.io', 'Health': 'InService'} ------ Name: beta-elb HealthCheck: {'Target': 'HTTP:80/beta/health/', 'Interval': 10, 'Timeout': 5, 'UnhealthyThreshold': 2, 'HealthyThreshold': 2} Instance Info: Instance List is Empty, Or not Instance is mapped
To List Application Load Balancer Configuration and Instances
import boto3 import pprint region_name = "us-east-1" profile = "prod" session = boto3.session.Session(profile_name=profile) elb = session.client('elbv2') ec2 = session.client('ec2') def gettargetgroups(arn): tgs=elb.describe_target_groups(LoadBalancerArn=arn) tgstring=[] for tg in tgs["TargetGroups"]: tgstring.append(tg["TargetGroupName"]) return tgstring def gettargetgrouparns(arn): tgs=elb.describe_target_groups(LoadBalancerArn=arn) tgarns=[] for tg in tgs["TargetGroups"]: tgarns.append(tg["TargetGroupArn"]) return tgarns def getinstancename(instanceid): instances=ec2.describe_instances(Filters=[ { 'Name': 'instance-id', 'Values': [ instanceid ] }, ],) for instance in instances["Reservations"]: for inst in instance["Instances"]: for tag in inst["Tags"]: if tag['Key'] == 'Name': return (tag['Value']) def gettargethealth(arn): inss=elb.describe_target_health(TargetGroupArn=arn) instanceids=[] for ins in inss["TargetHealthDescriptions"]: ins["Name"]=getinstancename(ins['Target']['Id']) instanceids.append(ins['Target']['Id']) print (ins) lbs = elb.describe_load_balancers(PageSize=400) for lb in lbs["LoadBalancers"]: print("\n"*2) print ("-"*6) print("Name:",lb["LoadBalancerName"]) print("Type:",lb["Type"]) print("TargetGroups:",str(gettargetgroups(lb["LoadBalancerArn"]))) for tgs in gettargetgrouparns(lb["LoadBalancerArn"]): gettargethealth(tgs)
Sample output
------ Name: iaas-elb Type: application TargetGroups: ['iaas-tg'] {'Target': {'Id': 'i-somestring', 'Port': 80}, 'HealthCheckPort': '80', 'TargetHealth': {'State': 'healthy'}, 'Name': 'iaas01.gritfy.io'} {'Target': {'Id': 'i-somestring', 'Port': 80}, 'HealthCheckPort': '80', 'TargetHealth': {'State': 'healthy'}, 'Name': 'iaas02.gritfy.io'} ------ Name: saas-elb Type: application TargetGroups: ['saas-tg'] {'Target': {'Id': 'i-somestring', 'Port': 80}, 'HealthCheckPort': '80', 'TargetHealth': {'State': 'healthy'}, 'Name': 'saas.gritfy.io'} ------ Name: app-saas Type: application TargetGroups: ['app-saas-TG'] {'Target': {'Id': 'i-somestring', 'Port': 80}, 'HealthCheckPort': '80', 'TargetHealth': {'State': 'unused', 'Reason': 'Target.InvalidState', 'Description': 'Target is in the stopped state'}, 'Name': None} ------ Name: service-elb Type: application TargetGroups: []
Updated script with JSON Output format
The previous scripts you have seen return the response in simple Text format.
It served the purpose. but now for further customisations and advancement, we have updated the script output to JSON format.
Now as a new version, I have updated the code to return the response in JSON format
here are the updated scripts
List Application Load Balancer and Network Load Balancer with Target Group
This python script is designed to accept the region and the profile name as a startup argument
Copy the following code and save it as clb-list-json.py
Here is the command example you can use. make sure to update the profile name and the region_name.
If you do not have any named profile on AWS CLI. just type default.
python3 alb-list-json.py us-east-1 default
here is the source code
alb-list-json.py
import boto3 import pprint import sys import json def gettargetgroups(arn): tgs=elb.describe_target_groups(LoadBalancerArn=arn) tgstring=[] for tg in tgs["TargetGroups"]: tgstring.append(tg["TargetGroupName"]) return tgstring def gettargetgrouparns(arn): tgs=elb.describe_target_groups(LoadBalancerArn=arn) tgarns=[] for tg in tgs["TargetGroups"]: tgarns.append(tg["TargetGroupArn"]) return tgarns def getinstancename(instanceid): instances=ec2.describe_instances(Filters=[ { 'Name': 'instance-id', 'Values': [ instanceid ] }, ],) for instance in instances["Reservations"]: for inst in instance["Instances"]: for tag in inst["Tags"]: if tag['Key'] == 'Name': return (tag['Value']) def gettargethealth(arn): # print("arn",arn) inss=elb.describe_target_health(TargetGroupArn=arn) instanceids=[] result=[] for ins in inss["TargetHealthDescriptions"]: ins["Name"]=getinstancename(ins['Target']['Id']) instanceids.append(ins['Target']['Id']) result.append(ins) return result def describelbs(): lbs = elb.describe_load_balancers(PageSize=400) for lb in lbs["LoadBalancers"]: lbjson={} lbjson['Name']=lb["LoadBalancerName"] lbjson['Type']=lb["Type"] lbjson['TG']=gettargetgrouparns(lb["LoadBalancerArn"]) lbjson['TGData']=[] TGLIST=[] if len(lbjson["TG"]) > 0: for tgs in lbjson['TG']: TGD={} TGD['Name']=tgs.split("/")[1] tgh=gettargethealth(tgs) if len(tgh) > 0: TGD['Instances']=tgh else: TGD['Instances']="" TGLIST.append(TGD) lbjson['TGData'] = TGLIST print("\n",json.dumps(lbjson, indent=4, sort_keys=True)) if __name__ == "__main__": if len(sys.argv) < 3: print(" – Region Name and the Profile name is mandatory – ") print(" Syntax: python3 clb-list-json.py us-east-1 default") exit() region_name = sys.argv[1] profile = sys.argv[2] session = boto3.session.Session(profile_name=profile) elb = session.client('elbv2') ec2 = session.client('ec2') describelbs()
List Classic Load Balancer with Target instances
This python script is designed to accept the region and the profile name as a startup argument
Copy the following code and save it as clb-list-json.py
Here is the command example you can use. make sure to update the profile name and the region_name
python3 clb-list-json.py us-east-1 default
clb-list-json.py
import boto3 import pprint import json import sys def getinstancename(instanceid): instances=ec2.describe_instances(Filters=[ { 'Name': 'instance-id', 'Values': [ instanceid ] }, ],) resultset = {} for instance in instances["Reservations"]: for inst in instance["Instances"]: resultset["State"]=inst["State"]["Name"] for tag in inst["Tags"]: if tag['Key'] == 'Name': resultset["Name"]=tag['Value'] # print (resultset) return resultset def getinstancehealth(lbname,instanceid): instancestate=elb.describe_instance_health( LoadBalancerName=lbname, Instances = [{ 'InstanceId' : instanceid }] ) return instancestate['InstanceStates'][0]['State'] def describelbs(): lbs = elb.describe_load_balancers(PageSize=400) for lb in lbs["LoadBalancerDescriptions"]: lbjson={} lbjson['Name']=lb["LoadBalancerName"] lbjson['HealthCheck']=lb["HealthCheck"] lbjson['Instances']=[] if len(lb["Instances"]) > 0: InstanceList=[] for instance in lb["Instances"]: instance.update(getinstancename(instance["InstanceId"])) instance['Health']=getinstancehealth(lb["LoadBalancerName"], instance["InstanceId"]) InstanceList.append(instance) lbjson['Instances']=InstanceList print("\n",json.dumps(lbjson, indent=4, sort_keys=True)) if __name__ == "__main__": if len(sys.argv) < 3: print(" – Region Name and the Profile name is mandatory – ") print(" Syntax: python3 clb-list-json.py us-east-1 default") exit() region_name = sys.argv[1] profile = sys.argv[2] print("profilename selected:",profile) print("regionname selected: ",region_name) session = boto3.session.Session(profile_name=profile) elb = session.client('elb') ec2 = session.client('ec2') describelbs()
Here is the output as JSON while I have run the script on my end
⚡ ⇒ python3 clb-list-json.py us-east-1 prod { "HealthCheck": { "HealthyThreshold": 10, "Interval": 30, "Target": "HTTP:80/index.html", "Timeout": 5, "UnhealthyThreshold": 2 }, "Instances": [ { "Health": "InService", "InstanceId": "i-06e3361ac9fe29d5a", "Name": "test-01.gritfy.io-UB20", "State": "running" }, { "Health": "InService", "InstanceId": "i-06e3361ac9fe29d5a", "Name": "push-01.gritfy.io-UB20", "State": "running" } ], "Name": "gritfy-elb" }
Github repo
That's the Github link you can Star and follow for further updates.
https://github.com/AKSarav/BotoScripts
List ALB and Target Groups as a Diagram
I have upgraded this script to the next level and now you can list your Application and Classic Load Balancers and their associated targets and target groups as a Diagram
Yes. I have added the python Diagram module to this existing code and made it possible.
you can create diagrams of all your Load Balancer in AWS using this
Here is the a glimpse of what it can do.
I have written an exclusive article on the same with the source code attached. Hope you might like it.
AWS ELB Diagram generator with Python Boto & Diagrams | Devops Junction
Find Unused Load Balancers based on Traffic - CloudWatch & Boto
I have created this new script which connects to CloudWatch API and collects the Load Balancer usage metrics of load balancers such as
- Request Count - ( ALB and CLB)
- ActiveFlowCount - ( NLB)
The report is generated and stored as a CSV - It is written with Threaded model for super fast data collection.
Check it out.
How to find Unused Load Balancers - Based on Traffic | AWS FinOps
Conclusion
Hope this AWS Boto script helps you with your Administration and AWS Management. you can feel free to contribute and upgrade this script
You can contribute to DevopsJunction by submitting an Article or the creative Devops work that you would like to share with the world.
Cheers
Sarav AK
Follow me on Linkedin My Profile Follow DevopsJunction onFacebook orTwitter For more practical videos and tutorials. Subscribe to our channel
Signup for Exclusive "Subscriber-only" Content