CloudFront + API Gateway で IPv6 のみでアクセスする

# やりたいこと

API Gateway は IPv6 は利用できないので、CloudFront を介して IPv6 のみでアクセスできるようにする。
![IPv6.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/9833c0ea-c475-4563-d721-dd3ac99644aa.png)

なお、今回は 検証用途として別VPC に EC2 で IPv6を有効化して検証します。そのため先に以下の方の記事を参考に作成しておいて下さい。

https://qiita.com/rotekxyz/items/5f171cc70d98b22f7d9b

# 手順

## API Gateway と Lambda

https://github.com/leomaro7/AWS_SAM/tree/master/Lambda-HelloWorld

AWS SAM で API Gateway と既存のプライベートサブネットに Lambda を作成します。

`template.yaml` で <サブネットid1>、<サブネットid2>、<セキュリティグループ> はご自分の環境に合わせます。

```template.yaml
      VpcConfig:
        SubnetIds:
          - <サブネットid1>
          - <サブネットid2>
        SecurityGroupIds:
          - <セキュリティグループ>
```

後は普通に `sam build　`、`sam build　` でデプロイします。

デプロイが完了したら、API Gateway　のエンドポイントにアクセスし、Hello　World が表示されるか確認しておきましょう・。

`https://XXXXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/`

## ACM

https://docs.aws.amazon.com/ja_jp/acm/latest/userguide/acm-regions.html

CloudFront で代替ドメイン名(CNAME)を利用するために、SSL証明書を ACM で作成しておきます。
なお、CloudFront で利用するためにはバージニア北部リージョンで作成しておきます。

## CloudFront

デフォルトから変更が必要な最低限の箇所だけ説明します。

「オリジンドメイン」は、API Gateway　のドメインを指定します。
「オリジナルパス」には、/Prod/Hello を入力します。
![スクリーンショット 2023-10-21 21.21.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/64bdad69-c299-12ad-0ad0-25e0c75f426e.png)

「代替えドメイン（CNAME）」に自身のドメインを入力します。
カスタムSSL証明書に先程　ACM　で作成した証明書を指定します。
![スクリーンショット 2023-10-21 21.30.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/4a7159e8-388a-a485-a4f7-f22217a98084.png)

デフォルトで「IPv６」は　オン　になるようです。
![スクリーンショット 2023-10-21 21.12.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/78b7fe27-3915-869b-6462-ed417dc34f75.png)

### 確認１

CloudFront　のデプロイが完了したら、ディストリビューションドメインに対して、先程作成した EC2 から dig を打ってみます。

```
$ dig XXXXXXXXXXXX.cloudfront.net a

;; ANSWER SECTION:
XXXXXXXXXXXX.cloudfront.net. 43 IN     A       13.227.62.X
XXXXXXXXXXXX.cloudfront.net. 43 IN     A       13.227.62.X
XXXXXXXXXXXX.cloudfront.net. 43 IN     A       13.227.62.X
XXXXXXXXXXXX.cloudfront.net. 43 IN     A       13.227.62.X


$ dig XXXXXXXXXXXX.cloudfront.net aaaa

;; ANSWER SECTION:
XXXXXXXXXXXX.cloudfront.net. 60 IN     AAAA    2600:9000:21ee:XXXX:1c:70af:e540:93a1
XXXXXXXXXXXX.cloudfront.net. 60 IN     AAAA    2600:9000:21ee:XXXX:1c:70af:e540:93a1
XXXXXXXXXXXX.cloudfront.net. 60 IN     AAAA    2600:9000:21ee:XXXX:1c:70af:e540:93a1
XXXXXXXXXXXX.cloudfront.net. 60 IN     AAAA    2600:9000:21ee:XXXX:1c:70af:e540:93a1
XXXXXXXXXXXX.cloudfront.net. 60 IN     AAAA    2600:9000:21ee:XXXX:1c:70af:e540:93a1
XXXXXXXXXXXX.cloudfront.net. 60 IN     AAAA    2600:9000:21ee:XXXX:1c:70af:e540:93a1
XXXXXXXXXXXX.cloudfront.net. 60 IN     AAAA    2600:9000:21ee:XXXX:1c:70af:e540:93a1
XXXXXXXXXXXX.cloudfront.net. 60 IN     AAAA    2600:9000:21ee:XXXX:1c:70af:e540:93a1
```

この状態だと、IPv4,IPv6 どちらも返ってきてしまいますね。

## Route53

代替えドメイン（CNAME）に対して、IPv6　のみが返されるように AAAAレコードを追加します。

![スクリーンショット 2023-10-21 21.51.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/49885f63-d06a-67c5-fa04-0ecb7ba764c6.png)

### 確認２

AAAAレコードが作成されたら、EC2 から自身のドメインに対して dig をうってみます。

```
$ dig test.XXXXXXXXXXXX.com aaaa

;; ANSWER SECTION:
XXXXXXXXXXXX.cloudfront.net. 60 IN     AAAA    2600:9000:21ee:XXXX:1c:70af:e540:93a1
XXXXXXXXXXXX.cloudfront.net. 60 IN     AAAA    2600:9000:21ee:XXXX:1c:70af:e540:93a1
XXXXXXXXXXXX.cloudfront.net. 60 IN     AAAA    2600:9000:21ee:XXXX:1c:70af:e540:93a1
XXXXXXXXXXXX.cloudfront.net. 60 IN     AAAA    2600:9000:21ee:XXXX:1c:70af:e540:93a1
XXXXXXXXXXXX.cloudfront.net. 60 IN     AAAA    2600:9000:21ee:XXXX:1c:70af:e540:93a1
XXXXXXXXXXXX.cloudfront.net. 60 IN     AAAA    2600:9000:21ee:XXXX:1c:70af:e540:93a1
XXXXXXXXXXXX.cloudfront.net. 60 IN     AAAA    2600:9000:21ee:XXXX:1c:70af:e540:93a1
XXXXXXXXXXXX.cloudfront.net. 60 IN     AAAA    2600:9000:21ee:XXXX:1c:70af:e540:93a1
```

### 確認3 

最後に　EC2 から自身のドメインに対して　curl　を打ち　IPv6　で接続していることが確認できれば本検証は終了です。

```
$ curl -iv https://test.XXXXXXXXXXXX.com 
*   Trying [2600:9000:21ee:XXXX:1c:70af:e540:93a1]:443...
* Connected to test.XXXXXXXXXXXX.com (2600:9000:21ee:XXXX:1c:70af:e540:93a1) port 443
```