はじめに
FusicAdventCalendar2025 12日目です!
株式会社Fusicでエンジニアをしている山本です。
昨日は@Junkinsさんの 用語整理に関する個人的なノウハウのまとめ でした。
今回の記事では、S3オブジェクトのストレージクラス制御についてご紹介いたします。
S3 には複数のストレージクラスが用意されており、利用頻度に応じて最適なコストで運用できます。
年に 1 回読み出すかどうかといったオブジェクトであれば、最も低コストな Glacier Deep Archive(以下 Glacier) を利用するのが一般的と思います。
ストレージクラスの変更方法として、AWS コンソール操作があり、対象オブジェクトを選択して「ストレージクラスを編集する」を選べば簡単に Glacier 化できます。しかし、これをAWS CLI を用いてプログラムで制御しようとすると、状態によって挙動が異なるため注意が必要です。
この記事では、S3 オブジェクトの Glacier 化・復元処理を自前で実装する際に理解しておきたい 状態と API の返却値の関係、そして注意点 をまとめます。
前提
今回は次の 2 種類のみを扱います。
・Standard
・Glacier Deep Archive(以下 Glacier)
Standard → Glacier への移行(凍結)
Glacier → Standard のような挙動を可能にする復元(解凍)
を CLI ベースのプログラムで実現することを想定します。
なお、本記事では具体的なソースコードの記載はありません。
オブジェクトの状態と storage_class の関係
プログラムでは一般的に次のことを実行します。
・Standard → Glacier へ変更するコマンドを発火
・Glacier → 復元コマンドを発火
そのためには「いまこのオブジェクトはどのストレージクラスなのか?」を取得する必要があります。
しかし、S3 では 変更中や復元中といった中間状態が存在し、APIで取得可能な storage_class が期待どおり変化しないケースがあります。
実際の挙動をまとめると次の通りです。
| 状態 | APIで取得したstorage_class |
|---|---|
| Standard | Standard |
| StandardからGlacierに凍結中 | Standard |
| Glacier | Glacier |
| Glacierから復元中 | Glacier |
| Glacierを復元した※ | Glacier |
| 復元したGlacierを再度凍結中 | Glacier |
特に重要なのは 「Glacier を復元した」後も storage_class は Glacier のまま という点です。
これにより、単純に storage_class だけを見ると、
・すでに復元済みのオブジェクトを “Standard と同様に扱う” 判定ができない
という問題が発生します。
復元済み Glacier を見分ける方法:RestoreStatus
S3のオブジェクトのプロパティとして RestoreStatus というフィールドを取得できます。
これは「復元されたかどうか」を返すもので、復元が完了した Glacier は RestoreStatus=true になります。
そのため、前述の判定は次のように修正できます。
・Standard
・storage_class = Glacier かつ RestoreStatus=true
上記のどちらかであれば、「Glacier 化(再凍結)対象」として扱うことが可能になります。
状態ごとのリクエスト結果:排他制御の観点から
プログラムで安全に処理するためには、
「どの状態でどのリクエストが成功し、どれがエラーになるか」
を確認しておくことが重要です。
以下は、各状態に対して Glacier 化リクエスト / 復元リクエストを発火した結果です。
| 状態 | Glacier化リクエストを発火 | 復元リクエストを発火 |
|---|---|---|
| Standard | 受け付ける | エラーとなる Restore is not allowed for the object's current storage class |
| StandardからGlacierに凍結中 | 受け付ける | エラーとなる Restore is not allowed for the object's current storage class |
| Glacier | エラーとなる Unable to perform copy operations on GLACIER objects | 受け付ける |
| Glacierから復元中 | エラーとなる Unable to perform copy operations on GLACIER objects | エラーとなる Object restore is already in progres |
| Glacierを復元した | 受け付ける | 受け付ける(ただ、何も起きない) |
| 復元したGlacierを再度凍結中 | (タイミングが短く実証不可) | (タイミングが短く実証不可) |
ポイントは次の 2 つです。
- 状態と矛盾するリクエストは基本的にエラーになる
- 状態遷移中のリクエストは受け付けられない
つまり、排他制御や状態管理を丁寧に実装しないと、意図しないエラーが発生しうるということです。
まとめ
S3 のストレージクラスを自前プログラムで制御する場合、
storage_class の文字列だけで判別するのではなく、RestoreStatus を併用するのが理想です。
特に Glacier → 復元済み状態では storage_class が変わらないため、
・Glacier なのにダウンロードできる
・Glacier なのに再度 Glacier 化できる
といった一見矛盾した挙動が起きます。
こうした S3 の仕様を踏まえて判定処理を組むことで、より堅牢なプログラムを実装できます。