期間制約を考慮したS3ストレージクラスのライフサイクル設定
ストレージクラスの移行
S3ではライフサイクルを使用することでオブジェクトのストレージクラスを移行することができる。ストレージクラスを変更することで、可用性と価格を制御することができる。
移行元と移行先のストレージクラスには制約があり、任意のストレージクラス間で変更できるわけではない。サポートされているストレージクラスの移行は以下の通り。
ストレージクラスの移行に伴う最小日数
ストレージクラスの変更について、種類だけでなく日数に関する制約も存在する。具体的には以下の通り。
ストレージクラス | 最小ストレージ期間 |
---|---|
Standard IA | 30日 |
One Zone IA | 30日 |
Glacier Instant Retrieval | 90日 |
Glacier Flexible Retrieval | 90日 |
Glacier Deep Archive | 180日 |
その他 | なし |
ただし、Standard IAおよびOne Zone IAに対する最小ストレージ期間の意味と、Glacier系に対する最小ストレージ期間の意味は少し異なる。
Standard IAおよびOne Zone IAは最小ストレージ期間以下のオブジェクトは許容されない。すなわち、作成してから29日以下のオブジェクトをStandard IAまたはOne Zone IAに移行することはできない。このようなライフサイクル設定を作成しようとするとエラーになってしまう。
一方でGlacier系は最小ストレージ期間を下回るオブジェクトは作成可能だが、料金は最小ストレージ期間の分だけ請求される。このため、オブジェクト作成直後にGlacierのストレージクラスに移行するライフサイクル設定を作成することは可能。
これについても公式ドキュメントに記載がある。
S3 標準 - IA または S3 1 ゾーン - IA にオブジェクトを移行する前に、これらのオブジェクトを少なくとも 30 日間 Amazon S3 に保存する必要があります。例えば、作成から 1 日後にオブジェクトを S3 標準 – IA ストレージクラスに移行するライフサイクルルールを作成することはできません。
Amazon S3 Glacier にアーカイブされているデータの削除は、削除するオブジェクトが最小ストレージ期間より長い期間アーカイブされている場合は無料です。アーカイブされたオブジェクトを最小ストレージ期間以内に削除または上書きする場合は、Amazon S3 によって比例配分された早期削除料金が課金されます。
terraformによる移行日数の指定
terraformでS3のライフサイクルを指定するには aws_s3_bucket_lifecycle_configuration
リソースを利用する。公式ドキュメントに記載の通り以下のように設定可能。
resource "aws_s3_bucket_lifecycle_configuration" "example" {
bucket = aws_s3_bucket.example.id
rule {
id = "rule-1"
status = "Enabled"
transition {
days = 30
storage_class = "STANDARD_IA"
}
transition {
days = 60
storage_class = "GLACIER"
}
}
}
ただし、ドキュメントに記載の通り対象のストレージクラスによって指定可能な日数は異なる。
設定不可能な日数を指定するとterraform apply時にエラーになる。具体的なエラーメッセージは以下の通り。
Valid values depend on storage_class, see Transition objects using Amazon S3 Lifecycle for more details.
$ cat main.tf
resource "aws_s3_bucket" "example" {
bucket = "sample-lifecycle-configuration-min-duration"
}
resource "aws_s3_bucket_lifecycle_configuration" "example" {
bucket = aws_s3_bucket.example.id
rule {
id = "example-rule"
status = "Enabled"
transition {
storage_class = "ONEZONE_IA"
}
}
}
$ terraform apply
...
╷
│ Error: updating S3 Bucket Lifecycle Configuration (sample-lifecycle-configuration-min-duration): operation error S3: PutBucketLifecycleConfiguration, https response error StatusCode: 400, RequestID: TZJVZJ0AEA87Q25D, HostID: h6xl6MDiy3B1fsOmhN8yxG6DmsTAZruFAftZksmZ168+DTO82ITul1tAr320LvEI6ENr2yx/uPc=, api error InvalidArgument: 'Days' in Transition action must be greater than or equal to 30 for storageClass 'ONEZONE_IA'
│
│ with aws_s3_bucket_lifecycle_configuration.example,
│ on main.tf line 5, in resource "aws_s3_bucket_lifecycle_configuration" "example":
│ 5: resource "aws_s3_bucket_lifecycle_configuration" "example" {
│
╵
より詳細なapply errorとなる条件は以下の通り。
- storage_classに"STANDARD_IA" または "ONEZONE_IA"を指定しており、daysの指定が30未満
daysの指定が30未満、またはdaysもdateも指定しないとdaysに0が指定されたものと見なされるのでこれもエラーになる。明示的に30以上の日数を指定する必要がある。
resource "aws_s3_bucket_lifecycle_configuration" "example" {
bucket = aws_s3_bucket.example.id
rule {
id = "example-rule"
status = "Enabled"
transition {
days = 3
storage_class = "ONEZONE_IA"
}
}
}
- 複数のtransitionルールを指定しており、日数の条件が移行可能なストレージ間に対応していない
30日経過したらONEZONE_IAに、60日経過したらGLACIERに移行するというルールはSTANDARD -> ONEZONE_IA -> GLACIERというストレージクラス間の移行が許容されているので設定できる。
resource "aws_s3_bucket_lifecycle_configuration" "example" {
bucket = aws_s3_bucket.example.id
rule {
id = "example-rule"
status = "Enabled"
transition {
days = 30
storage_class = "ONEZONE_IA"
}
transition {
days = 60
storage_class = "GLACIER"
}
}
}
逆に、30日経過したらGLACIER、60日経過したらSTANDARD_IAに移行するというルールは GLACIER -> STANDARD_IAのストレージクラス間移行が許容さていないので設定できない。
同様に、ONEZONE_IA -> STANDARD_IAの移行も許容されていないので、STANDARD_IAのtransition.daysはONEZONE_IAのtransition.daysより大きな値を指定しなくてはならない
resource "aws_s3_bucket_lifecycle_configuration" "example" {
bucket = aws_s3_bucket.example.id
rule {
id = "example-rule"
status = "Enabled"
transition {
days = 30
storage_class = "GLACIER"
}
transition {
days = 60
storage_class = "ONEZONE_IA"
}
}
}
$ terraform apply
...
aws_s3_bucket_lifecycle_configuration.example: Modifying... [id=sample-lifecycle-configuration-min-duration]
╷
│ Error: updating S3 Bucket Lifecycle Configuration (sample-lifecycle-configuration-min-duration): operation error S3: PutBucketLifecycleConfiguration, https response error StatusCode: 400, RequestID: GYDRVEMB933B3393, HostID: e3TiVNz0ksNdethv7psJUFIl+ii30LjfUiq5J6c4uMr6f/WxFyhbkqvJ7jUbFB4IVjc9VHifA5lN+o9OZ77+8w==, api error InvalidArgument: 'Days' in the 'Transition' action for StorageClass 'GLACIER' for filter '(prefix=)' must be greater than 'Days' in the 'Transition' action for StorageClass 'ONEZONE_IA' for filter '(prefix=)'
│
│ with aws_s3_bucket_lifecycle_configuration.example,
│ on main.tf line 5, in resource "aws_s3_bucket_lifecycle_configuration" "example":
│ 5: resource "aws_s3_bucket_lifecycle_configuration" "example" {
│
╵
エラーにならないケースとして、dateを指定する場合がある。
AWSマネコン上では指定できないが、terraformなどのAPIでは移行を実施する日付(date)を指定できる。日付指定の場合はライフサイクル設定作成時ではエラーにならなかった。
未検証だが、ストレージクラスにSTANDARD_IAを指定した場合、Dateで移行日を指定できるが、移行日に条件を満たしていない生成から30日未満のオブジェクトは単に無視される?
Discussion