Redshift-managed VPC endpointsを構築してみた

#はじめに
Redshift 管理の VPC エンドポイントを作成したので、その備忘録として記載いたします。

#Redshift-managed VPC endpointsの特徴
* 別AWSアカウントにあるRedshiftや別VPCにあるRedshiftにアクセスするといった用途の際に利用するものであり、エンドポイントはRedshift側で管理される。
* Amazon VPC コンソールを使用して RedShift が管理する VPC エンドポイントを管理することはできない。
* 作成できる RedShift 管理の VPC エンドポイントの数は、VPC エンドポイントのクォータに制限される。

参考URL：https://docs.aws.amazon.com/ja_jp/redshift/latest/mgmt/managing-cluster-cross-vpc.html

**■イメージ図**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252895/b726cbdc-f953-4749-3867-59051e3fc138.png)


#実施手順
今回の実施手順としては、**AWSアカウントAで保有しているRedshift**にアクセスするために、**AWSアカウントBでRedshift-managed VPC endpoints**を作成する手順を記載いたします。
基本的には、下記URLの記載通りに実施します。
https://aws.amazon.com/jp/blogs/big-data/enable-private-access-to-amazon-redshift-from-your-client-applications-in-another-vpc/

##(1)Redshiftを保有しているAWSアカウント側の作業(AWSアカウントA側の作業)

###(1.1)クラスターの再配置を有効
Redshiftで、クラスターの再配置を有効化する。
(新規で作成する際は、その際に有効化しとくとラク)
※本作業を実施しないと、今後の作業でエラーとなり、失敗する。

Redshiftのクラスターの再配置に関しての参考URL：https://dev.classmethod.jp/articles/20201210-amazon-redshift-cross-az-recovery/

###(1.2)信頼するAWSアカウント/VPC IDを設定する。

今回は、AWS CLIで実行します。

```
[cloudshell-user@ip-10-0-37-83 ~]$ aws redshift authorize-endpoint-access --cluster-identifier <クラスター識別子>  --account <AWSアカウントB> --vpc-ids <AWSアカウントBのVPC ID>
↓出力結果例
{
    "Grantor": "AWSアカウントA",
    "Grantee": "AWSアカウントB",
    "ClusterIdentifier": "クラスター識別子",
    "AuthorizeTime": "2022-02-03T01:57:17.682000+00:00",
    "ClusterStatus": "active",
    "Status": "authorized",
    "AllowedAllVPCs": false,
    "AllowedVPCs": [
        "AWSアカウントBのVPC ID"
    ],
    "EndpointCount": 0
}
```

##(2)Redshift-managed VPC endpointsを作成する側の作業(AWSアカウントB側の作業)

###(2.1)エンドポイント用のSG作成

エンドポイント用のSGを作成。
(インバウンドルールで許可するIP CIDRに対して、TCPで5439ポートを許可する設定でOK。)

###(2.2)クラスターサブネットグループを作成

クラスターサブネットグループの名前と所属するサブネットを指定する。(画面キャプチャ参考)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252895/a6fde6ce-faf1-99c6-9dcf-00c0eff3f6b5.png)

###(2.3)Redshift-managed VPC endpointsを作成

今回もAWS CLIの方がらくなので、そっちで作成します。

```
[cloudshell-user@ip-10-0-157-209 ~]$ aws redshift create-endpoint-access --cluster-identifier <AWSアカウントAのクラスター識別子> --resource-owner <AWSアカウントAのAWS ID> --endpoint-name <EndpointName> --subnet-group-name <(2.2)で作成したクラスターサブネットグループ> --vpc-security-group-ids <(2.1)で作成したSecurityGroupId>
↓出力結果例
{
    "ClusterIdentifier": "AWSアカウントAのクラスター識別子",
    "ResourceOwner": "AWSアカウントAのAWS ID",
    "SubnetGroupName": "(2.2)で作成したクラスターサブネットグループ",
    "EndpointStatus": "creating",
    "EndpointName": "EndpointName",
    "Port": 5439,
    "VpcSecurityGroups": [
        {
            "VpcSecurityGroupId": "(2.1)で作成したSecurityGroupId",
            "Status": "active"
        }
    ]
}
```


###(2.4)作成後の確認


```
[cloudshell-user@ip-10-0-157-209 ~]$ aws redshift describe-endpoint-access
↓出力結果
{
    "EndpointAccessList": [
        {
            "ClusterIdentifier": "AWSアカウントAのクラスター識別子",
            "ResourceOwner": "AWSアカウントAのAWS ID",
            "SubnetGroupName": "(2.2)で作成したクラスターサブネットグループ",
            "EndpointStatus": "active",
            "EndpointName": "EndpointName",
            "EndpointCreateTime": "2022-02-03T02:22:36.136000+00:00",
            "Port": 5439,
            "Address": "<EndpointName>-endpoint-××××××××××××.cpujakusqpms.ap-northeast-1.redshift.amazonaws.com",
            "VpcSecurityGroups": [
                {
                    "VpcSecurityGroupId": "sg-××××××××××××××",
                    "Status": "active"
                }
            ],
            "VpcEndpoint": {
                "VpcEndpointId": "vpce-××××××××××××××",
                "VpcId": "vpc-××××××××××××××",
                "NetworkInterfaces": [
                    {
                        "NetworkInterfaceId": "eni-××××××××××××××",
                        "SubnetId": "subnet-××××××××",
                        "PrivateIpAddress": "××.××.××.××",
                        "AvailabilityZone": "ap-northeast-1c"
                    }
                ]
            }
        }
    ]
}
```

###(2.5)作成後のアクセス確認

下記、コマンドを実行し、RedshiftにアクセスできればOK。
※事前にクライアント側で、PostgreSQLをインストールする必要がある。

```
$ psql -h <Redshift-managed VPC endpointsのエンドポイントURL> -U awsuser -p 5439 -d <データベース名>
```

#作成後の疑問点

(2.4)で確認した際に、IPアドレスが1つしか割り当てられていなかったので、AZ障害時の挙動に関して、AWSサポートに問い合わせをしました。
問い合わせ内容としては、下記である。

```
Q
・2つのサブネットを指定したクラスターサブネットグループを作成し、それをRedshift-managed VPC endpointsに割り当てたが、IPアドレスが1つしか割り当てられていなかったが、こちらは仕様でしょうか。
・上記1IPアドレスしか割り当ていない状態で、AZ障害が起きた際は、フェイルオーバーの機能はありますでしょうか
・エンドポイント側で一度取得したIPアドレスは、固定でしょうか。
・VPCエンドポイントを作成時にAZを指定することはできないが、構築後にAZを変更することはできますでしょうか。

A
・現在の Redshift-managed VPC endpoints は、単一の ENI の IP アドレスを使い Redshift クラスターと通信を行う。
　Redshift-managed VPC endpoints 作成時のサブネットグループで Multi AZ を構成した場合も上記の動作となり、複数の AZ に跨ったエンドポイントを構成することは現状不可である。
・ Redshift-managed VPC endpoints の ENI が存在する AZ に広域障害が発生した場合、別の AZ に ENI を作成することはしないため、AZ 障害時には影響があります。(単一障害点としてなり得る。)
・単一の ENI のみを使用する仕様である為、一度割り当てられた IP アドレスは変わらない。
・作成時にサブネットを指定したり、作成後のサブネットの変更は不可。
```

上記内容を踏まえ、Redshift-managed VPC endpointsの冗長構成が可能かを試したところ、
下記のエラーが発生し、エンドポイントの作成に失敗した。
同じRedshiftを指定したエンドポイントを同一VPC内に2つ以上作れないようであった。
>An error occurred (EndpointAlreadyExists) when calling the CreateEndpointAccess operation: The Redshift-managed VPC endpoint for VPC vpc-×××××××××× to access cluster <redshift-cluster-Name> already exists

**今回の調査結果のまとめ**

* 所属するサブネットを明確に指定したい場合は、クラスタサブネットグループで一つのサブネットのみを指定する。
* Redshift-managed VPC endpointsは、AZ障害時のフェイルオーバー機能を備えていない為、単一障害点としてなり得る。
* 同一VPC内では、同じRedshiftを指定したエンドポイントは2つ以上作成できない。


#最後に
現時点(2022/2/10)では、Redshift-managed VPC endpointsは、単一障害点としてなり得るということがわかった。
そこを理解した上で、使用する必要がある。
今後のアップデートで、AZ障害時のフェイルオーバーに対応した構成になるといいな。。。

#参考URL一覧
* [はじめてのRedshift](https://qiita.com/nyasba/items/2586b172219776d694a6)
* [【速報】Amazon Redshift の障害を自動的に検出して別のAZで復旧する『Cross-AZ cluster recovery』が発表されました #reinvent](https://dev.classmethod.jp/articles/20201210-amazon-redshift-cross-az-recovery/)
* [別のVPCのクライアントアプリケーションからAmazonRedshiftへのプライベートアクセスを有効にする](https://aws.amazon.com/jp/blogs/big-data/enable-private-access-to-amazon-redshift-from-your-client-applications-in-another-vpc/)
* [Amazon Redshift での Redshift 管理の VPC エンドポイントの操作](https://docs.aws.amazon.com/ja_jp/redshift/latest/mgmt/managing-cluster-cross-vpc.html)