-
-
Save dastergon/b4994c605f76d528d0c4 to your computer and use it in GitHub Desktop.
from collections import defaultdict | |
import boto3 | |
""" | |
A tool for retrieving basic information from the running EC2 instances. | |
""" | |
# Connect to EC2 | |
ec2 = boto3.resource('ec2') | |
# Get information for all running instances | |
running_instances = ec2.instances.filter(Filters=[{ | |
'Name': 'instance-state-name', | |
'Values': ['running']}]) | |
ec2info = defaultdict() | |
for instance in running_instances: | |
for tag in instance.tags: | |
if 'Name'in tag['Key']: | |
name = tag['Value'] | |
# Add instance info to a dictionary | |
ec2info[instance.id] = { | |
'Name': name, | |
'Type': instance.instance_type, | |
'State': instance.state['Name'], | |
'Private IP': instance.private_ip_address, | |
'Public IP': instance.public_ip_address, | |
'Launch Time': instance.launch_time | |
} | |
attributes = ['Name', 'Type', 'State', 'Private IP', 'Public IP', 'Launch Time'] | |
for instance_id, instance in ec2info.items(): | |
for key in attributes: | |
print("{0}: {1}".format(key, instance[key])) | |
print("------") |
I like this code because I was unable to find any other code example of using boto3 and printing the specific tag values.
However, looks like this code would not run properly if the running EC2s have multiple tag names that have "Name" in the tag names.
For example, the running instances has a tag name "Name" and value "web1" and has another tag name "Cluster Name" and value "US-West". I have not tested it yet, but I will circle back after I test it.
@sandygvs / anyone else looking for an answer to the above (if I understand the question correctly) - if you're referring to filtering this code by VPC, subnets etc or limiting to a region you can add things like:
import boto3
from collections import defaultdict
region = 'ap-southeast-2'
az = 'ap-southeast-2a'
vpc = 'vpc-12345678'
subnet = 'subnet-12345678'
ec2 = boto3.resource('ec2', region)
running_instances = ec2.instances.filter(
Filters=[{
'Name': 'instance-state-name',
'Values': ['running']
},
{
'Name': 'availability-zone',
'Values': [az]
},
{
'Name': 'vpc-id',
'Values': [vpc]
},
{
'Name': 'subnet-id',
'Values': [subnet]
}]
)
If you mean ASG as in outputting security groups, you can add 'SG': instance.security_groups at the end of ec2info, and include it as an attribute.
As @ikekim said this will not work properly if instance.tags
has more than one tag with a value which has 'Name` as a substring, e.g.
>>> 'Name' in 'NameOfEmployee'
True
>>> 'name' in 'dog'
False
>>> 'Name' in 'Names'
I used
if tag['Key'] == 'Name'
...
...because if you examine the instance.tags
list of dicts there is only one 'Key'
with a value of 'Name'
Hola buen dia tengo una duda, como podria obtener el nombre de la instancia ?
Thanks a lot!!
@TacMechMonkey, is there anyway we can filter Instance Status for specific VPCID? resource does not have status option.
running_instances = ec2.instances.filter(
Filters=[{
'Name': 'instance-status.status',
'Values': ['impaired']
},
{
'Name': 'vpc-id',
'Values': [vpc]
}]
)
@nakkanar you're on the right track, you'll have to use the ec2 client:
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.describe_instance_status
you can use something like this and put in lambda. This will give you all the asg based on a name/tag you provide , list all the instance id's and then you can get things like IP/key etc on the id's
import boto3
client = boto3.client('autoscaling')
clientips=boto3.client('ec2')
paginator = client.get_paginator('describe_auto_scaling_groups')
page_iterator = paginator.paginate(
PaginationConfig = {
'PageSize': 100
}
)
def lambda_handler(event, context):
filtered_asgs = page_iterator.search(
'AutoScalingGroups[] | [?contains(Tags[?Key==`{}`].Value, `{}`)]'.format('type', 'node')
)
for asg in filtered_asgs:
print (asg['AutoScalingGroupName'])
response = client.describe_auto_scaling_groups(
AutoScalingGroupNames=[
asg['AutoScalingGroupName'],
],
)
instances=response["AutoScalingGroups"][0]["Instances"]
instanceids=[]
for i in instances:
instanceids.append(i["InstanceId"])
instaneips=[]
reservations = clientips.describe_instances(InstanceIds=[i['InstanceId']]).get("Reservations")
for reservation in reservations:
for instance in reservation['Instances']:
print(instance.get("PublicIpAddress"))
is there a way to filter out ASG specific to VPC or subnets via python boto? I tried with filter but no luck.
Any help is much appreciated