In today's cloud-centric world, managing AWS EC2 instances efficiently is paramount for DevOps engineers and system administrators. To streamline this process, I've developed a versatile Python script that not only simplifies listing and managing EC2 instances but also introduces a user-friendly way to filter and access your instances directly. This guide will walk you through the script's features, setup, and usage to help you manage your AWS infrastructure more effectively.
Key Features
- List All EC2 Instances: Displays both running and stopped instances, providing crucial details at a glance.
- Optional Filtering: Choose whether to include stopped instances in your list, allowing for a tailored view that matches your current needs.
- Search Functionality: Quickly find instances by name using a simple search term, perfect for environments with numerous instances.
- Selective Instance Access: Log into your chosen instance directly from the script, leveraging the correct SSH keys automatically.
Getting Started
Before diving into the script, ensure you have the AWS CLI and Boto3 library installed and configured on your system. These tools provide the necessary foundation to interact with AWS services and execute the script successfully.
- AWS CLI Installation: Follow the official AWS documentation to install and configure the AWS CLI, setting up your access ID, secret key, and default region.
- Boto3 Installation: Install Boto3 via pip with
pip install boto3
, ensuring you have Python 3.6 or later.
Script Breakdown
The script is structured into several key functions, each designed to handle specific aspects of the EC2 management process:
- Instance Listing and Filtering: Users can list all instances or opt to exclude stopped instances. Additionally, a search term can be applied to filter instances by name.
- Instance Selection: A user-friendly list allows you to select an instance for access, streamlining the login process.
- SSH Key Handling: The script automatically finds and uses the correct SSH key for the selected instance, based on its associated key name.
Usage
Running the script is straightforward. Execute it in your terminal, and follow the on-screen prompts to filter and select the instance you wish to access:
python manage_ec2.py
You'll first be asked whether to include stopped instances in the listing. Next, you have the option to enter a search term to filter instances by name. Finally, select the instance you wish to access from the presented list, and the script will initiate an SSH connection using the appropriate key.
Conclusion
This Python script enhances your AWS EC2 management capabilities, offering a streamlined and intuitive way to access and manage your instances. By incorporating optional filtering and search functionality, it caters to environments of all sizes, from a handful of instances to large-scale deployments.
Sharing this script on my blog is part of my commitment to not only improve my productivity but also contribute to the wider community. Whether you're a fellow DevOps engineer, a system administrator, or anyone managing AWS EC2 instances, I hope you find this tool as useful as I have in simplifying your cloud management tasks.
Feel free to adapt the script to your specific needs, and I'm eager to hear any feedback or enhancements you might suggest. Happy coding, and here's to a more manageable cloud infrastructure!
import boto3
import subprocess
import os
import time
# Initialize a boto3 EC2 resource
ec2 = boto3.resource('ec2')
def list_all_instances(include_stopped=False, search_term=None):
"""List all EC2 instances, optionally excluding stopped instances and filtering by search term."""
filters = [{'Name': 'tag:Name', 'Values': ['*'+search_term+'*']} if search_term else {'Name': 'instance-state-name', 'Values': ['running', 'stopped']}]
if not include_stopped:
filters.append({'Name': 'instance-state-name', 'Values': ['running']})
instances = ec2.instances.filter(Filters=filters)
return instances
def get_instance_name(instance):
"""Extract the name of the instance from its tags."""
for tag in instance.tags or []:
if tag['Key'] == 'Name':
return tag['Value']
return "No Name"
def select_instance(instances):
"""Allow the user to select an instance to log into."""
print("Available instances:")
if not instances:
print("No matching instances found.")
return None
for i, instance in enumerate(instances, start=1):
name = get_instance_name(instance)
print(f"{i}) Name: {name}, Instance ID: {instance.id}, State: {instance.state['Name']}")
selection = input("Enter the number of the instance you want to log into (or 'exit' to quit): ")
if selection.lower() == 'exit':
return None
try:
selection = int(selection) - 1
return list(instances)[selection]
except (ValueError, IndexError):
print("Invalid selection.")
return None
def find_key_for_instance(instance):
"""Find the SSH key for the instance based on its KeyName."""
key_name = instance.key_name
keys_directory = os.path.expanduser("~/.ssh")
for key_file in os.listdir(keys_directory):
if key_file.startswith(key_name) and key_file.endswith(".pem"):
return os.path.join(keys_directory, key_file)
return None
def ssh_into_instance(instance, remote_user="ec2-user"):
"""SSH into the selected instance, if any."""
if instance is None:
return
ssh_key_path = find_key_for_instance(instance)
if not ssh_key_path:
print(f"No matching SSH key found for instance {instance.id} with KeyName {instance.key_name}")
return
print(f"Logging into {get_instance_name(instance)} ({instance.id})...")
private_ip = instance.private_ip_address
ssh_cmd = f'ssh -o StrictHostKeyChecking=no -i {ssh_key_path} {remote_user}@{private_ip}'
subprocess.run(ssh_cmd, shell=True)
def main():
"""Main function to list instances and allow user selection for SSH login."""
include_stopped = input("Include stopped instances? (yes/no): ").lower().startswith('y')
search_term = input("Enter a search term to filter by instance name (leave empty for no filter): ").strip() or None
instances = list(list_all_instances(include_stopped, search_term))
selected_instance = select_instance(instances)
ssh_into_instance(selected_instance)
if __name__ == "__main__":
main()
π Join the DevOps Dojo! π
Are you passionate about growth, learning, and collaboration in the world of DevOps? The DevOps Dojo is your new home! Whether you’re just starting out or looking to refine your skills, this vibrant community is here to support your journey.
π§ What You’ll Get:
- Access to expert-led discussions
- Hands-on learning opportunities
- Networking with like-minded professionals
Ready to take your DevOps game to the next level? Click below to learn more and join the community!
π Join the DevOps Dojo Today
Letβs build, grow, and thrive together! π