AWS リソースの一覧を CLI で取得するスクリプト(生成 AI による追加運用も添えて)
こんにちは、製造ビジネステクノロジー部の若槻です。
AWS 環境の棚卸しなど、AWS リソースの一覧を出力したいシチュエーションは多いと思います。
AWS CLI には resourcegroupstaggingapi get-resources というリソースの一覧をサービス横断で取得できるコマンドがあります。AWS リソース 一覧 取得
などで検索してトップに出てくるのがこのコマンドです。しかし残念ながらこのコマンドは タグが付与済み又は付与されたことがある リソースのみが取得対象となり、それ以外のリソースは取得できません。タグ付与運用をしていない環境では利用が難しいコマンドとなります。
そこで今回、AWS リソースの一覧を CLI で取得するスクリプトを作成してみたのでご紹介します。
今回紹介するスクリプトで考慮していないこと
今回のスクリプトはカスタマイズ性のためにシンプルな構成にしています。よって以下の点は考慮していません。
- リソースの詳細情報の出力
- リソース種類ごとの取得数のカウント
- ページネーション
スクリプト
作成したスクリプトはこちらです。
#!/bin/bash
REGION="ap-northeast-1"
DATETIME=$(date +%Y%m%d_%H%M%S)
ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
OUTPUT_FILE="aws_resources_${ACCOUNT_ID}_${REGION}_${DATETIME}.txt"
echo "Fetching AWS resources in ${REGION} (Account: ${ACCOUNT_ID})..."
> "${OUTPUT_FILE}"
# API Gateway REST APIs
aws apigateway get-rest-apis --region ${REGION} --query 'items[*].id' --output text | \
tr '\t' '\n' | \
sed "s/^/arn:aws:apigateway:${REGION}:\/restapis\//" >> "${OUTPUT_FILE}"
# AppSync APIs
aws appsync list-graphql-apis --region ${REGION} --query 'graphqlApis[*].arn' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# CloudFormation Stacks
aws cloudformation list-stacks --region ${REGION} --query 'StackSummaries[*].StackId' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# CloudWatch Log Groups
aws logs describe-log-groups --region ${REGION} --query 'logGroups[*].arn' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# Cognito Identity Pools
aws cognito-identity list-identity-pools --region ${REGION} --query 'IdentityPools[*].IdentityPoolId' --output text | tr '\t' '\n' | sed "s/^/arn:aws:cognito-identity:${REGION}:${ACCOUNT_ID}:identitypool\//" >> "${OUTPUT_FILE}"
# Cognito User Pools
aws cognito-idp list-user-pools --region ${REGION} --query 'UserPools[*].Id' --output text | tr '\t' '\n' | sed "s/^/arn:aws:cognito-idp:${REGION}:${ACCOUNT_ID}:userpool\//" >> "${OUTPUT_FILE}"
# DynamoDB Tables
aws dynamodb list-tables --region ${REGION} --query 'TableNames[*]' --output text | tr '\t' '\n' | sed "s/^/arn:aws:dynamodb:${REGION}:${ACCOUNT_ID}:table\//" >> "${OUTPUT_FILE}"
# EC2 Instances and VPCs
aws ec2 describe-instances --region ${REGION} --query 'Reservations[*].Instances[*].InstanceId' --output text | tr '\t' '\n' | sed "s/^/arn:aws:ec2:${REGION}:${ACCOUNT_ID}:instance\//" >> "${OUTPUT_FILE}"
aws ec2 describe-vpcs --region ${REGION} --query 'Vpcs[*].VpcId' --output text | tr '\t' '\n' | sed "s/^/arn:aws:ec2:${REGION}:${ACCOUNT_ID}:vpc\//" >> "${OUTPUT_FILE}"
# EventBridge Rules
aws events list-rules --region ${REGION} --query 'Rules[*].Arn' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# Lambda Functions
aws lambda list-functions --region ${REGION} --query 'Functions[*].FunctionArn' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# S3 Buckets
aws s3api list-buckets --query 'Buckets[*].Name' --output text | tr '\t' '\n' | sed 's/^/arn:aws:s3:::/' >> "${OUTPUT_FILE}"
# SSM Parameters
aws ssm describe-parameters --region ${REGION} --query 'Parameters[*].Name' --output text | tr '\t' '\n' | sed "s/^/arn:aws:ssm:${REGION}:${ACCOUNT_ID}:parameter\//" >> "${OUTPUT_FILE}"
# Step Functions
aws stepfunctions list-state-machines --region ${REGION} --query 'stateMachines[*].stateMachineArn' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# IAM (グローバルサービス)
aws iam list-users --query 'Users[*].Arn' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
aws iam list-groups --query 'Groups[*].Arn' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
aws iam list-policies --scope Local --query 'Policies[*].Arn' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# Amplify Apps
aws amplify list-apps --region ${REGION} --query 'apps[*].appArn' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# AWS Config Recorders
aws configservice describe-configuration-recorders --region ${REGION} --query 'ConfigurationRecorders[*].arn' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# Security Hub Standards
aws securityhub get-enabled-standards --region ${REGION} --query 'StandardsSubscriptions[*].StandardsArn' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# CloudTrail Trails
aws cloudtrail list-trails --region ${REGION} --query 'Trails[*].TrailARN' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# Detective Graphs
aws detective list-graphs --region ${REGION} --query 'GraphList[*].Arn' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# GuardDuty Detectors
aws guardduty list-detectors --region ${REGION} --query 'DetectorIds[*]' --output text | tr '\t' '\n' | sed "s/^/arn:aws:guardduty:${REGION}:${ACCOUNT_ID}:detector\//" >> "${OUTPUT_FILE}"
# Inspector Findings
aws inspector2 list-findings --region ${REGION} --query 'findings[*].findingArn' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# Macie Sessions
aws macie2 get-macie-session --region ${REGION} --query 'status' --output text > /dev/null 2>&1 && echo "arn:aws:macie2:${REGION}:${ACCOUNT_ID}:session" >> "${OUTPUT_FILE}"
# VPC Public Access Block
aws ec2 describe-account-attributes --region ${REGION} --attribute-names vpc-max-security-groups-per-interface --query 'AccountAttributes[*].AttributeValues[*].AttributeValue' --output text > /dev/null 2>&1 && echo "arn:aws:ec2:${REGION}:${ACCOUNT_ID}:vpc-public-access-block" >> "${OUTPUT_FILE}"
# CodeBuild Projects
aws codebuild list-projects --region ${REGION} --query 'projects[*]' --output text | \
tr '\t' '\n' | \
sed "s/^/arn:aws:codebuild:${REGION}:${ACCOUNT_ID}:project\//" >> "${OUTPUT_FILE}"
# CodeCommit Repositories
aws codecommit list-repositories --region ${REGION} --query 'repositories[*].repositoryArn' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# CloudFront Distributions
aws cloudfront list-distributions --query 'DistributionList.Items[*].ARN' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# Route 53 Hosted Zones
aws route53 list-hosted-zones --query 'HostedZones[*].Id' --output text | tr '\t' '\n' | sed 's/\/hostedzone\///' | sed "s/^/arn:aws:route53:::hostedzone\//" >> "${OUTPUT_FILE}"
# ACM Certificates
aws acm list-certificates --region ${REGION} --query 'CertificateSummaryList[*].CertificateArn' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# KMS Keys
aws kms list-aliases --region ${REGION} --query 'Aliases[*].TargetKeyId' --output text | tr '\t' '\n' | sed "s/^/arn:aws:kms:${REGION}:${ACCOUNT_ID}:key\//" >> "${OUTPUT_FILE}"
# Secrets Manager
aws secretsmanager list-secrets --region ${REGION} --query 'SecretList[*].ARN' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# WAF v2 Web ACLs
aws wafv2 list-web-acls --scope REGIONAL --region ${REGION} --query 'WebACLs[*].ARN' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# WAF v2 IP Sets
aws wafv2 list-ip-sets --scope REGIONAL --region ${REGION} --query 'IPSets[*].ARN' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# WAF v2 Regex Pattern Sets
aws wafv2 list-regex-pattern-sets --scope REGIONAL --region ${REGION} --query 'RegexPatternSets[*].ARN' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# CloudWatch Alarms
aws cloudwatch describe-alarms --region ${REGION} --query 'MetricAlarms[*].AlarmArn' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# SNS Topics
aws sns list-topics --region ${REGION} --query 'Topics[*].TopicArn' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
# SQS Queues
aws sqs list-queues --region ${REGION} --query 'QueueUrls[]' --output text | tr '\t' '\n' | sed "s/^https:\/\/sqs.${REGION}.amazonaws.com\/${ACCOUNT_ID}\//arn:aws:sqs:${REGION}:${ACCOUNT_ID}:/" >> "${OUTPUT_FILE}"
# "None" を削除
echo "Removing 'None' entries..."
grep -v "^None$" "${OUTPUT_FILE}" > "${OUTPUT_FILE}.tmp" && mv "${OUTPUT_FILE}.tmp" "${OUTPUT_FILE}"
# ソートして重複を削除 (必要に応じて)
# sort -u "${OUTPUT_FILE}" -o "${OUTPUT_FILE}"
echo "Complete! Results have been saved to: ${OUTPUT_FILE}"
- AWS CLI のサービスごとのリソース一覧取得コマンドを実行しています。
- 取得対象のサービスおよびリソースに対応するコマンドは適宜追加する必要があります。
- 取得結果を単一のファイルに追記出力しています。
- AWS CLI の
--query
オプションにより、リソース ID のみを取得しています。 - AWS CLI の
--output text
オプションによりタグ区切り出力されるリソース ID に対して、tr '\t' '\n'
で改行区切りに変換しています。 - リソース種類によっては Arn が取得できないので、
sed
で Arn 形式に変換しています。 - ページネーションは未考慮のため、出力数が多いリソースは個別にコマンドを実行して全数取得する必要があります。
- 複数リージョンに対してスクリプトを実行した場合は、グローバルなサービス(IAM、S3 など)が重複して出力されるため、必要に応じて削除してください。
動作確認
スクリプトを実行します。
$ sh list_aws_resources.sh
Fetching AWS resources in ap-northeast-1 (Account: XXXXXXXXXXXX)...
Removing 'None' entries...
Complete! Results have been saved to: aws_resources_XXXXXXXXXXXX_ap-northeast-1_20250324_232149.txt
ファイルにリソースの Arn 一覧が出力されました。
arn:aws:apigateway:ap-northeast-1:/restapis/d89oz0jjo3
arn:aws:apigateway:ap-northeast-1:/restapis/dtca6l6op8
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/Main/01ab87c0-03e8-11f0-9141-0ea4b6a23d7f
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/IAM-User-CM-Wakatsuki-Ryuta/f77c68c0-ea9f-11ef-a8ec-0aab0e5be0e7
...
arn:aws:kms:ap-northeast-1:XXXXXXXXXXXX:key/4d98a9e6-5970-48bc-84c9-8e3cb4482954
arn:aws:wafv2:ap-northeast-1:XXXXXXXXXXXX:regional/webacl/ApiBackendWafWebAcl5781-2JpyE7MI9hGG/0cbe573b-d140-4622-ac95-9577d7c6f215
arn:aws:wafv2:ap-northeast-1:XXXXXXXXXXXX:regional/webacl/ApiBackendWafWebAcl5781-I2oLosUtdWgs/ccb67f67-9191-4d0e-a544-64b3ca39be75
arn:aws:sns:ap-northeast-1:XXXXXXXXXXXX:SecurityHubNotificationTopicC3B5529F-eXeqnqOOgLEo
arn:aws:sqs:ap-northeast-1:XXXXXXXXXXXX:MyQueue
生成 AI を活用したコマンドの追加運用
スクリプトに新しいサービス/リソース種類一覧取得コマンドを追加したい場合は、生成 AI チャットで次のように質問します。
```
list_aws_resources.sh スクリプトの内容(省略)
```
上記スクリプトに RDS インスタンス一覧取得処理を追加して
すると次のようにコマンドを生成してくれます。コマンドを個別に実行して動作が問題無ければ、スクリプトに追加します。
RDS インスタンス一覧を取得する処理を追加します。以下のコードを、スクリプトの適切な位置(例えば SQS Queues の処理の後)に追加してください:
```bash
# RDS Instances
aws rds describe-db-instances --region ${REGION} --query 'DBInstances[*].DBInstanceArn' --output text | tr '\t' '\n' >> "${OUTPUT_FILE}"
```
このコードは以下のことを行います:
1. `aws rds describe-db-instances` コマンドを使用して RDS インスタンスの一覧を取得
2. `--query 'DBInstances[*].DBInstanceArn'` で各インスタンスの ARN を抽出
3. `--output text` でテキスト形式で出力
4. `tr '\t' '\n'` で タブ区切りを改行に変換
5. 結果を出力ファイルに追加
RDS の ARN は自動的に正しい形式(arn:aws:rds:region:account-id:db:instance-name)で返されるため、追加の整形は必要ありません。
このようにある程度スクリプトが育てば、その後の追加運用は生成 AI を活用して楽に行うことができます。
おわりに
AWS CLI でリソース一覧を取得するスクリプトを作成してみたのでご紹介しました。どなたかの参考になれば幸いです。
以上