ニュース&ブログ
AWSから簡単にパラメータシートを生成する
投稿日:2025-09-17
はじめに
時間の経過とともに増えていくEC2インスタンス、作成者が不明なVPC、整理が行き届いていないサブネットやセキュリティグループなど、AWS環境は運用を続ける中で複雑化していく傾向があります。
容易にリソースを作成できる一方で、「現在の構成を正確に把握したい」というニーズが生じた際、マネジメントコンソール上で手作業で情報を集計するのは手間がかかり、漏れやミスにつながる可能性があります。
そこで今回は、AWS CLIでリソース情報(JSON形式)を取得し、Pythonを用いてExcel形式のパラメータシートを生成する方法をご紹介します。
この方法により、複雑化したAWS環境をワンコマンドで一覧化し、構成管理の効率化と正確性の向上が可能になります。
ゴールと要件
- AWS上のEC2、VPC関連の全リソースを取得
- 構成管理に使えるパラメータシート(Excel)形式で出力
- いつでもワンコマンドで最新情報を取得できる再現性
- 将来的にRDSやS3など他サービスも追加可能な構造
技術選定
技術 | 用途 | 採用理由 |
---|---|---|
AWS CLI | リソース情報取得 | スクリプタブルで再現性・汎用性が高い |
Python + pandas | JSON → DataFrame加工 | 複雑なJSON整形と表形式変換が容易 |
openpyxl | Excel出力 | pandasとの親和性が高く、マルチシート出力対応 |
全体アーキテクチャ
このツールは、AWS環境からリソース情報を取得し、整形してExcel形式のパラメータシートにまとめるまでを2つのスクリプトで実現します。
[AWS環境]
↓ (AWS CLI / aws_resources.sh)
[JSONファイル群]
↓ (Python / aws_resources_to_excel.py)
[パラメータシート]
(Excel / aws_resources.xlsx)
📋 処理フロー
ステップ | スクリプト名 | 処理内容 | 入力 | 出力 |
---|---|---|---|---|
1 | aws_resources.sh | AWS CLIを使って、EC2 / VPC / Subnet / RouteTable / SecurityGroup の情報を取得 | AWS環境 | JSONファイル群(ec2_instances.json など) |
2 | aws_resources_to_excel.py | JSONをDataFrameに整形し、リソースごとにシート分けして1つのExcelファイルに出力 | JSONファイル群 | aws_resources.xlsx(パラメータシート) |
実装ハイライト
💻 JSON取得スクリプト(aws_resources.sh)
#!/bin/bash
#============================
# AWS リソース取得
# 取得対象: EC2 / VPC
#============================
# リージョン指定(デフォルトap-northeast-1)
REGION=${1:-ap-northeast-1}
# スクリプトのあるディレクトリ
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
# 出力ディレクトリ
OUTDIR="${SCRIPT_DIR}/output_$(date +%Y%m%d%H%M%S)"
mkdir -p "$OUTDIR"
echo "AWS リージョン: $REGION"
echo "出力ディレクトリ: $OUTDIR"
#################################
# 1. EC2
#################################
aws ec2 describe-instances --region "$REGION" --output json > "$OUTDIR/ec2_instances.json"
#################################
# 2. VPC
#################################
aws ec2 describe-vpcs --region "$REGION" --output json > "$OUTDIR/vpcs.json"
aws ec2 describe-subnets --region "$REGION" --output json > "$OUTDIR/subnets.json"
aws ec2 describe-route-tables --region "$REGION" --output json > "$OUTDIR/route_tables.json"
aws ec2 describe-security-groups --region "$REGION" --output json > "$OUTDIR/security_groups.json"
#################################
# ZIP 圧縮
#################################
ZIPFILE="${SCRIPT_DIR}/aws_resources_${REGION}_$(date +%Y%m%d%H%M%S).zip"
cd "$SCRIPT_DIR" || exit 1
zip -r "$ZIPFILE" "$(basename "$OUTDIR")" > /dev/null
echo "取得完了: $OUTDIR"
echo "ZIPファイル作成: $ZIPFILE"
💻 Excel生成スクリプト(aws_resources_to_excel.py)
import json
import pandas as pd
from pathlib import Path
def get_name_tag(tags):
"""Nameタグの値を取得"""
return next((t["Value"] for t in tags if t["Key"] == "Name"), "")
# ==== JSONファイル読み込み ====
with open("ec2_instances.json", "r", encoding="utf-8") as f:
ec2_data = json.load(f)
with open("vpcs.json", "r", encoding="utf-8") as f:
vpcs_data = json.load(f)
with open("subnets.json", "r", encoding="utf-8") as f:
subnets_data = json.load(f)
with open("route_tables.json", "r", encoding="utf-8") as f:
rtb_data = json.load(f)
with open("security_groups.json", "r", encoding="utf-8") as f:
sg_data = json.load(f)
# ==== EC2 Instances ====
ec2_records = []
for reservation in ec2_data["Reservations"]:
for instance in reservation["Instances"]:
name_tag = get_name_tag(instance.get("Tags", []))
subnet_id = instance.get("SubnetId", "")
sg_list = [sg["GroupId"] for sg in instance.get("SecurityGroups", [])]
sg_names = [sg["GroupName"] for sg in instance.get("SecurityGroups", [])]
ec2_records.append({
"InstanceId": instance.get("InstanceId", ""),
"Name": name_tag,
"InstanceType": instance.get("InstanceType", ""),
"AvailabilityZone": instance.get("Placement", {}).get("AvailabilityZone", ""),
"State": instance.get("State", {}).get("Name", ""),
"PrivateIpAddress": instance.get("PrivateIpAddress", ""),
"PublicIpAddress": instance.get("PublicIpAddress", ""),
"SubnetId": subnet_id,
"SecurityGroupIds": ", ".join(sg_list),
"SecurityGroupNames": ", ".join(sg_names)
})
df_ec2 = pd.DataFrame(ec2_records)
# ==== VPCs ====
vpc_records = []
for vpc in vpcs_data["Vpcs"]:
vpc_records.append({
"VpcId": vpc.get("VpcId", ""),
"Name": get_name_tag(vpc.get("Tags", [])),
"CidrBlock": vpc.get("CidrBlock", ""),
"State": vpc.get("State", ""),
"IsDefault": vpc.get("IsDefault", False)
})
df_vpcs = pd.DataFrame(vpc_records)
# ==== Subnets ====
subnet_records = []
for sn in subnets_data["Subnets"]:
subnet_records.append({
"SubnetId": sn.get("SubnetId", ""),
"Name": get_name_tag(sn.get("Tags", [])),
"VpcId": sn.get("VpcId", ""),
"CidrBlock": sn.get("CidrBlock", ""),
"AvailabilityZone": sn.get("AvailabilityZone", "")
})
df_subnets = pd.DataFrame(subnet_records)
# ==== Route Tables ====
rtb_records = []
for rtb in rtb_data["RouteTables"]:
routes_str = "; ".join(
[f"{r.get('DestinationCidrBlock', r.get('DestinationIpv6CidrBlock', ''))} -> {r.get('GatewayId', r.get('NatGatewayId', r.get('TransitGatewayId', '')))}"
for r in rtb.get("Routes", [])]
)
rtb_records.append({
"RouteTableId": rtb.get("RouteTableId", ""),
"Name": get_name_tag(rtb.get("Tags", [])),
"VpcId": rtb.get("VpcId", ""),
"Routes": routes_str
})
df_rtb = pd.DataFrame(rtb_records)
# ==== Security Groups ====
sg_records = []
for sg in sg_data["SecurityGroups"]:
ingress_rules = []
for perm in sg.get("IpPermissions", []):
proto = perm.get("IpProtocol", "")
if "FromPort" in perm and "ToPort" in perm:
ports = f"{perm.get('FromPort')} - {perm.get('ToPort')}"
else:
ports = "ALL"
cidrs = ",".join([r.get("CidrIp", "") for r in perm.get("IpRanges", [])])
ingress_rules.append(f"{proto} {ports} {cidrs}")
sg_records.append({
"GroupId": sg.get("GroupId", ""),
"Name": get_name_tag(sg.get("Tags", [])),
"GroupName": sg.get("GroupName", ""),
"VpcId": sg.get("VpcId", ""),
"Description": sg.get("Description", ""),
"Ingress": "; ".join(ingress_rules)
})
df_sg = pd.DataFrame(sg_records)
# ==== Excel 出力 ====
out_path = Path("aws_resources.xlsx")
with pd.ExcelWriter(out_path, engine="openpyxl") as writer:
df_ec2.to_excel(writer, sheet_name="EC2 Instances", index=False)
df_vpcs.to_excel(writer, sheet_name="VPCs", index=False)
df_subnets.to_excel(writer, sheet_name="Subnets", index=False)
df_rtb.to_excel(writer, sheet_name="RouteTables", index=False)
df_sg.to_excel(writer, sheet_name="SecurityGroups", index=False)
print(f"Excelファイルを出力しました: {out_path.resolve()}")
工夫ポイントとハマりどころ
- ReadOnlyAccessだけで実行可能なので環境を変更するリスクがない
- SGルールの簡潔化:Protocol / Port / CIDR をまとめて1セルに表記
- マルチSG・マルチルート対応:複数値はカンマ・セミコロンで連結
- スキーマ統一:列順を決めてDataFrame化、Excel列幅も後で調整しやすく
実行手順
1. 事前準備
- AWS CLIがインストールされていること
- AWSアクセスキーが設定されていること
- Python3が利用可能であること
- 必要なPythonライブラリのインストール
pip install pandas openpyxl
2. JSONファイル取得
- (1) ターミナル(またはコマンドプロンプト)を開く
- (2) aws_resources.sh のあるディレクトリへ移動
- (3) 実行権限がない場合は付与
chmod +x aws_resources.sh
- (4) JSON取得スクリプトを実行 ※引数が無い場合は東京リージョン(
ap-northeast-1
)を取得します。./aws_resources.sh <Region Name>
実行後に作成されるファイル:
- ec2_instances.json(EC2インスタンス一覧)
- vpcs.json(VPC一覧)
- subnets.json(サブネット一覧)
- route_tables.json(ルートテーブル一覧)
- security_groups.json(セキュリティグループ一覧)
3. パラメータシート(Excel)生成
-
(1) JSONファイルのあるディレクトリで以下を実行
python aws_resources_to_excel.py
📊 出力されるExcelの構成
シート名 | 内容 |
---|---|
EC2 Instances | EC2インスタンス一覧(InstanceId / Name / InstanceType / AZ / State / Private/Public IP / SubnetId / SecurityGroupIds / SecurityGroupNames) |
VPCs | VPC一覧(VpcId / Name / CidrBlock / State / IsDefault) |
Subnets | サブネット一覧(SubnetId / Name / VpcId / CidrBlock / AvailabilityZone) |
RouteTables | ルートテーブル一覧(RouteTableId / Name / VpcId / Routes) |
SecurityGroups | セキュリティグループ一覧(GroupId / Name / GroupName / VpcId / Description / Ingressルール) |
実行例
今回はAWSマネジメントコンソール(CloudShell)で実行します。
必要に応じてAWSCloudShellFullAccessポリシーを付与してください。
必要に応じてAWSCloudShellFullAccessポリシーを付与してください。
📌 PythonライブラリのインストールからJSONファイル取得まで

📌 Excelパラメータシートを生成するまで

📌 パラメータシート(Excel)の画面

今後の拡張
- RDS / S3 / ELB などのサービス追加
- 自動化による定期実行(cron / GitHub Actions / Lambda)
- Gitで構成履歴を管理し差分比較
まとめ
AWS環境は時間とともに複雑化しやすく、手動でのリソース把握は非効率です。 今回紹介したスクリプトを使えば、現状の構成を即座にExcel化し、チーム全員で共有できます。
構成管理の可視化はトラブル予防にもつながります。小さなステップからでも導入してみましょう。
野口大貴(1992年生まれ 2022年入社)
株式会社システムサポート フューチャーイノベーション事業本部
ソリューションサービス事業部所属。
インフラエンジニア。AWS、Azureの基本設計から運用までを担当。開発もたまにやります。
- « 前のニュースへ