- 公開日
- 最終更新日
【Lambda】AWS リソース情報を一括収集する
この記事を共有する
目次
はじめに
皆さんこんにちは!パーソル&サーバーワークスの小泉です。
AWS環境を運用していると、リソースの棚卸や構成管理のために、定期的にAWSリソースの情報を収集したいケースがあります。
本記事では、AWS Lambda関数を使用して様々なAWSリソース情報を収集し、Excelファイルとして出力する方法をまとめました
実現したいこと
以下のようなことを自動化したいと思ったことはありませんか?
- AWS環境のリソースを定期的に棚卸したい
- 実環境をもとにしたパラメータシートを作成したい
本記事で紹介するLambda関数を使えば、EC2、VPC、セキュリティグループ、RDS、Route 53など、多岐にわたるAWSリソースの情報を自動的に収集し、整理されたExcelファイルとして出力することができます。
全体の処理フロー
このLambda関数の処理フローは以下の通りです。
- 各種AWSリソース情報をAWS SDKを使って収集
- 収集した情報をExcelファイルに整理して出力
- 生成したExcelファイルをS3バケットにアップロード
実装の詳細
必要なライブラリ
この機能を実現するために、以下のライブラリを使用しています。
import boto3 import openpyxl from openpyxl import Workbook from openpyxl.styles import Font, PatternFill from io import BytesIO from datetime import datetime
boto3
: AWS SDKでAWSリソースにアクセスするために使用openpyxl
: Excelファイルを操作するために使用BytesIO
: メモリ上でバイナリデータを扱うために使用datetime
: 日時情報を扱うために使用
収集するAWSリソース情報
この関数では、以下のAWSリソース情報などを収集することができます。
※本記事では、EC2インスタンスの処理を抜粋して説明します。
- EC2インスタンス
- Auto Scaling Group
- AMI
- VPC
- サブネット
- ルートテーブル
- セキュリティグループ
- インターネットゲートウェイ
- NATゲートウェイ
- ALB(Application Load Balancer)
- ターゲットグループ
- RDSインスタンス
- Route 53ホストゾーンとレコードセット
- ACM証明書
- IAMロール
主要な関数の解説
リソース情報収集関数
この関数では、boto3のEC2クライアントを使用して、すべてのEC2インスタンス情報を取得しています。
ページネーションにも対応しており、大量のインスタンスがある環境でも全てのデータを取得できます。
def get_ec2_instances(): ec2 = boto3.client('ec2') ec2_data = [] next_token = None while True: try: response = ec2.describe_instances(NextToken=next_token) if next_token else ec2.describe_instances() except Exception as e: print(f"EC2インスタンスの取得エラー: {e}") break for reservation in response['Reservations']: for instance in reservation['Instances']: security_groups = [sg['GroupName'] for sg in instance['SecurityGroups']] tags = {tag['Key']: tag['Value'] for tag in instance.get('Tags', [])} launch_time = remove_timezone(instance['LaunchTime']).strftime("%Y-%m-%d %H:%M:%S") ec2_info = { 'Instance ID': instance['InstanceId'], 'Instance Type': instance['InstanceType'], 'State': instance['State']['Name'], # 他の属性も収集 } ec2_data.append(ec2_info) next_token = response.get('NextToken', None) if not next_token: break return ec2_data
同様に、他のAWSリソースについても専用の関数を用意し、それぞれのリソース情報を収集することが可能です。
Excel出力関数
この関数では、openpyxlを使用して新しいExcelワークブックを作成し、各リソースタイプごとにシートを作成して情報を書き込みを行います。 ヘッダー行は太字と黄色背景で強調表示されるようにスタイル設定されています。
def create_excel_file( ec2_data, vpc_data, subnet_data, route_table_data, sg_data, igw_data, nat_data, alb_data, listener_data, target_group_data, rds_data, route_53_data, record_set_data, acm_data, iam_roles_data, asg_data, ami_data ): workbook = Workbook() # EC2情報をシートに書き込む ec2_sheet = workbook.active ec2_sheet.title = "EC2 Instances" ec2_headers = [ "Instance ID", "Instance Type", "State", "Public IP", "Private IP", "Launch Time", # 他のヘッダー ] style_headers(ec2_sheet, ec2_headers) for instance in ec2_data: ec2_sheet.append([ instance['Instance ID'], instance['Instance Type'], instance['State'], # 他の属性 ]) # 他のリソース情報も同様にシートに書き込む # ... # バイナリストリームに保存 excel_stream = BytesIO() workbook.save(excel_stream) excel_stream.seek(0) return excel_stream
S3アップロード関数
この関数では、boto3のS3クライアントを使用して、メモリ上のExcelファイルをS3バケットにアップロードを行います。
def upload_to_s3(excel_stream, bucket_name, file_name): s3 = boto3.client('s3') try: s3.upload_fileobj(excel_stream, bucket_name, file_name) print(f"S3バケット '{bucket_name}' にファイル '{file_name}' が正常にアップロードされました。") except Exception as e: print(f"S3へのアップロードエラー: {e}")
メイン処理(Lambda Handler)
この関数では、各リソース情報を収集し、Excelファイルを生成して、S3バケットにアップロードするという一連の処理を実行します。 ファイル名には現在の日時が含まれるため、実行するたびに一意のファイル名が生成されます。
def lambda_handler(event, context): # 各種AWSリソースデータを取得 ( ec2_instances, vpc_information, subnet_information, route_table_information, security_group_information, internet_gateway_information, nat_gateway_information, alb_information, listener_information, target_group_information, rds_information, route_53_information, record_set_information, acm_information, iam_roles_information, asg_information, ami_information ) = gather_aws_resource_data() # Excelファイルを生成 print("Generating Excel file with collected AWS resource data...") excel_file = create_excel_file( ec2_instances, vpc_information, subnet_information, route_table_information, security_group_information, internet_gateway_information, nat_gateway_information, alb_information, listener_information, target_group_information, rds_information, route_53_information, record_set_information, acm_information, iam_roles_information, asg_information, ami_information ) print("Excel file generation completed.") # ファイル名に現在の日時を追加 current_time = datetime.now().strftime("%Y%m%d_%H%M%S") file_name = f'aws_resources_{current_time}.xlsx' # S3にアップロード bucket_name = 'xxxxxxx' print(f"Uploading file {file_name} to S3 bucket {bucket_name}...") upload_to_s3(excel_file, bucket_name, file_name) print(f"File {file_name} successfully uploaded to S3 bucket {bucket_name}.") # レスポンスを返却 return { 'statusCode': 200, 'body': f"全てのAWSリソース情報をExcelファイルとしてS3バケット '{bucket_name}' にアップロードしました。ファイル名: {file_name}" }
実装のポイント
1. エラーハンドリング
各リソース情報を取得する関数では、try-except文を使用してエラーハンドリングを行っています。これにより、一部のリソース情報の取得に失敗しても、処理全体が中断されることなく続行されます。
try: response = ec2.describe_instances(NextToken=next_token) if next_token else ec2.describe_instances() except Exception as e: print(f"EC2インスタンスの取得エラー: {e}") break
2. ページネーション対応
AWS APIは多くの場合、結果がページネーションされます。このコードでは、NextTokenを使用して全てのページを取得する処理を実装しています。
while True: response = ec2.describe_instances(NextToken=next_token) if next_token else ec2.describe_instances() # データ処理 next_token = response.get('NextToken', None) if not next_token: break
3. タイムゾーン情報の処理
AWS APIから返される日時情報にはタイムゾーン情報が含まれていますが、Excelに出力する際にはタイムゾーン情報を削除して統一的に扱うようにしています。
def remove_timezone(dt): if dt is not None and hasattr(dt, 'replace'): return dt.replace(tzinfo=None) return dt
4. メモリ効率の良い処理
大量のデータを扱う場合でも効率的に処理できるよう、ファイルをディスクに書き込まずにメモリ上で処理しています。
excel_stream = BytesIO() workbook.save(excel_stream) excel_stream.seek(0)
感想
本記事が、どなたかのお役に立てれば幸いです。
この記事は私が書きました
小泉 和貴
記事一覧全国を旅行することを目標に、仕事を頑張っています。
