はじめに
今回、Lambda@Edge で利用する Lambda 関数を用意する必要があったのでそのコードを ChatGPT に書いてもらうことにしました。
構成イメージ
今回は CloudFront + S3 という一般的な構成をベースに導入します。
また、ベースの構成はすでに用意済みの状態で、そこに Lambda@Edge を追加する内容となります。
要件
CloudFront の場合だとデフォルトルートは index.html
の補完を設定することができますが、
その他のパスでは補完がされません。
通常
○ https://cloudfronturl/ → https://cloudfronturl/index.html
× https://cloudfronturl/test/ → https://cloudfronturl/test/index.html
今回はそう言った場合で index.html
を補完するLambda@Edge を導入します。
Lambda@Edge 導入
○ https://cloudfronturl/ → https://cloudfronturl/index.html
○ https://cloudfronturl/test/ → https://cloudfronturl/test/index.html
こんな感じです。
導入
以下、ChatGPT との全文になります。読んでいただくとわかりますがただ質問してるだけです。
質問(1回目)
cloudfrontでデフォルトルート以外のパス配下でindex.htmlがなくてもindex.htmlを見るようなlambda@edgeのコードを教えてください。
言語はpythonでお願いします。
ChatGPT レスポンス(1回目)
以下は、CloudFrontでデフォルトルート以外のパス配下でも
index.html
をデフォルトで表示するLambda@Edgeのコード例です。言語はPythonです。このコードは、リクエストされたパスがファイルで終わっていない場合、そのパスに
index.html
を追加して、リクエストをリダイレクトする役割を果たします。import re from urllib.parse import urlparse def lambda_handler(event, context): request = event['Records'][0]['cf']['request'] uri = request['uri'] # パスの末尾がスラッシュで終わるか、またはファイル拡張子がない場合 if uri.endswith('/') or not re.search(r'\.\w+$', uri): # `index.html`をパスに追加 request['uri'] = re.sub(r'/$', '', uri) + '/index.html' return request
説明:
- re.search(r'.\w+$', uri): URIにファイル拡張子が含まれているかどうかをチェックします。含まれていない場合は、ディレクトリと見なされます。
- re.sub(r'/$', '', uri): パスの末尾のスラッシュを削除します。
利用方法:
- Lambda関数を作成し、このコードをペーストします。
- CloudFrontディストリビューションのビヘイビアで、
Origin Request
またはViewer Request
トリガーにこのLambda@Edge関数を関連付けます。これにより、ユーザーがCloudFrontを介してアクセスする際に、デフォルトルート以外のパスでも
index.html
をデフォルトで表示することができます。
python コードだけでなく説明や利用方法まで教えてくれました。
ただ、今回は re
モジュールがデフォルトでサポートされているのかが気になりました。
質問(2回目)
ということで聞いてみます。
reはlambdaのデフォルトでサポートされてますか?
ChatGPT レスポンス(2回目)
いいえ、Lambda@Edgeの環境では標準ライブラリの
re
(正規表現モジュール)はデフォルトでサポートされています。したがって、re
モジュールをインポートして使用することができます。ただし、Lambda@Edgeでは特定のライブラリがサポートされていないことがあるため、外部のパッケージが必要な場合は注意が必要です。しかし、
re
モジュールはPythonの標準ライブラリの一部なので、特別な設定なしに利用可能です。もし正規表現を使用したくない場合は、URIのチェックを別の方法で行うことも可能です。
「いいえ」と言いつつ「サポートされています」という返事です。その後の内容を読んでも結局サポートされているのかがよく分かりません。
質問(3回目)
ということで改めて質問してみます。
lambdaではサポートされていないけど、lambda@edgeではサポートされているということですか?
ChatGPT レスポンス(3回目)
re
モジュールは、Pythonの標準ライブラリの一部であり、LambdaとLambda@Edgeの両方でサポートされています。したがって、Lambda@Edge専用でサポートされているわけではなく、どちらの環境でも利用可能です。両方の環境で標準ライブラリとして提供されているため、追加の設定やインストールなしで
re
モジュールを使うことができます。もし、Lambda関数で
re
モジュールを利用する際に問題が発生した場合は、それは別の要因が原因かもしれませんが、一般的にre
モジュールは問題なく動作するはずです。
結局サポートされているので大丈夫ということですね。
質問(4回目)
その後、マネジメントコンソールで Lambda 関数を作成し Lambda@Edge へデプロイを行おうとしたところ、以下のエラーが表示されました。
これについても聞いてみます。
以下のエラーの対応について教えてください。
関数の実行ロールは、edgelambda.amazonaws.com サービスプリンシパルによって引き受け可能である必要があります。
ChatGPT レスポンス(4回目)
このエラーは、Lambda@Edge関数に関連付けられたIAMロールが、CloudFrontでLambda@Edge関数を実行するために必要な権限を持っていないことを示しています。具体的には、IAMロールが
edgelambda.amazonaws.com
というサービスプリンシパルによって引き受けられるように設定されていないことが原因です。この問題を解決するには、以下の手順に従ってIAMロールの設定を修正します。
手順 1: IAMロールの修正
- AWSマネジメントコンソールにログインします。
- IAMコンソールに移動します。
- Lambda@Edge関数に関連付けられているIAMロールを選択します。
- 信頼関係タブをクリックします。
- ポリシードキュメントの編集をクリックし、以下の内容が含まれていることを確認または追加します。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "edgelambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
このポリシーは、
edgelambda.amazonaws.com
サービスプリンシパルに、このIAMロールを引き受ける権限を付与します。手順 2: 変更の保存
- ポリシードキュメントの変更を保存し、IAMロールを更新します。
手順 3: Lambda関数の再デプロイ
- Lambda@Edge関数を再度デプロイし、CloudFrontディストリビューションに関連付けます。
この手順を実施することで、CloudFrontでLambda@Edge関数を正常に実行できるようになります。
信頼関係で Lambda@Edge に許可されていないのが原因ということです。
また、対応手順についても答えてくれました。
質問(5回目)
無事に解決できたのですが、さっきの質問でちょっと疑問があったので追加で質問してみました。
Origin Request とViewer Request の違いは何ですか?
ChatGPT レスポンス(5回目)
Origin Request
とViewer Request
は、CloudFrontがリクエストを処理する際にトリガーされるタイミングの違いを示す用語です。それぞれの違いを理解することは、Lambda@Edge関数をどのタイミングで実行させるかを決める上で重要です。Viewer Request
- タイミング: エンドユーザー(ビューワー)からCloudFrontにリクエストが届いたときにトリガーされます。
- 用途: リクエスト内容を変更したり、ユーザーのリクエストに基づいてカスタム処理を実行する際に使用されます。例えば、認証やリクエストのリダイレクト、カスタムヘッダーの追加などができます。
- 典型的なシナリオ:
- ユーザーからのリクエストを特定の言語にリダイレクトする。
- 認証トークンの検証を行い、アクセスを許可するかを決定する。
Origin Request
- タイミング: CloudFrontがリクエストをオリジン(例えば、S3バケットやウェブサーバー)に送信する前にトリガーされます。
- 用途: オリジンに対して送信されるリクエストを変更したり、オリジンに送る前にカスタム処理を実行する際に使用されます。例えば、オリジンに送るリクエストのURIを変更したり、カスタムヘッダーを追加することができます。
- 典型的なシナリオ:
- 特定のパスのリクエストを別のオリジンにルーティングする。
- リクエストURIを変更して、動的なコンテンツを配信する。
主な違い
- Viewer Request は、ユーザーからCloudFrontにリクエストが来た瞬間に処理が開始され、リクエストがオリジンに到達する前に変更できます。
- Origin Request は、CloudFrontがリクエストをオリジンに送る直前にトリガーされ、オリジンに送信するリクエスト内容を変更することができます。
まとめ
- Viewer Request: ユーザーからのリクエストを初期処理するために使用されます。
- Origin Request: オリジンにリクエストを送る前に、リクエストを最終的に変更するために使用されます。
Lambda@Edge関数をどちらでトリガーするかは、実現したい機能によって選択します。例えば、リクエストを受けた瞬間に特定の処理を行いたい場合は
Viewer Request
を、オリジンに対してリクエストをカスタマイズしたい場合はOrigin Request
を選ぶとよいでしょう。
違いだけでなく用途など詳しく回答してくれています。
とりあえず質問は以上で終了です。
おわりに
ChatGPT を活用することで開発工数が大幅に削減できるなと感じました。
もっとプロンプトの内容がうまく書ければより効率よくコーディングなどができると思うのでもっと積極的に利用していこうと思います。