SAA合格への道 - Week1 Day3〜5 - 私の知らないS3

# この記事について

AWS-SAAに今年合格しようというメンバーで勉強会を立ち上げました。

EC2やS3などの基本的なサービスの深い知識が結局いちばんよく問われる、ということで、そちらを勉強することに。

その中でS3について学んでいたら、「これ私の知ってるS3じゃない」という機能や特性がいろいろ出てきたのでまとめます。

# 教材

こちら↓のS3のコーナーを受講していてびっくりした内容をもとに・・・

https://www.udemy.com/course/aws-knan/

こちら↓のS3のコーナーにもとづきハンズオンを実施しながら、ポイントをまとめていきます。

https://www.udemy.com/course/aws-certified-solutions-architect-associate-saa-c03/

# 学んだこと

## 基本概念

### bucket

#### リージョン

S3自体はグローバルサービスだが、バケットはリージョンごとに作られる。

:::note
なるほど、S3のビューからは全リージョンのバケットが参照できるが、各バケットはリージョンに紐づいている。そういうことか。
:::

#### ネーミングルール

- 3〜63文字で、大文字とアンスコは使えない
- 開始文字は英小文字か数字
- xn-- で始まる名前はNG
- -s3alias で終わる名前はNG


### オブジェクト

#### データ構造

S3のオブジェクトは Key-value 構造であるということ。

見た目上はディレクトリ構造みたいに見えるが、実体はパスが key, ファイルの中身が value という key-value構造になっている。

例えばフルパスが以下だとすると…

`s3://bucket-name/folder1/folder2/filename.txt`

キーは `folder1/folder2/filename.txt` の部分

:::note warn
この点は、初心者がつまづきやすいポイントらしい。
私ももれなくつまづきました。
:::

#### サイズ

- 1オブジェクトの最大サイズは5TB
- 5GB以上のオブジェクトをアップロードする場合、 multi-part アップロードを使うべし

#### メタデータ

- key-value ペアのメタデータを持っている
- ユーザーが設定するメタデータの代表格はタグ
- システムが設定するメタデータの代表格は Version ID （バージョニングが有効化されている場合）

### プリフィックス

`s3://バケット名/folder1/folder2/file.txt` における `/folder1/folder2/` 部分をS3のプリフィックスという。

## S3のセキュリティ

### アクセス制御

#### わかりやすい例

![Screen Shot 2024-02-02 at 10.10.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/eca264d2-27a3-a50c-3d21-c4c158612fdd.png)

右上のボタンでファイルの中身を必ず参照できるのは、このボタンでは認証情報をエンコードしたURLのリンクに飛ぶから。

ObjectURLは、パブリックURLだが、これを参照できるかどうかはS3自体に設定したパブリックアクセスの許可の有無による。

#### ユーザーベースのアクセス制御

- IAMポリシーに基づき、どのAPIコールをどのIAMユーザーが実行できるかを制御する
- IAM ユーザーに対するポリシー ＆ IAM Role による特定のリソースからのアクセス許可もここに含まれる
- 同じAWSアカウント内でのアクセス制御に使用
- アクセス元のIPやドメイン単位でのアクセス制御も可能

#### リソースベースのアクセス制御

##### バケットポリシー

- S3のコンソール上で、バケットレベルのアクセスを管理する
- クロスアカウントで設定できる
- オブジェクトをパブリックにする設定もここでやる

パブリックアクセスを許可するバケットポリシーはこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/468cc066-385f-1901-5fde-ada9797da7f5.png)

:::note warn
上記を設定しても、S3の設定でパブリックアクセスのブロックを有効にしている場合は、ブロックが勝つ。
:::

- アクセス元のIPやドメイン単位でのアクセス制御も可能
- **暗号化の強制**ができるのはこれだけ
- 他のAWSアカウントからアップロードされたオブジェクトへのコントロール権限をバケット所有者に付与する際もこれを使う

:::note warn
バケットの所有者は、他のAWSアカウントからアップロードされたオブジェクトに対するフルコントロール権限をデフォルトで持っているわけではない
:::

##### ACL(Access Control List)

- オブジェクトレベル、バケットレベルで設定できる
- アクセス元のIPやドメイン単位でのアクセス制御は**できない**

#### アカウントレベルのアクセス制御

パブリックアクセスの拒否は、アカウントレベルでも設定できる。

#### S3にアクセスできる条件

- ユーザーがIAMのパーミッションを持っている **または** リソースポリシーでアクセスが許可されている
- 上記 **かつ** 明示的な DENY の条件が定義されていない

#### 署名付きURL

AWSアカウントを持っていないユーザーに、非公開設定されたS3のデータにアクセスを許す唯一の方法がこれ。

:::note warn
認証機能がないのでセキュリティ的にはどうか。
:::

### 暗号化

暗号化キーを使って、S3のオブジェクトを暗号化できる

#### SSE

SSE は、Server Side Encryptionの略。
SSE には、誰が管理している（どこの）鍵を使うかによっていくつかの方式がある。

SSE (**Server Side** Encryption) の名前のとおり、**暗号化はいずれの方式でもS3が行う**。

- SSE-S3
    - S3が管理している鍵を使う
- SSE-KMS
    - AWS KMS に保存されているキーを使う
- SSE-C
    - ユーザーが管理している鍵を使う

#### クライアント側での暗号化

上記以外に、当然ながらクライアント側で暗号化してからデータをS3に上げる方法もある。

### オブジェクトロック

保持期間が無期限の「リーガルホールド」と、期限付きの「リテンションモード」の2種類がある。
「リテンションモード」には、「ガバナンスモード」と「コンプライアンスモード」がある。

#### リーガルホールド

特定の権限 `s3:PutObjectLegalHold` をを持たないユーザーに対して、オブジェクトを読み取り専用にする。

期限は無期限（リーガルホールドが解除されるまで）。

#### リテンションモード

##### ガバナンスモード

権限（s3:BypassGovernanceRetention）を持たないユーザーに対して、指定した保持期間中オブジェクトを読み取り専用にする。

権限を持つユーザーは、オブジェクトの更新・削除と、ガバナンスモードの解除ができる。

##### コンプライアンスモード

ルートを含むすべてのユーザーに対して、指定した保持期間中オブジェクトを読み取り専用にする。

保持期間中はルートユーザーを含めてコンプライアンスモードを解除できない。

:::note warn
何のための機能なんだこれは
:::

## バージョニング

### 有効化方法

Bucket のプロパティからバージョンをONにして、オブジェクトの一覧で show versions のトグルをONにすると以下のように表示される。

![Screen Shot 2024-02-02 at 12.54.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/5205314f-d4a1-f37c-5057-ecbe45c97b1c.png)

:::note warn
バージョンのIDは通番ではないんですね。
:::

:::note
バージョンIDが null のファイルは、バージョニングを有効化する前に作成したもの。
:::

### 特定バージョンの削除方法

バージョンを表示した一覧から、特定のバージョンを指定して削除する。

![Screen Shot 2024-02-02 at 12.56.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/68296554-123a-7d6e-ff76-a8e539195d9e.png)

-> index.html を 静的Webサイト（後述）のホームページに使っていた場合は、ひとつ前のバージョンに自動で戻る。

### 論理削除

バージョンを表示しない一覧からオブジェクトを削除すると、削除は物理削除ではなく「削除状態」として扱われる。（論理削除的なことができる）

![Screen Shot 2024-02-02 at 13.02.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/a0e4267f-8b8d-ac70-a7c9-833c3de7d73d.png)

すると、バージョン表示なしの一覧からはオブジェクトが見えなくなるが、バージョンを表示すると、「削除マーカーつきのオブジェクトが最新状態になっている」ような状態になっている。

![Screen Shot 2024-02-02 at 13.02.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/c9815f97-0c38-7837-6c98-40d2973e1418.png)

ここから、「削除マーカーつきのオブジェクト」を削除することでオブジェクトを復旧することができる。

### MFA Delete

バージョニング機能を使用して管理されているオブジェクトを削除する際に、MFAデバイスの認証が必要となる機能。

**これを有効にすると、世代管理されたデータの物理削除権限をルートユーザーのみが持つようになる。**

:::note
誤削除を何が何でも防ぎたい場合の設定か。
:::

## レプリケーション

### レプリケーションの前提条件

- 非同期のレプリケーション
- レプリケーション元とレプリケーション先のバージョニングを共に有効にしておく必要あり
- レプリケーション元と先は、同じリージョン、クロスリージョン、異なるAWSアカウントのいずれでも可
    - 同じリージョンのレプリケーション：SRR(Same Region Replication)
    - 別リージョン間のレプリケーション：CRR(Cross Region Replication)
- 適切な IAM permission が必要

### レプリケーションの対象

#### 新規オブジェクト／既存オブジェクト

- レプリケーションを有効にした後に追加されたオブジェクトのみがレプリケーション対象となる
- 既存のオブジェクトをレプリケーションしたいときは、 S3 Batch Replication を使う

#### 削除の場合

- 論理削除の状態はレプリケーションの対象となる
- 元のファイルが物理削除された場合、レプリケーション先のファイルが物理削除されることはない（悪意のあるオペレーションを防ぐためらしい）

#### バージョニングの連鎖は行わない

bucketA のレプリケーション先が bucketBで、bucketB のレプリケーション先が bucketC の場合、bucketAに作成されたファイルは bucketC にはレプリケーション **されない**

:::note warn
・・・なんで（・＿・；）？ かつ、ほんとか・・・（・＿・；）？
と思いましたが、挙動を確認したら本当でした。
:::

### レプリケーションのユースケース

- CRR のユースケース
    - コンプラ対応、DR
    - アカウントまたぎのレプリケーション
    - 低レイテンシの実現

- SRR のユースケース
    - ログ収集
    - 本番・テスト間でのデータレプリケーション

:::note warn
本番とテストでデータをレプリケーションって・・・やっていいの？？
:::

## ストレージクラス

ストレージクラス（Glacier とか Standard-IAとか）は bucket やフォルダの単位ではなく、**オブジェクト単位**のプロパティとして設定できるということを初めて知った。

ライフサイクルマネジメント（作成から◯日後にどこのクラスに移すとか）は、 **Bucket 単位** のルールとして設定する。

## S3のパフォーマンス

### デフォルトのパフォーマンス

- PUT/COPY/POST/DELETE -> 3500リクエスト / 秒 / プリフィックス
- GET/HEAD -> 5500リクエスト / 秒 / プリフィックス

### パフォーマンス向上ための方法

#### Multi-part アップロード

大きなファイルを細かいパートに分けてパラレルでアップロードする方法。
パラでアップしているすべてのセッションに対して、AWSのストレージクラスに応じた料金が課金される仕組みらしい。

- 100MB超の場合は推奨
- 5GB超の場合は必須

#### S3 Transfer Acceleration

- ファイルをAWSのエッジロケーションに置くことで転送スピードを速くする方法
- Multi-part upload にも対応している

:::note
そもそもエッジロケーションとは
日本に住んでいて、S3がアメリカにある場合などに、日本国内にEdgeロケーションというサービスを置くことができる。
国内の通信はインターネット経由、エッジロケーションからS3の通信はAWSのプライベートネットワークを使うことにより、インターネット上を通る経路を短くするとともに、パフォーマンスを向上させるなどの効果がある。
:::

#### バイトの範囲を指定した Fetch

- multi-part アップロードの逆（大きなS3ファイルをGetする際に、パートに分けてパラで処理する）
- ファイルの一部だけを取得する

## その他の Advanced Features

### S3 select / Glacier select

- SQLをつかってサーバサイドでフィルターをかけ、ネットワークやクライアント側のCPUコストを下げる手法
- 行方向でも列方向でもフィルタリングできる
- それの Glacier 版が Glacier select

### S3 バッチオペレーション

#### 利用シーン

以下のような操作をバルクで行う場合に！

- 全オブジェクトのメタデータやプロパティを書き換えたい場合
- S3のバケットから別のバケットに全オブジェクトを移行・コピーしたい場合
- 暗号化されていないオブジェクトを暗号化する場合
- ACLやタグを修正する場合
- S3 Glacier からオブジェクトをリストアする場合
- 各オブジェクトへの操作をキーに Lambda Function の起動の紐付けを行う場合

#### 実行方法

- オブジェクト名、そのアイテムに対する操作、（あれば）パラメータを定義したリストを作成し、そのリストに従って処理する
- オブジェクト名のリストを作成する際は、S3 Inventory という機能を使える
- リトライ、進捗の追跡、完了の通知、レポートの作成にも対応

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/d4c2072f-3df0-3934-fddb-fcb564667045.png)


## S3のユースケース

考えたことがなかったユースケースのみ記載。

### 静的Webサイトをホストする

EC2で立てたWebサーバが画像ファイルなどを取得するアクセス先としてではなく、S3のサービス自体の中でWebサイトをホストすることができる！

:::note warn
S3自体のパブリックアクセス許可が必要であるなど、セキュリティ的には色々あやしそう。。。
:::

### Cloud Front のオリジンとして使う

詳細は、Cloud Front 含めて作ってみたらまた追記します。

# 以上

また何か学んだことがあれば追記します。