特定のLambda@Edgeが使われているCloudFrontのURLをAWS CLIで抽出してみた
クラウド事業本部の梶原@シン福岡オフィスです。
AWS Lambda の Python 3.9 のサポート終了がアナウンスされ更新対応していたのですが、Lambda@Edgeでいくつか実装しているものがあり
影響範囲を確認するため、Lambda@EdgeがどのCloudFrontのビヘイビアに紐づいているかコンソールで一つずつ見てい。。。
やってられるか!
ということで、AWS CLIを使ったスクリプトでまとめて抽出できるようにしてみました。
今回は、特定のLambda@EdgeのARNを指定して、関連するCloudFrontのURLを出力するスクリプトを作成したので、共有します。
尚、スクリプトの生成には生成AIを使用しています。動作検証は十分に行っていますがすべての環境での動作を保証するものではありませんので、ご容赦ください。
環境前提
- AWS CLIがインストールされていて、適切な権限が設定されていること。
- jqがインストールされていること(なければ
brew install jq
など,CloudShell にはインストール済みです)。 - Lambda@EdgeのARNを準備(例:
arn:aws:lambda:us-east-1:123456789012:function:my-function:1
)。
スクリプトの使い方
スクリプトをlist_lambda_urls.sh
として保存し、実行権限を付与します。
AWS CloudShellでの動作を確認しています。CloudFrontの読み取り権限のあるユーザーでログイン、また起動してください。
chmod +x list_lambda_urls.sh
./list_lambda_urls.sh <Lambda@EdgeのARN> [debug]
<Lambda@EdgeのARN>
: 対象のARNを指定。[debug]
: 指定するとJSONをdistributions.json
に保存してデバッグしやすくなります。
出力例:
Distribution ID: EXXXXXXXXXXXXX
Domain Name: dxxxxxxxxxxxxxx.cloudfront.net
Alias: example.com
Effective Domain: example.com
Default Behavior URL: https://example.com/
Cache Behavior URLs:
URL: https://example.com/images/*
---
これで関連するURLが分かります。
1つのLabmda関数が、複数のCloudFrontdディストリビューションに割り当てられている場合でも、複数ディストリビューションが出力されます。
一括抽出したあとに処理を行っているため、ディストリビューションが100を超えるような環境はうごかないかもしれません。適切なページ処理などを実装ください
スクリプト全文
以下にスクリプトを記載します。コピーして使ってみてください。
#!/bin/bash
# スクリプトの使用方法: ./script.sh <Lambda@Edge のARN> [debug]
# 例: ./script.sh arn:aws:lambda:us-east-1:123456789012:function:my-function:1 debug
# debug を指定すると、生のJSONを distributions.json に保存します。
# 前提: AWS CLI がインストールされ、適切な権限が設定されていること。また、jq がインストールされていること。
LAMBDA_ARN="$1"
DEBUG="$2"
if [ -z "$LAMBDA_ARN" ]; then
echo "Usage: $0 <LAMBDA_ARN> [debug]"
exit 1
fi
if ! command -v jq >/dev/null 2>&1; then
echo "Error: jq is required but not installed. Install jq to run this script."
exit 1
fi
# CloudFront ディストリビューションのリストを取得
DISTRIBUTIONS=$(aws cloudfront list-distributions --output json 2>/dev/null)
if [ $? -ne 0 ]; then
echo "Error: Failed to execute 'aws cloudfront list-distributions'. Check AWS CLI configuration and permissions."
exit 1
fi
# デバッグモードで生JSONを保存
if [ "$DEBUG" = "debug" ]; then
echo "$DISTRIBUTIONS" > distributions.json
echo "Debug: Raw JSON saved to distributions.json"
fi
# ディストリビューションが存在するかチェック
if [ -z "$DISTRIBUTIONS" ] || [ "$(echo "$DISTRIBUTIONS" | jq 'if .DistributionList.Items then .DistributionList.Items | length else 0 end')" == "0" ]; then
echo "No CloudFront distributions found."
exit 0
fi
# jq でディストリビューションを解析し、Lambda@Edge の関連を抽出(出力形式をURLベースに変更、EventTypeとIncludeBodyを削除)
echo "$DISTRIBUTIONS" | jq -r --arg arn "$LAMBDA_ARN" '
(if .DistributionList.Items then .DistributionList.Items else [] end) |
.[] |
{
Id: .Id,
DomainName: .DomainName,
Alias: (if .Aliases.Items[0] then .Aliases.Items[0] else "None" end),
EffectiveDomain: (if .Aliases.Items[0] then .Aliases.Items[0] else .DomainName end),
Default: (
(if .DefaultCacheBehavior.LambdaFunctionAssociations.Items then .DefaultCacheBehavior.LambdaFunctionAssociations.Items else [] end) |
[.[] | select(.LambdaFunctionARN == $arn)]
),
Behaviors: (
(if .CacheBehaviors.Items then .CacheBehaviors.Items else [] end) |
[.[] | {
Path: (if .PathPattern then .PathPattern else "None" end),
Associations: (
(if .LambdaFunctionAssociations.Items then .LambdaFunctionAssociations.Items else [] end) |
[.[] | select(.LambdaFunctionARN == $arn)]
)
} | select(.Associations != [])]
)
} |
select(.Default != [] or .Behaviors != []) |
( .EffectiveDomain as $eff |
"Distribution ID: \(.Id)\nDomain Name: \(.DomainName)\nAlias: \(.Alias)\nEffective Domain: \(.EffectiveDomain)\n" +
(if .Default != [] then
"Default Behavior URL: https://\($eff)/\n"
else
""
end) +
(if .Behaviors != [] then
"Cache Behavior URLs:\n" + (.Behaviors | map(" URL: https://\($eff)/\(.Path)") | join("\n"))
else
""
end) + "\n---"
)
'
# 出力がない場合のメッセージ
if [ $? -ne 0 ]; then
echo "Error: jq failed to process the data. Check distributions.json for issues if debug mode was used."
else
if [ -z "$(echo "$DISTRIBUTIONS" | jq -r --arg arn "$LAMBDA_ARN" '(if .DistributionList.Items then .DistributionList.Items else [] end) | .[] | select(((if .DefaultCacheBehavior.LambdaFunctionAssociations.Items then .DefaultCacheBehavior.LambdaFunctionAssociations.Items else [] end)[]?.LambdaFunctionARN == $arn) or ((if .CacheBehaviors.Items then .CacheBehaviors.Items else [] end)[]? | (if .LambdaFunctionAssociations.Items then .LambdaFunctionAssociations.Items else [] end)[]?.LambdaFunctionARN == $arn))')" ]; then
echo "No behaviors found associated with Lambda ARN: $LAMBDA_ARN"
fi
fi
スクリプトのポイント
- AWS CLIで
list-distributions
を実行してデータを取得。 - jqでARNにマッチするビヘイビアをフィルタリングし、Alias優先でURLを作成。
- デバッグモードで生JSONを保存しています。
- ディストリビューション数が多く取得できてないなと思う場合はこちらを確認してください
- ディストリビューションが多い環境では、実行時間がかかる場合があります。
まとめ
このスクリプトで、Lambda@Edgeの関連URLを一覧で確認できます。必要に応じてカスタマイズしてみてください。
Pythonの更新の際の影響確認に使いましたが、Lambdaの実行環境には依存しておらず、必要なのはARNだけなので、他のLambda@Edgeの更新時にも使用可能です。
参考情報
Lambda ランタイム