Serverless FrameworkでRESTFulAPIを作成すると、通常だと以下のようにAWS側で用意されたドメインを利用するわけですが、
https://d-hhlj8cxjl7.execute-api.us-east-1.amazonaws.com/dev/welcome
今回は次のようにこちらで用意したドメインでリクエストを可能にします。
https://api.blog.katsubemakito.net/api/welcome
これはServerless Frameworkのプラグイン「serverless-domain-manager」を導入することで比較的簡単に実現できます。
事前準備
Serverless Framework?
基本的な利用方法については過去の記事をご覧くださいませ。 blog.katsubemakito.net
Route53にドメインを設定
独自ドメインをRoute53にドメインをセットしておきます。今回は新しく「api.blog.katsubemakito.net」という名前のホストゾーンを作成しました。
※ドメインの詳しい設定については割愛します。
SSL証明書を作成
AWSのマネジメントコンソールのにログインし、ACM(AWS Certificate Manager)に移動、右上にあるリージョンを確認、必要があれば変更します。基本的にLambdaを実行するリージョンと同じ物を選択すればよいのですが、CloudFront(edge)での配信を希望する場合は「バージニア北部(us-east-1)」を指定します。
証明書のリクエストをクリック。
「パブリック証明書のリクエスト」を選択しボタンをクリック。
ドメイン名を入力し「次へ」をクリック。
「DNSの検証」を選択し「次へ」をクリック。このあとタグ付ける画面が出てきますが必要に応じて設定してください。
ステップ5まで来たら「Route53でのレコードの作成」をクリックします。
最初の一覧画面に戻ったら「検証保留中」の部分が「発行済」に切り替わったら作成完了です。数分程度で完了します。
独自ドメインを設定
ここから本題です。
プロジェクトの作成
今回は「hello2」という名前でプロジェクトを作成しました。ここではJavaScript(Node.js)を選択していますが何でもかまいません。
$ serverless Serverless: No project detected. Do you want to create a new one? Yes Serverless: What do you want to make? AWS Node.js Serverless: What do you want to call this project? hello2 Project successfully created in 'hello2' folder.
作成されたプロジェクト用フォルダの下に移動し、package.json
を作成するためにnpm init
を実行します。
$ cd hello2
$ npm init
プラグインのインストール
npmでプラグインをインストールします。package.jsonにも記録されているか確認しておきます。
$ npm install serverless-domain-manager --save-dev
serverless-domain-managerの詳細は以下を参照ください。 github.com
handler.jsを準備
ほぼデフォルトのままです。メッセージの内容を簡略化しています。Lambda関数の処理自体は独自ドメインの設定とは直接関係ありませんのでこれまで通り自由に記述できます。
'use strict'; module.exports.hello = async event => { return { statusCode: 200, body: JSON.stringify( { message: 'Welcome to MyDomain', }, null, 2 ), }; };
serverless.ymlを設定
プロジェクトの設定ファイルである「serverless.yml」の下の方にplugins以下の項目を書き足します。domainNameやcertificateNameなどの値は環境に合わせて変更してください。
service: hello2 provider: name: aws runtime: nodejs12.x functions: hello: handler: handler.hello events: - http: path: welcome method: get plugins: - serverless-domain-manager custom: customDomain: domainName: api.blog.katsubemakito.net stage: dev basePath: api certificateName: 'api.blog.katsubemakito.net' createRoute53Record: true endpointType: 'regional' securityPolicy: tls_1_2
各項目の意味は以下になります。domainNameは必ず指定する必要があり、他の項目は任意です。
項目名 | 初期値 | 說明 |
---|---|---|
domainName | - | 設定したい独自ドメイン |
stage | provider.stageで設定した値 | 対象のステージを指定 |
basePath | (なし) | APIのendpointで利用するベース部分を指定 |
certificateName | (domainNameに近い物) | ACMで作成したドメイン名 |
createRoute53Record | true | プラグインがRroute53にレコード作成を行うか |
endpointType | edge | endpointの形式をregional かedge を指定 |
securityPolicy | tls_1_2 | セキュリティポリシーをtls_1_0 かtls_1_2 を指定 |
この他の項目はプラグインのドキュメントを参照してください。
AWSへドメイン設定を反映する
serverless.ymlの編集が終わったらserverless create_domain
を実行します。実行結果が返ってくると完了まで40分くらいかかるとありますのでしばし待ちます。
$ serverless create_domain
Serverless: Custom domain api.blog.katsubemakito.net was created.
New domains may take up to 40 minutes to be initialized.
ただ、何度か試しに実行するといずれも数分〜10分程度で利用できたので、状況によってはすぐに終わりそうですね。
AWSへデプロイ
最後に通常通りデプロイすれば完了です。
$ serverless deploy
途中、これまで通りamazonaws.comドメインのendpointsも作成されます。こちらの利用も引き続き可能です。
endpoints: GET - https://4lei1rl4ti.execute-api.us-east-1.amazonaws.com/dev/welcome
最後にプラグインの実行結果が表示されます。
Serverless Domain Manager Summary Domain Name api.blog.katsubemakito.net Distribution Domain Name Target Domain: d-hhlj8cxjl7.execute-api.us-east-1.amazonaws.com Hosted Zone Id: Z1UJRXOUMOOFQ8
実行する
早速curlでリクエストを飛ばしてみます。無事に実行されていることが確認できました。
$ curl https://api.blog.katsubemakito.net/api/welcome { "message": "Welcome to MyDomain" }
amazonaws.comの方も同様に実行可能ですね。
$ curl https://4lei1rl4ti.execute-api.us-east-1.amazonaws.com/dev/welcome { "message": "Welcome to MyDomain" }
独自ドメインを削除する
設定した独自ドメインは以下のコマンド一発で削除できます。一瞬で反映されますので実行は慎重に。
$ serverless delete_domain Serverless: Custom domain api.blog.katsubemakito.net was deleted.
curlで確かめるとほぼ一瞬で消えてなくなりました。
$ curl https://api.blog.katsubemakito.net/api/welcome curl: (6) Could not resolve host: api.blog.katsubemakito.net
もう一度同じ独自ドメインを設定したくなった場合はserverless create_domain
した後にデプロイします。デプロイを忘れると永遠に403が返ってきますのでご注意を。
$ serverless create_domain $ serverless deploy