AWSアカウントのリソースを色々なところから確認してみる

Uniforceのインフラ担当のニシです。

最近はBlendyの濃厚 クリーミーカフェラテ デカフェ にハマっています。(甘い飲み物、食べ物、好き🤤)

今回はAWSアカウントにどのようなリソースが存在するのかを確認するためにいくつかの方法を試してみました。

その内容を共有したいと思います。

そもそもツールで管理はされていないのか

Uniforceでは、システムの提供基盤としてはAWSを使用しています。

AWSのリソースを管理するためのツールとしては、CloudFormation、Terraform、AWS CDKなど、様々な選択肢があります。

このように様々なツールがある中で、UniforceではフロントエンドにAWS Amplify、バックエンドにAWS SAMを使用しています。

これらのツールのConfig情報を確認すれば、AWSアカウント内にあるAWSリソースを把握することが可能です。

ですが、それらのConfig情報を確認してみると、VPCやECSなど、ツールで管理されていないものがあることがわかりましたので、

他の方法でAWSアカウントにどのようなリソースがあるのかを調べてみることにしました。

AWSアカウント内のリソースの調べ方

今回は4つの方法で調べることにしました。

  • リソースエクスプローラー
  • タグエディタ
  • AWS Config
  • 請求書

リソースエクスプローラー (断念、理由は後述)

リソースエクスプローラーの使用にあたっては、下記のブログを参考にさせていただきました。

[レポート] AWS Resource Explorer についての Chalk Talk に参加しました #reinvent #COP220 | DevelopersIO

AWS CLIでアクティブなリソース一覧を取得 - とことんDevOps | 日本仮想化技術のDevOps技術情報メディア

リソースエクスプローラーから取得するスクリプトを下記の通り作成しました。

# リソースの取得を行う関数
# 引数は、リージョン、リソースタイプ、タグ情報とファイル名の一部を受け取る
function get_resources() {
local region=$1
local resourceType=$2
local tag=$3
local filename=$4
# /を_に置換
local replaceResourceType=${resourceType//\\//_}
# AWSのCLIコマンドを作成
local AWS_CLI_COMMAND="aws resource-explorer-2 search --query-string=\\"region:${region} resourcetype:${resourceType} ${tag}\\""
local next_token=""

# リソース取得ループ
while true; do
# Throttling対策
sleep 2

# next_tokenの有無で対応を変える
if [ -z "$next_token" ]; then
local output=$(eval $AWS_CLI_COMMAND | jq 'select(.Count.TotalResources != 0)')
else
local output=$(eval $AWS_CLI_COMMAND --starting-token $next_token | jq 'select(.Count.TotalResources != 0)')
fi

# outputがあればそれをファイルに保存
if [ -n "$output" ]; then
echo "${region}_${replaceResourceType}_${filename} get resources"
echo "$output" >> ${region}_${replaceResourceType}_${filename}.json
else
echo "${region}_${replaceResourceType}_${filename} is not resource"
break
fi

# next_tokenの更新
next_token=$(echo "$output" | jq -r '.NextToken')

# next_tokenがnullならループ終了
if [ "$next_token" = "null" ]; then
break
fi
done
}

# 各リージョンに対してリソース取得
for region in $(aws resource-explorer-2 list-indexes --query 'Indexes[].Region' --output text); do
# 各リソースタイプに対する処理
for resourceType in $(aws resource-explorer-2 list-supported-resource-types --query 'ResourceTypes[].ResourceType' --output text); do
# 各envタグとタグなしに対する処理
for tag in "tag:env=prod" "tag:env=stg" "tag:env=dev" "tag:env=qa"; do
get_resources $region $resourceType $tag ${tag:8}
done
get_resources $region $resourceType "-tag:env=prod -tag:env=stg -tag:env=dev -tag:env=qa" "no_env"
done
done

# globalに対したリソース取得
for resourceType in $(aws resource-explorer-2 list-supported-resource-types --query 'ResourceTypes[].ResourceType' --output text); do
# 各envタグとタグなしに対する処理
for tag in "tag:env=prod" "tag:env=stg" "tag:env=dev" "tag:env=qa"; do
get_resources "global" $resourceType $tag ${tag:8}
done
get_resources "global" $resourceType "-tag:env=prod -tag:env=stg -tag:env=dev -tag:env=qa" "no_env"
done

echo "finished"

いざスクリプトを動作させてみると、途中でサービスの使用制限に達してしまいました。

An error occurred (ThrottlingException) when calling the Search operation (reached max retries: 2): You exceeded your quota for this account. You can try increasing your quota using the Service Quotas console.

Quotas for Resource Explorer - AWS Resource Explorer

Rate limits for operations

Default value

Maximum Search operations per second

5

Maximum non-Search operations per second

3

Maximum Search operations in aggregator Region per month

10,000

Maximum Search operations in local Regions per month

500

作成したスクリプトを実行する場合、

28,440回(18リージョン x 316 サービス x 5 タグ)の操作が必要となる計算なため、軽々と上限に到達していました。

※リージョン数などは環境によります。

AWSへ余裕を持った数値で上限緩和を依頼してみましたが、緩和することが難しかったため、今回はリソースエクスプローラーによる方法を断念しました。

タグエディタ

タグエディタの使用にあたっては下記ブログを参考にさせていただきました。

特定のタグが付いた AWS のリソース一覧を取得する方法を教えてください | DevelopersIO

タグエディタから取得するスクリプトを下記の通り作成しました。


for region in `aws ec2 describe-regions --query 'Regions[].RegionName' --region us-west-1 --output text`
do
AWS_CLI_COMMAND="aws resourcegroupstaggingapi get-resources --region ${region}"
next_token=""

while true; do
if [ -z "$next_token" ]; then
echo "NextToken is blank"
output=$($AWS_CLI_COMMAND | jq 'select(.ResourceTagMappingList | length > 0)')
else
echo "NextToken is not blank"
output=$($AWS_CLI_COMMAND --starting-token $next_token | jq 'select(.ResourceTagMappingList | length > 0)')
echo $output
fi

if [ -n "$output" ]; then
echo "${region} get resources"
echo "$output" >> ${region}.json
else
echo "${region} is not resource"
break
fi

next_token=$(echo "$output" | jq -r '.PaginationToken')

if [ "$next_token" = "null" ]; then
echo "NextToken is null"
break
else
echo "token is $next_token"
fi

done

done

echo "finished"

スクリプトから得られた結果により、AWSリソースとそのタグ情報を取得することができました。

また、どのリージョンが使用されているのかも掴むことができました。

さらに、下記のコマンドでタグの付き方を調べてみると、

フロントエンドとバックエンドで使用しているタグが違うことも見えてきましたので、タグ設計も整えてみると良いかもと思いました。

cat ap-northeast-1.json \\
| jq -r '.ResourceTagMappingList[].Tags[] | [.Key, .Value] | @csv' \\
| sort \\
| uniq \\
| grep -v -e "**cloudformation**" -e "aws:**" -e "ecs:**" \\
> tag_user_custom_ap-northeast-1.csv

AWS Config

AWS Configの使用にあたっては下記ブログを参考にさせていただきました。

AWSのリソース情報を設定情報含めてCLIで一括取得する

ブログに掲載されているコマンドそのままでAWS Configから設定情報を取得することができました。

ファイルサイズが0のものもあったため、find . -size 0 -delete で余分なファイルは削除しました。

請求書

AWSのマネジメントコンソールにサインインし、「請求とコスト管理」>「請求書」から月々にかかっているAWSのコストを確認できます。

コストからもどのようなAWSのサービスを使っているのかを知り手がかりとなります。

また、AWS Marketplaceで購入しているものがないのかの確認にも使えます。

Uniforceの環境でいうと、Amazon Connectを使用していることがわかりました。

まとめ

今回はAWSアカウント内のリソースを調べる方法として、4つのアプローチから試みてみました。

  • リソースエクスプローラー
  • タグエディタ
  • AWS Config
  • 請求書

残念ながら、リソースエクスプローラーについては、サービスの上限により途中で断念することになりましたが、

これら4つの方法を用いることでAWSアカウント内のリソースを解明するための手がかりを得られることがわかりました。

本日の記事はここまでとなります。

最後まで読んでいただきありがとうございました🙌