AWS API Gateway REST API カスタムドメインを使用する

# 初めに

API Gateway で作成した API の URL は、
`https://api-id.execute-api.region.amazonaws.com/stage`
という形式です。これをカスタマイズしてわかりやすい URL にしたいことがあります。

以下のドキュメントを参考にやってみました。

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/how-to-custom-domains.html

# 手順

## 1. ACM にサーバ証明書をインポートする

途中で聞かれる Common Name にドメイン名を入力します。（e.g. example-20210811.com）

```
openssl genrsa -out server.key 2048
openssl req -new -sha256 -key server.key -out server.csr
openssl x509 -req -in server.csr -signkey server.key \
> -set_serial 01 -out server.crt -days 3650 -sha256
aws acm import-certificate --region us-east-1 \
> --certificate fileb://server.crt \
> --private-key fileb://server.key \
> --certificate-chain fileb://server.crt
```

`openssl` コマンドよりも、OpenVPN の easy-rsa の方が慣れていればこちらでもよいです。

```
git clone https://github.com/OpenVPN/easy-rsa
cd easy-rsa/easyrsa3/
./easyrsa init-pki
./easyrsa build-ca nopass
./easyrsa build-server-full example-20210811.com nopass
mkdir custom_folder
cp pki/ca.crt pki/issued/example-20210811.com.crt \
> pki/private/example-20210811.com.key custom_folder/
cd custom_folder/
aws acm import-certificate --region us-east-1 \
> --certificate fileb://example-20210811.com.crt \
> --private-key fileb://example-20210811.com.key \
> --certificate-chain fileb://ca.crt
```

## 2. カスタムドメインを作成する

ドメイン名を入力します。Route 53 で取得したドメイン名にします。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/3fb9c6a1-2f6d-9ac1-47b6-ab38c9e9b099.png)



![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/92924344-c9b6-52fe-d2b9-0a90cf1afb46.png)


## 3. Route 53 でレコードを作成する

シンプルルーティングを選択し、作成した API Gateway のカスタムドメイン名を設定します。

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/56e7e282-ff9f-3e90-4599-8db5583fb1b5.png)

ここで「カスタムドメイン名」とは、以下のことです。

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/9238379d-8aaf-c665-bca8-3b251c0ceb96.png)

## 4. バックエンドを作成する

「custom-domain-api」という Lambda 関数を作成します。ソースコードはデフォルトのまま進めます。

```js:index.js
exports.handler = async (event) => {
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};
```

## 5. REST API を作成する

GET メソッドを作成し、4 で作成した Lambda 関数を統合します。

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/c75d0767-fbe5-e26f-b339-57c6d9f2cc39.png)

## 6. API マッピングを作成する

以下の「API マッピングを設定」をクリックします。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/3d76b34a-4823-fdc4-1f99-b8a521b0378f.png)

REST API と、ステージ変数を選択します。その後「保存」をクリックします。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/bd307ea9-7c63-9f0d-8a5b-ba33b642e557.png)

新しいリソースができたら、「新しいマッピングを追加」をクリックし、ここに追加していきます。

## 7. 確認

```
$ curl -k https://example-20210811.com
{"statusCode":200,"body":"\"Hello from Lambda!\""}
```

またはブラウザにカスタムドメインを開き、レスポンスが返ってくることを確認します。

なお、オプション `-k` で以下のエラーを無視します。

```
$ curl https://example-20210811.com
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
```

オプション `-k` についてはこちらを参考にさせていただきました。

https://qiita.com/ponsuke0531/items/224e4cba2a8c8def5987

# トラブルシューティング

- `"message":"Forbidden"`

API マッピングが設定されていない場合、このエラーが発生しました。

```
$ curl -k https://example-20210811.com
{"message":"Forbidden"}
```



# 参考記事

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/how-to-custom-domains.html

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/http-api-mutual-tls.html

https://aws.amazon.com/jp/blogs/compute/introducing-mutual-tls-authentication-for-amazon-api-gateway/

https://qiita.com/aqmr-kino/items/40ceea7c6674a78abbf4