はじめに
こちらの記事の続編です。
(※ 読まなくても大丈夫です。)
Serverless Framework で REST API をデプロイすると、AWS 側で以下のようなドメインが発行されます。
https://5tjwpqfgo2.execute-api.us-east-1.amazonaws.com/dev/hello
このドメインに含まれる 5tjwpqfgo2
という値は、こちらで何も設定しないとデプロイするごとに毎回変更されてしまい、使い勝手がよくないです。
なので、これをカスタムドメインで固定しようというのが、今回やりたいことになります。
サマリー
以下を Serverless Framework で実現しました。
- カスタムドメインを指定できるようにすること
- 開発環境と本番環境で異なるカスタムドメインを指定できるようにすること
その結果、REST API のパスが以下のように固定することができるようになりました。
- Before
- URL:
https://xxxxxxx.execute-api.us-east-1.amazonaws.com/dev/hello
- 備考:URL の
xxxxxxx
の部分はデプロイするたびに変わる
- URL:
- After
- 開発環境 URL:
https://dev.suguru-takahashi.com/api/hello
- 本番環境 URL:
https://suguru-takahashi.com/api/hello
- 備考:カスタムドメインは固定である
- 開発環境 URL:
全体のソースコードはこちらにあげました。
やりたいこと
やりたいことは以下の 2 つです。
- カスタムドメインを指定できるようにすること
- 開発環境と本番環境で異なるカスタムドメインを使用すること
これを↓
- カスタム度名指定前(Before)
https://5tjwpqfgo2.execute-api.us-east-1.amazonaws.com/dev/hello
こうしたい↓
- カスタムドメイン指定後(After その1)
https://mogemoge.suguru-takahashi.com/api/hello
そして、以下のように開発環境と本番環境で URL を分けたい↓
- 開発環境(After その2)
https://dev.suguru-takahashi.com/api/hello
- 本番環境(After その2)
https://suguru-takahashi.com/api/hello
全体構成図
この記事では増築された部分の設定の仕方について触れます。
カスタムドメインを指定できるようにする
前提
以下の操作はすべて済んでいることを前提に手順を説明します。
- Serverless Framework 関連の準備
- カスタムドメインの設定を除いた serverless.yml の設定
- カスタムドメイン関連の準備
- 外部サービス or Route 53 でのカスタムドメインの取得
- Route 53 でのホストゾーンの作成
- ACM での SSL証明書の作成
これらの操作については以下の記事がわかりやすかったです。
【参考】
- Serverless Frameworkでカスタムドメインを設定する
- 【Serverless Framework 入門】 API Gateway + Lambda + DynamoDB サンプル(過去記事1)
- 【AWS】 Route 53 + ACM + CloudFront + S3 の構成を構築する際につまずいたところ解説(過去記事2)
プラグインのインストール
serverless-domain-manager という npm パッケージのプラグインを使用します。
npm パッケージなので Serverless Framework のプロジェクトを Node.js で使用しなければならないという縛りはないです。(例えば Python などのプロジェクトでも使用可能)
# package.json の作成(すでにあればスキップ)
$ npm init -y
# serverless-domain-manager のインストール
$ npm install serverless-domain-manager --save-dev
serverless.yml の設定
- plugins の設定
serverless-domain-manager
を追記するだけです。
plugins:
- serverless-domain-manager
- custom の設定
mogemoge.suguru-takahashi.com/api
というドメインを作成する例になります。
custom:
customDomain:
# API のパスは `https://<domainName>/<basePath>/xxxx` となる
domainName: mogemoge.suguru-takahashi.com
basePath: api
certificateName: '*.suguru-takahashi.com'
createRoute53Record: true
endpointType: 'regional'
securityPolicy: tls_1_2
詳しい設定項目の説明は serverless-domain-manager の公式ドキュメントを参照ください。
実のところ、Serverless Framework を使用しなくても、以下の AWS 公式ドキュメントの操作を行えば同じことは実現できます。
【参考】
・REST API のカスタムドメイン名を設定する
endpointType
などについての設定項目は上記の AWS 公式ドキュメントに詳しく説明があります。
また、事前に Route 53 や ACM の設定は必要です。今回は以下のような設定です。
ドメイン設定の AWS への反映
以下のコマンドによって、AWS にドメイン設定を反映させます。
$ sls create_domain
このコマンド実行によって Route 53 に A レコードと AAAA レコードの 2 つのレコードが作成されます。
【参考】
・DNSレコード
デプロイ
$ sls deploy
挙動の確認
Serverless Framework のデフォルトで配置されている /hello
の API で挙動を確認します。
- A. 今まで通りの AWS が発行のドメインでアクセスする
コンソールにでている AWS 側から発行される https://xxxxx.execute-api.us-east-1.amazonaws.com/dev/hello
というドメインでもアクセスできます。
※ /dev
の部分は API Gateway 側のステージ名が反映されます。Serverless Framework でのデフォルトのステージ名は dev になります。
もちろん、証明書は AWS が用意したものになります。
- B. カスタムドメインでアクセスする(本命)
設定した以下のカスタムドメインでアクセスでします。
https://mogemoge.suguru-takahashi.com/api/hello
証明書は ACM に登録したものが設定されています。
API Gateway の設定も確認してみます。以下の画像のように Route 53 に挿入された A レコードと AAAA レコードの対応通りになっていることが確認できます。
serverless.yml で設定した basePath: api
も反映されていることが確認できます。
プロジェクトの削除
こちらのコマンドでプロジェクトは削除されます。
$ sls remove
先にドメイン設定を削除してしまうと、プロジェクトの削除に失敗するおそれがあるので注意してください。
ドメイン設定の削除
以下のコマンドによって、AWS にドメイン設定を反映させます。
$ sls delete_domain
Route 53 を確認すると sls create_domain
で作成された A レコードおよび AAAA レコードが削除されていることが確認できます。
運用
serverless-domain-manager のインストールと serverless.yml の設定が完了すれば、実運用としては以下のコマンドでカスタムドメインを設定した REST API のデプロイから削除までを行うことができます。
# ドメイン作成
$ sls create_domain
# プロジェクト作成
$ sls deploy
# プロジェクト削除
$ sls remove
# ドメイン削除
$ sls delete_domain
Serverless Framework でのカスタムドメイン設定の基礎的な部分は以上になります。
開発環境と本番環境で異なるカスタムドメインを指定できるようにする
sls create_domain
の実行時に sls deploy
のときと同様にコマンド実行時に --stage <ステージ名>
で stage を設定することができるので、それを利用して開発環境と本番環境で異なるカスタムドメインを指定します。
前提
- 『その 1:カスタムを指定できるようにする』が完了していること
serverless.yml の設定
変更するのは serverless.yml
のみです。
ステージ名、カスタムドメインを以下のように設定します。
- 開発環境
- ステージ名:
dev
(デフォルト) - カスタムドメイン:
dev.suguru-takahashi.com
- ステージ名:
- 本番環境
- ステージ名:
prd
- カスタムドメイン:
suguru-takahashi.com
- ステージ名:
custom:
stage: ${opt:stage, self:provider.stage}
endpoint:
dev: "dev.suguru-takahashi.com"
prd: "suguru-takahashi.com"
customDomain:
domainName: ${self:custom.endpoint.${self:custom.stage}}
stage: ${self:custom.stage}
basePath: api
certificateName: '*.suguru-takahashi.com'
createRoute53Record: true
endpointType: 'regional'
securityPolicy: tls_1_2
custom.stage
, custom.endpoint
はという名称は引数名なので何でもよいです。
ここでのポイントはステージ名を domainName
に埋め込むようにすると本番環境のカスタムドメインが prd.suguru-takahashi.com
なってしまい prd
が格好悪いので、custom.endpoint
をクッションにおいて自由なカスタムドメインを設定できるようにしています。
開発環境
開発環境はデフォルトでステージ名が dev
なので、デプロイと削除のコマンドに変更はありません。
# ドメイン作成
$ sls create_domain
# プロジェクト作成
$ sls deploy
# プロジェクト削除
$ sls remove
# ドメイン削除
$ sls delete_domain
※ もちろん、--stage dev
とオプションをつけても同様の挙動になります。
本番環境
開発環境との違いはコマンド実行時に --stage <ステージ名>
のオプションでステージ名を prd
と指定してあげるだけです。
# ドメイン作成
$ sls create_domain --stage prd
# プロジェクト作成
$ sls deploy --stage prd
# プロジェクト削除
$ sls remove --stage prd
# ドメイン削除
$ sls delete_domain --stage prd
※ あえて、serverless.yml 内で設定していないようなステージ名を --stage <ステージ名>
でわたすと serverless.yml での変数名が解決できず、デプロイに失敗してくれます。
挙動の確認
開発環境と本番環境のデプロイ後の AWS コンソールを確認すると以下のようになります。
両方の環境が別々のドメインがふられていることが確認できます。
以上になります。
参考文献
- Serverless Framework 公式のブログでの解説
- serverless-domain-manager
- わかりやすかった記事
- 開発環境/本番環境の切り替えで参考になった資料