deploying-custom-domain-rest-api について
カスタムドメインと Lambda リクエストオーソライザーを備えた AWS API Gateway REST API のデプロイ用スキルです。リージョナルエンドポイント、証明書、DNS、ステージマッピングを扱い、プライベートエンドポイントは対象外です。
主な機能
- 01リージョナル REST API と Lambda バックエンドの作成
- 02リクエスト型 Lambda オーソライザーの設定
- 03ACM 証明書と TLS 1.2 の構成
- 04カスタムドメインとステージマッピングの設定
- 05Route 53 エイリアスレコードの作成
活用シーン
- 01GET /example に認証付き API をデプロイ
- 02API にカスタムドメインと HTTPS を設定
- 03Route 53 でドメインを API Gateway に接続
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ aws/ agent-toolkit-for-aws --skill deploying-custom-domain-rest-apiインストール後、Claude Code で/deploying-custom-domain-rest-apiを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
scripts/authorizer.mjsdns-record.jsonexample_function.mjslambda-trust-policy.jsonvalidate.sh詳細
Lambda とリクエストオーソライザーを使用したカスタムドメイン REST API
概要
この SOP では、リージョナルカスタムドメイン名、Lambda バックエンド関数、リクエストベースの Lambda オーソライザーを使用して REST API をデプロイします。ACM 証明書のプロビジョニング、IAM ロールの作成、Lambda 関数のデプロイ、カスタムオーソライザーを使用した API Gateway REST API の作成、カスタムドメインの設定、ベースパスマッピング、Route 53 の DNS 設定を行います。
アーキテクチャには、次のものが含まれます。
- エンドポイントタイプが REGIONAL の API Gateway REST API
- ヘッダー、クエリ文字列パラメーター、ステージ変数を検証するリクエストベースの Lambda オーソライザー
GET /exampleの Lambda バックエンド関数- TLS 1.2 を使用するカスタムドメイン名
- カスタムドメインを API ステージに接続するベースパスマッピング
- カスタムドメインを API Gateway のリージョナルエンドポイントに向ける Route 53 の A エイリアスレコード
重要:この SOP ではリージョナルエンドポイントを使用します。ユーザーからプライベートエンドポイントをリクエストされた場合は、このスキルが対象とするのはリージョナルエンドポイントのみであることを伝えてください。プライベートエンドポイントには VPC エンドポイントの設定が必要です。
パラメーター
- custom_domain_name(必須):API の完全修飾ドメイン名(例:
api.example.com) - region(必須):すべてのリソースで使用する AWS リージョン。リージョナルエンドポイントの場合、ACM 証明書は同じリージョンにある必要があります
- hosted_zone_id(必須):ドメインの Route 53 ホストゾーン ID
- acm_certificate_arn(任意):カスタムドメインをカバーする既存の ACM 証明書の ARN。指定されていない場合、ステップ 2 で作成します
- stage_name(任意、デフォルト:"dev"):API Gateway のステージ名
パラメーター取得時の制約:
- 必須パラメーターは、1 つずつではなく、1 回のプロンプトですべてまとめて確認する必要があります
- 複数の入力方法(直接入力、ファイルパス、URL)に対応する必要があります
- すべてのパラメーターを正常に取得したことを確認してから、次に進む必要があります
- このスキルでは、本番環境での使用には適さないハードコードされたデモ用認証値(headerValue1、queryValue1、stageValue1)を使用することをユーザーに伝える必要があります。本番環境では、AWS Secrets Manager または Systems Manager Parameter Store を使用して認証情報を管理してください。詳細:https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html
- custom_domain_name が有効な FQDN であることを検証する必要があります
手順
0. 依存関係の確認
制約:
- 次のツールが利用可能であることを確認する必要があります:aws-cli、python3、sed、node(v22 以降)
- 不足しているツールがある場合は、明確なメッセージでユーザーに伝える必要があります
- ツールが不足していても続行するか、ユーザーに確認する必要があります
- いつでも中止したいというお客様の判断を尊重する必要があります
- どのステップを実行するのか、その理由、および呼び出すツールをお客様に説明する必要があります
1. AWS アカウント ID の取得
このステップは、他のすべてのステップより先に実行する必要があります。
制約:
- 次のコマンドでアカウント ID を取得する必要があります:
aws sts get-caller-identity --query 'Account' --output text - 結果を {account_id} として保存し、後続のステップで {account_id} を参照する際に再利用する必要があります
- 認証情報が設定されていない場合は中止する必要があります
2. ACM 証明書をリクエストする
acm_certificate_arn がすでに指定されている場合は、この手順をスキップしてください。
制約:
- 次のコマンドで証明書をリクエストする必要があります:
aws acm request-certificate --domain-name {custom_domain_name} --validation-method DNS --region {region} - レスポンスから CertificateArn を取得する必要があります
- 次のコマンドで DNS 検証レコードを取得する必要があります:
aws acm describe-certificate --certificate-arn {cert_arn} --query 'Certificate.DomainValidationOptions[0].ResourceRecord' --region {region} - 次のコマンドで Route 53 に検証用 CNAME を作成する必要があります:
aws route53 change-resource-record-sets --hosted-zone-id {hosted_zone_id} --change-batch '{"Changes":[{"Action":"UPSERT","ResourceRecordSet":{"Name":"{validation_name}","Type":"CNAME","TTL":300,"ResourceRecords":[{"Value":"{validation_value}"}]}}]}' - 次のコマンドで証明書の検証完了を待つ必要があります:
aws acm wait certificate-validated --certificate-arn {cert_arn} --region {region} - 待機コマンドには最大 30 分かかる場合があります。タイムアウトした場合は、次のコマンドでステータスを手動で確認し、ステータスがまだ PENDING_VALIDATION であれば待機コマンドを再実行してください:
aws acm describe-certificate --certificate-arn {cert_arn} --query 'Certificate.Status' --region {region} - 証明書のステータスが ISSUED になるまで、次の手順に進んではいけません
- 手順 7 で使用するため、証明書 ARN を acm_certificate_arn として保存する必要があります
3. IAM 実行ロールを作成する
制約:
- IAM ロールを 2 つ作成する必要があります。1 つはオーソライザー Lambda 用、もう 1 つはサンプル関数 Lambda 用です
- どちらのロールにも、
scripts/lambda-trust-policy.jsonの同じ信頼ポリシーを使用します。この信頼ポリシーには、ユーザーのアカウント ID に範囲を限定したaws:SourceAccount条件が含まれています - 信頼ポリシーの作業用コピーを作成し、
ACCOUNT_IDプレースホルダーを手順 1 で取得した実際のアカウント ID に置き換える必要があります。次を使用してください:sed 's/ACCOUNT_ID/{account_id}/' scripts/lambda-trust-policy.json > /tmp/lambda-trust-policy.json - 次のコマンドでオーソライザーロールを作成する必要があります:
aws iam create-role --role-name request-authorizer-role --assume-role-policy-document file:///tmp/lambda-trust-policy.json - 次のコマンドでオーソライザーロールに基本実行ポリシーをアタッチする必要があります:
aws iam attach-role-policy --role-name request-authorizer-role --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - 次のコマンドでサンプル関数ロールを作成する必要があります:
aws iam create-role --role-name example-function-role --assume-role-policy-document file:///tmp/lambda-trust-policy.json - 次のコマンドでサンプル関数ロールに基本実行ポリシーをアタッチする必要があります:
aws iam attach-role-policy --role-name example-function-role --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole - 手順 4 で使用するため、それぞれの create-role レスポンスからロール ARN を取得する必要があります
- IAM ロールの反映は最終的に整合するため、ロールを作成してから Lambda 関数を作成するまでに、少なくとも 10 秒待つ必要があります
4. Lambda 関数を作成してデプロイする
制約:
- リクエストオーソライザーとサンプル関数の 2 つの Lambda 関数を必ず作成してください
- オーソライザー関数について:
- インラインコードを使用して関数を必ず作成してください。まずコードをファイルに書き込み、パッケージ化します:
python3 -c "import zipfile,io,base64; z=io.BytesIO(); f=zipfile.ZipFile(z,'w'); f.writestr('index.mjs', open('scripts/authorizer.mjs').read()); f.close(); open('/tmp/authorizer.zip','wb').write(z.getvalue())" - 次に、以下のコマンドで関数を作成します:
aws lambda create-function --function-name request-authorizer --runtime nodejs22.x --handler index.handler --role {authorizer_role_arn} --zip-file fileb:///tmp/authorizer.zip --timeout 10 --region {region}
- インラインコードを使用して関数を必ず作成してください。まずコードをファイルに書き込み、パッケージ化します:
- サンプル関数について:
- インラインコードを使用して関数を必ず作成してください。まずコードをファイルに書き込み、パッケージ化します:
python3 -c "import zipfile,io; z=io.BytesIO(); f=zipfile.ZipFile(z,'w'); f.writestr('index.mjs', open('scripts/example_function.mjs').read()); f.close(); open('/tmp/example_function.zip','wb').write(z.getvalue())" - 次に、以下のコマンドで関数を作成します:
aws lambda create-function --function-name example-function --runtime nodejs22.x --handler index.handler --role {example_role_arn} --zip-file fileb:///tmp/example_function.zip --timeout 10 --region {region}
- インラインコードを使用して関数を必ず作成してください。まずコードをファイルに書き込み、パッケージ化します:
- 以下を呼び出して、各関数が作成されたことを必ず確認してください:
aws lambda get-function --function-name {function_name} --region {region}
5. リクエストオーソライザーを使用して REST API を作成する
制約:
- 次のコマンドを使用して REST API を作成する必要があります:
aws apigateway create-rest-api --name custom-domain-api --endpoint-configuration types=REGIONAL --region {region} - API ID を取得し、次のコマンドでルートリソース ID を取得する必要があります:
aws apigateway get-resources --rest-api-id {api_id} --region {region} - 次のコマンドを使用して、リクエストベースの Lambda オーソライザーを作成する必要があります:
aws apigateway create-authorizer --rest-api-id {api_id} --name request-authorizer --type REQUEST --authorizer-uri 'arn:aws:apigateway:{region}:lambda:path/2015-03-31/functions/arn:aws:lambda:{region}:{account_id}:function:request-authorizer/invocations' --identity-source 'method.request.header.HeaderAuth1,method.request.querystring.QueryString1,context.stage' --region {region} - レスポンスからオーソライザー ID を取得する必要があります
- 次のコマンドを使用して、API Gateway にオーソライザーの呼び出しを許可する必要があります:
aws lambda add-permission --function-name request-authorizer --statement-id apigateway-auth-invoke --action lambda:InvokeFunction --principal apigateway.amazonaws.com --source-arn 'arn:aws:execute-api:{region}:{account_id}:{api_id}/authorizers/{authorizer_id}' --region {region} - 次のコマンドを使用して
/exampleリソースを作成する必要があります:aws apigateway create-resource --rest-api-id {api_id} --parent-id {root_resource_id} --path-part example --region {region} - 次のコマンドを使用して GET メソッドを作成する必要があります:
aws apigateway put-method --rest-api-id {api_id} --resource-id {example_resource_id} --http-method GET --authorization-type CUSTOM --authorizer-id {authorizer_id} --region {region} - 次のコマンドを使用して Lambda プロキシ統合を作成する必要があります:
aws apigateway put-integration --rest-api-id {api_id} --resource-id {example_resource_id} --http-method GET --type AWS_PROXY --integration-http-method POST --uri 'arn:aws:apigateway:{region}:lambda:path/2015-03-31/functions/arn:aws:lambda:{region}:{account_id}:function:example-function/invocations' --region {region} - 次のコマンドを使用して、API Gateway に example 関数の呼び出しを許可する必要があります:
aws lambda add-permission --function-name example-function --statement-id apigateway-invoke --action lambda:InvokeFunction --principal apigateway.amazonaws.com --source-arn 'arn:aws:execute-api:{region}:{account_id}:{api_id}/*/GET/example' --region {region} - すべてのリソース、メソッド、統合を設定するまで、デプロイを作成してはなりません
- QueryString1 と HeaderAuth1 が想定されるパターンに一致することを検証し、サイズ制限を適用して、不正なクエリパラメーターとヘッダーを拒否するよう、リクエスト検証を設定する必要があります
6. API をデプロイする
制約:
- 次のコマンドを使用してデプロイを作成する必要があります:
aws apigateway create-deployment --rest-api-id {api_id} --stage-name {stage_name} --region {region} - 次のコマンドを使用して、オーソライザーに必要なステージ変数を設定する必要があります:
aws apigateway update-stage --rest-api-id {api_id} --stage-name {stage_name} --patch-operations op=replace,path=/variables/StageVar1,value=stageValue1 --region {region} - 次のコマンドを実行してデプロイとステージ変数を検証し、variables に StageVar1 が含まれていることを確認する必要があります:
aws apigateway get-stage --rest-api-id {api_id} --stage-name {stage_name} --region {region} - ステージでアクセスログを有効にする必要があります。まず、ロググループを作成します:
aws logs create-log-group --log-group-name api-gw-access-logs --region {region}。次に、以下の形式でログを有効にします:aws apigateway update-stage --rest-api-id {api_id} --stage-name {stage_name} --patch-operations op=replace,path=/accessLogSettings/destinationArn,value=arn:aws:logs:{region}:{account_id}:log-group:api-gw-access-logs op=replace,path=/accessLogSettings/format,value='{"requestId":"$context.requestId","ip":"$context.identity.sourceIp","requestTime":"$context.requestTime","httpMethod":"$context.httpMethod","resourcePath":"$context.resourcePath","status":"$context.status"}' --region {region}
7. カスタムドメインとベースパスマッピングの作成
制約:
- カスタムドメインは、必ず次のコマンドで作成してください:
aws apigateway create-domain-name --domain-name {custom_domain_name} --regional-certificate-arn {acm_certificate_arn} --endpoint-configuration types=REGIONAL --security-policy TLS_1_2 --region {region} - ステップ 8 で使用するため、応答から regionalDomainName と regionalHostedZoneId を必ず取得してください
- ベースパスマッピングは、必ず次のコマンドで作成してください:
aws apigateway create-base-path-mapping --domain-name {custom_domain_name} --rest-api-id {api_id} --stage {stage_name} --base-path '(none)' --region {region} - 次を呼び出して、ドメインが作成されたことを必ず確認してください:
aws apigateway get-domain-name --domain-name {custom_domain_name} --region {region} - セキュリティポリシーを TLS_1_2 未満に下げてはいけません
8. Route 53 DNS レコードの作成
制約:
- プレースホルダーを置き換えて、必ず
scripts/dns-record.jsonの作業用コピーを作成してください:sed -e 's/CUSTOM_DOMAIN_NAME/{custom_domain_name}/' -e 's/REGIONAL_DOMAIN_NAME/{regional_domain_name}/' -e 's/REGIONAL_HOSTED_ZONE_ID/{regional_hosted_zone_id}/' scripts/dns-record.json > /tmp/dns-record.json - コマンドは次のとおりです:
aws route53 change-resource-record-sets --hosted-zone-id {hosted_zone_id} --change-batch file:///tmp/dns-record.json - AliasTarget には、ユーザーのホストゾーン ID ではなく、ステップ 7 で取得した regionalDomainName と regionalHostedZoneId を必ず使用してください
- DNS プロバイダーとして Route 53 を使用する場合は、必ず A エイリアスレコードを使用してください(CNAME は使用しないでください)
- DNS の伝播には最大 48 時間かかる場合があることをユーザーに伝えることを推奨します
9. 最終セットアップの検証
制約:
- すべてのリソースを確認するために、
scripts/validate.sh {custom_domain_name} {api_id} {region}を実行することを推奨します - 次のコマンドでテストするよう、ユーザーに必ず伝えてください:
curl 'https://{custom_domain_name}/example?QueryString1=queryValue1' -H 'HeaderAuth1: headerValue1' - 期待される応答は、
{"message": "Hello from the example function!"}を含む 200 であることを必ず説明してください - 正しい HeaderAuth1 ヘッダーまたは QueryString1 クエリパラメーターがないリクエストは、オーソライザーによって拒否されることを必ず説明してください
- 作成したすべてのリソースの概要を必ず提示してください。以下を含めます:
- ACM 証明書 ARN
- IAM ロール ARN
- Lambda 関数 ARN
- REST API ID とステージ名
- オーソライザー ID
- カスタムドメイン名と Regional domain name
- Route 53 DNS レコード
例
入力例
custom_domain_name: api.example.com
region: us-east-2
hosted_zone_id: Z2OJLYMUO9EFXC
stage_name: prod
出力例
ACM certificate issued for api.example.com
ARN: arn:aws:acm:us-east-2:123456789012:certificate/abc-123
IAM roles created
Authorizer: arn:aws:iam::123456789012:role/request-authorizer-role
Example: arn:aws:iam::123456789012:role/example-function-role
Lambda functions deployed
Authorizer: arn:aws:lambda:us-east-2:123456789012:function:request-authorizer
Example: arn:aws:lambda:us-east-2:123456789012:function:example-function
REST API deployed
API ID: a1b2c3d4e5
Stage: prod (StageVar1=stageValue1)
Authorizer: request-authorizer (REQUEST type)
Custom domain configured
Domain: api.example.com
Regional endpoint: d-abc123.execute-api.us-east-2.amazonaws.com
TLS: 1.2
Route 53 DNS record created
A-alias: api.example.com -> d-abc123.execute-api.us-east-2.amazonaws.com
Test command (authorized):
curl 'https://api.example.com/example?QueryString1=queryValue1' -H 'HeaderAuth1: headerValue1'
Test command (denied):
curl 'https://api.example.com/example'
トラブルシューティング
証明書が PENDING_VALIDATION のままになる
aws acm describe-certificate --certificate-arn {arn} --query 'Certificate.DomainValidationOptions' を実行して、DNS 検証用の CNAME レコードが Route 53 に存在することを確認してください。CNAME が正しいホストゾーンに作成されていることを確認してください。
API 呼び出しで 403 Forbidden が発生する
リクエストオーソライザーは 3 つの値を確認します。HeaderAuth1 ヘッダーが headerValue1、QueryString1 クエリパラメーターが queryValue1、ステージ変数 StageVar1 が stageValue1 である必要があります。3 つすべてが存在し、正しいことを確認してください。詳細なエラーメッセージについては、オーソライザー関数の CloudWatch Logs を確認してください。
401 Unauthorized
オーソライザー関数を呼び出せない場合、API Gateway は 401 を返します。API Gateway がオーソライザーを呼び出すための Lambda 権限が追加されていることを確認してください。オーソライザー URI が正しいことを確認してください。
Missing Authentication Token(403)
リクエストパスが設定済みのリソースと一致しません。aws apigateway get-resources --rest-api-id {api_id} を実行して、/example リソースが存在することを確認してください。すべてのリソースを作成した後に API がデプロイされたことを確認してください。
カスタムドメインから応答がない
DNS の伝播には最大 48 時間かかる場合があります。dig {custom_domain_name} で確認してください。A エイリアスレコードが、create-domain-name の応答から取得した正しい regionalDomainName と regionalHostedZoneId を指していることを確認してください。
Stage 変数が設定されていない
オーソライザーがすべてのリクエストを拒否する場合は、aws apigateway get-stage --rest-api-id {api_id} --stage-name {stage_name} --query 'variables' を実行して、ステージ変数が設定されていることを確認してください。StageVar1 変数には stageValue1 を設定する必要があります。
Lambda の作成時に IAM ロールが見つからない
IAM ロールの反映には時間がかかる場合があります。ロールを作成してから Lambda 関数を作成するまで、少なくとも 10 秒待ってください。aws iam get-role --role-name {role_name} を実行してロール ARN を確認してください。
ベースパスマッピングが機能しない
aws apigateway get-base-path-mappings --domain-name {custom_domain_name} を実行して確認してください。ベースパス (none) は、ドメインのルートをステージにマッピングします。ステージへのデプロイが正常に完了していることを確認してください。
セキュリティに関する考慮事項
- Lambda オーソライザーにハードコードされている認証値(
headerValue1、queryValue1、stageValue1)はデモ専用であり、本番環境には適していません。本番環境にデプロイする前に、適切な認証メカニズム(JWT 検証、AWS Secrets Manager の API キー、OAuth など)に置き換えてください。 - 不正使用を防ぐため、API ステージでリクエストのスロットリングを有効にしてください。次のコマンドでレートとバーストの上限を設定します:
aws apigateway update-stage --rest-api-id {api_id} --stage-name {stage_name} --patch-operations op=replace,path=/throttle/rateLimit,value=1000 op=replace,path=/throttle/burstLimit,value=2000 - Lambda ロググループの CloudWatch Logs 暗号化を有効にしてください。次のコマンドで KMS キーを関連付けます:
aws logs associate-kms-key --log-group-name /aws/lambda/request-authorizer --kms-key-arn <KMS_KEY_ARN> - AWS WAF でパブリック API を保護し、一般的な攻撃(SQL インジェクション、XSS、レートベースのルール)を軽減してください:
aws wafv2 associate-web-acl --web-acl-arn <WAF_ACL_ARN> --resource-arn arn:aws:apigateway:{region}::/restapis/{api_id}/stages/{stage_name}