【AWS】オプトインリージョンへのS3アクセス時の注意

# これは何？


とある事情でLambdaからS3へファイルを転送する構成で、中東(バーレーン)リージョンに導入する必要がありました。
が少し上手くいかなかったのでメモです。

## 状況
いつも通りTerraformにて同じリソースをデプロイした。
しかしながら、S3へログを転送するLambdaでエラーが発生。


## エラー内容
・エラー内容は以下、調べてみるとリージョン系のエラーっぽい。

```
2021-09-02T10:58:14.881Z	fe9ac618-e5a7-46ad-b53e-4e35607db33a	ERROR	Cannot put object!.
2021-09-02T10:58:14.821Z	fe9ac618-e5a7-46ad-b53e-4e35607db33a	ERROR	IllegalLocationConstraintException: The ap-northeast-1 location constraint is incompatible for the region specific endpoint this request was sent to.
    at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/services/s3.js:714:35)
    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:688:14)
    at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:690:12)
    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18) {
  code: 'IllegalLocationConstraintException',
  region: null,
  time: 2021-09-02T10:58:14.820Z,
  requestId: '4M0KG8KW7QA19ZTJ',
  extendedRequestId: 'AzznZnK0ORD+UQV1jRp6Jn8bTyzCcjpCj18raYClvuI1cmA/CjrT6ATYtwvFTzcLG+4AXpYEva0=',
  cfId: undefined,
  statusCode: 400,
  retryable: false,
  retryDelay: 70.7991884883068
}
```

スクリプト内で確かにリージョンを指定してないのでエラーが出たのかもと思ったが、
これまで欧州や豪州などにも導入してきたが問題無く動作していたので納得いかない。


## オプトインリージョン
今回、構築しているリージョンのバーレーンリージョンはオプトインリージョンと呼ばれ、デフォルトで使用することができず、明示的に有効化し使用する必要があります。
現在は以下の4リージョンがあるようですね。

- アフリカ (ケープタウン)
- アジアパシフィック (香港)
- ヨーロッパ (ミラノ)
- 中東 (バーレーン)<br>
https://docs.aws.amazon.com/ja_jp/general/latest/gr/rande-manage.html

今まで他リージョンでも上手くっていたのでオプトインリージョン固有の問題があると推測。

## 検証
・日本 → S3(バーレーン)
　400エラーが出て上手くいかない。
  これを実現するには↓のオプションを追加してあげる必要がある。

```
--endpoint-url https://s3.me-south-1.amazonaws.com
```
　https://github.com/aws/aws-cli/issues/3567

```
$ aws s3 cp ./log.json s3://kurono-access-me/ --region ap-northeast-1 --debug
~略~
2021-09-07 21:16:24,131 - ThreadPoolExecutor-0_0 - urllib3.connectionpool - DEBUG - https://kurono-access-me.s3.ap-northeast-1.amazonaws.com:443 "PUT /log.json HTTP/1.1" 400 None
~略~
```
・バーレーン → S3(日本)
　↑と同じように上手くいかない。

```
$ aws s3 cp ./log.json s3://kurono-access-jp/ --region me-south-1 --debug
~略~
2021-09-07 21:19:01,948 - ThreadPoolExecutor-0_0 - urllib3.connectionpool - DEBUG - https://kurono-access-jp.s3.me-south-1.amazonaws.com:443 "PUT /log.json HTTP/1.1" 400 None
~略~
```

・日本 → S3(バージニア北部)
　適切なリージョンへと**301でリダイレクト**されていることが分かる。
　他のデフォルトであるリージョンを試してみたが同じような結果に。

```
$ aws s3 cp ./log.json s3://kurono-access-us/ --region ap-northeast-1 --debug
~略~
2021-09-07 21:22:17,866 - ThreadPoolExecutor-0_0 - urllib3.connectionpool - DEBUG - https://kurono-access-us.s3.ap-northeast-1.amazonaws.com:443 "PUT /log.json HTTP/1.1" 301 None
2021-09-07 21:22:17,868 - ThreadPoolExecutor-0_0 - botocore.parsers - DEBUG - Response headers: {'x-amz-bucket-region': 'us-east-1', 'x-amz-request-id': '051SQJHPG0RZ4VT5', 'x-amz-id-2': 'tWSa/q0g1g2sQmyk33xa+ydcP7Mdkl7P5bwgWUNJtLBTZoXtIEs+BfFNOnMfiE/aqu6ZrOnSzkc=', 'Content-Type': 'application/xml', 'Transfer-Encoding': 'chunked', 'Date': 'Tue, 07 Sep 2021 12:22:17 GMT', 'Server': 'AmazonS3', 'Connection': 'close'}
~略~
```
## まとめ
・参考となる文献は見つけられていないがオプトインリージョンはエンドポイントの互換性が無く、
　明示的にリージョン(エンドポイント)を指定してあげないと上手くいかない。
 
・中々、オプトインリージョンを使うことはないかもしれませんが、誰かの役に立てばと思います。