get_ebs_volumes - robjcook/sync GitHub Wiki
import boto3
import csv
from datetime import datetime
def get_ebs_volumes_with_specific_tags_to_csv(
region_name='us-east-1',
output_file='ebs_volumes_tags.csv',
tag_keys_to_include=None,
ignore_name_tag_prefix=None
):
"""
Pulls a list of EBS volumes and their metadata from a specified AWS region.
It creates a CSV file with each of the specified tag keys as its own column,
while ignoring any volumes whose 'Name' tag value starts with a specified prefix.
Args:
region_name (str): The AWS region to query for EBS volumes.
output_file (str): The name of the output CSV file.
tag_keys_to_include (list): A list of strings representing the tag keys to
include as separate columns in the CSV.
ignore_name_tag_prefix (str): A string prefix for the 'Name' tag value to ignore.
For example, 'workerenv' will ignore any
volume with a 'Name' tag value starting with 'workerenv'.
"""
if not tag_keys_to_include:
print("No tag keys specified. Please provide a list of tag keys to include.")
return
try:
ec2_client = boto3.client('ec2', region_name=region_name)
print(f"Connecting to AWS region: {region_name}...")
# Define the static metadata field names
base_fieldnames = [
'VolumeId', 'VolumeType', 'Size', 'Iops', 'State',
'AvailabilityZone', 'CreateTime', 'Encrypted', 'SnapshotId',
'Attachment_InstanceId', 'Attachment_Device'
]
# Combine base field names with the user-specified tag keys to form the full header
all_fieldnames = base_fieldnames + tag_keys_to_include
# Prepare the CSV file for writing
with open(output_file, 'w', newline='') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=all_fieldnames)
writer.writeheader()
print(f"Retrieving EBS volume data and writing to '{output_file}'...")
volume_count = 0
filtered_out_count = 0
# Paginate through all EBS volumes
paginator = ec2_client.get_paginator('describe_volumes')
volume_pages = paginator.paginate()
for page in volume_pages:
for volume in page['Volumes']:
# Extract tags first, as we need them for filtering
tags_list = volume.get('Tags', [])
tags_dict = {tag['Key']: tag['Value'] for tag in tags_list}
# --- New Logic: Ignore volumes based on 'Name' tag prefix ---
name_tag_value = tags_dict.get('Name', '') # Get 'Name' tag value, default to empty string if not found
if ignore_name_tag_prefix and name_tag_value.startswith(ignore_name_tag_prefix):
filtered_out_count += 1
continue # Skip to the next volume
volume_count += 1
# Create a dictionary for the current row
row_data = {
'VolumeId': volume.get('VolumeId'),
'VolumeType': volume.get('VolumeType'),
'Size': volume.get('Size'),
'Iops': volume.get('Iops', 'N/A'),
'State': volume.get('State'),
'AvailabilityZone': volume.get('AvailabilityZone'),
'CreateTime': volume.get('CreateTime', datetime.min).isoformat(),
'Encrypted': volume.get('Encrypted'),
'SnapshotId': volume.get('SnapshotId', 'N/A')
}
# Handle attachments
attachments = volume.get('Attachments', [])
row_data['Attachment_InstanceId'] = attachments[0].get('InstanceId', 'N/A') if attachments else 'N/A'
row_data['Attachment_Device'] = attachments[0].get('Device', 'N/A') if attachments else 'N/A'
# Add a value for each desired tag, using the already-created tags_dict
for tag_key in tag_keys_to_include:
row_data[tag_key] = tags_dict.get(tag_key, 'N/A')
writer.writerow(row_data)
print(f"Successfully retrieved and processed {volume_count} EBS volumes.")
if filtered_out_count > 0:
print(f"Ignored {filtered_out_count} volumes based on the 'Name' tag prefix: '{ignore_name_tag_prefix}'.")
print(f"CSV file '{output_file}' created successfully.")
except Exception as e:
print(f"An error occurred: {e}")
if __name__ == '__main__':
# --- Example Usage ---
# Define the list of tag keys you want as individual columns
my_desired_tags = ['Name', 'Environment', 'System']
# Define the prefix for the 'Name' tag to ignore
name_prefix_to_ignore = 'workerenv'
get_ebs_volumes_with_specific_tags_to_csv(
region_name='us-east-1',
output_file='ebs_volumes_filtered_by_name.csv',
tag_keys_to_include=my_desired_tags,
ignore_name_tag_prefix=name_prefix_to_ignore
)