If you can’t run Ansible on every EC2 because you don’t have all the SSH keys, and you don’t have AWS SSM installed on every machine, so you can’t do remote code execution with Run Commands, this is your next best option.
This script finds server OS & OS Version data by looping through every region, every reservation in every region, then every instance in every reservation.
To find the OS version, the script makes a call to describe_images
for a given instance’s Image ID. The description field will contain the OS version if a default AMI was used to build the EC2. The script will not find an OS version if custom AMIs were used.
Enjoy!
"""
This script retrieves information about all Amazon Elastic Compute Cloud (EC2)
instances in a given list of regions and writes it to a CSV file.
The script uses the boto3 library to connect to the EC2 service and call the
describe_instances method to get a list of all reservations in each region.
It then iterates through the list of reservations and instances, and writes the
following information to a row in the CSV file:
- Instance ID
- Private IP address
- Image ID
- Platform details
- The image's description (if available)
The list of regions is specified in the REGIONS global variable.
"""
import csv
import boto3
REGIONS = [
"ap-south-1",
"eu-north-1",
"eu-west-3",
"eu-west-2",
"eu-west-1",
"ap-northeast-3",
"ap-northeast-2",
"ap-northeast-1",
"ca-central-1",
"sa-east-1",
"ap-southeast-1",
"ap-southeast-2",
"eu-central-1",
"us-east-1",
"us-east-2",
"us-west-1",
"us-west-2",
]
FILENAME = "ec2s.csv"
def main():
# Do The Work
with open(FILENAME, "w", newline="", encoding="utf-8") as csvfile:
fieldnames = [
"Instance ID",
"Private IP",
"Image ID",
"PlatformDetails",
"Description",
"Region",
]
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for region in REGIONS:
# Initialize EC2 client with region specified
ec2 = boto3.client("ec2", region_name=region)
# Call the describe_instances method to get a list of reservations
reservations = ec2.describe_instances()["Reservations"]
# Iterate through the list of reservations
for reservation in reservations:
# Iterate through the list of instances
for instance in reservation["Instances"]:
# Try to find the OS version through the description field
try:
description = ec2.describe_images(ImageIds=[instance["ImageId"]])[
"Images"
][0]["Description"]
except Exception:
description = None
# Store instance data
with open(FILENAME, "a", newline="", encoding="utf-8") as csvfile:
writer = csv.writer(csvfile)
writer.writerow(
[
instance["InstanceId"],
instance["PrivateIpAddress"],
instance["ImageId"],
instance["PlatformDetails"],
description,
region,
]
)
if __name__ == "__main__":
main()