Use the OSS Go SDK V2 to create, query, and delete lifecycle rules that automatically transition or expire bucket objects.
Background
Lifecycle rules let you define policies that OSS evaluates against your objects. Each rule performs one of two action types:
Transition — Moves objects to a lower-cost storage class after a specified number of days.
Expiration — Deletes objects (or their noncurrent versions) after a specified number of days.
OSS supports two rule triggers that determine how the day count is measured:
| Trigger | How it works |
|---|---|
| Last modified time | The day count starts from when the object was last written. Use this when objects follow a predictable aging pattern. |
| Last access time | OSS monitors access patterns and tracks when each object was last read. Use this to automatically tier data based on actual usage. |
Learn how each trigger works before configuring rules. See Lifecycle rules based on last modified time and Lifecycle rules based on last access time.
Prerequisites
Before you begin, ensure that you have:
An OSS bucket
Access credentials stored in environment variables. See Configure access credentials
The required RAM permissions:
| Operation | Required permission |
|---|---|
| Set lifecycle rules | oss:PutBucketLifecycle |
| Query lifecycle rules | oss:GetBucketLifecycle |
| Delete all lifecycle rules | oss:DeleteBucketLifecycle |
For details on granting these permissions, see Grant custom policies to RAM users.
Set lifecycle rules
The following examples use cn-hangzhou (China (Hangzhou)) as the region and read credentials from environment variables. By default, a public endpoint is used. If you want to access OSS from other Alibaba Cloud products in the same region, you can use an internal endpoint. For more information, see OSS regions and endpoints.
To modify one or more existing lifecycle rules, see How do I modify one or more lifecycle rule configurations?.
Transition objects based on last modified time
The following example sets two lifecycle rules on a bucket. Both rules use IsAccessTime: false, which means the day count is based on last modified time.
NoncurrentVersionExpirationandNoncurrentVersionTransitionare used for versioning-enabled buckets. WhenExpiredObjectDeleteMarkeris set totrue, if an object has only a delete marker, the delete marker is automatically deleted.
package main
import (
"context"
"flag"
"log"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
var (
region string
bucketName string
)
func init() {
flag.StringVar(®ion, "region", "", "The region in which the bucket is located.")
flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
}
func main() {
flag.Parse()
if len(bucketName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, bucket name required")
}
if len(region) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, region required")
}
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion(region)
client := oss.NewClient(cfg)
request := &oss.PutBucketLifecycleRequest{
Bucket: oss.Ptr(bucketName),
LifecycleConfiguration: &oss.LifecycleConfiguration{
Rules: []oss.LifecycleRule{
{
// rule1: transition objects with prefix "foo/" and tag k1=v1
// to Infrequent Access 30 days after last modified.
Status: oss.Ptr("Enabled"),
ID: oss.Ptr("rule1"),
Prefix: oss.Ptr("foo/"),
Transitions: []oss.LifecycleRuleTransition{
{
Days: oss.Ptr(int32(30)),
StorageClass: oss.StorageClassIA,
IsAccessTime: oss.Ptr(false),
},
},
Tags: []oss.Tag{
{
Key: oss.Ptr("k1"),
Value: oss.Ptr("v1"),
},
},
},
{
// rule2: for objects with prefix "dir/" in a versioning-enabled bucket:
// - Auto-delete expired delete markers (ExpiredObjectDeleteMarker).
// - Expire noncurrent versions after 30 days.
// - Transition noncurrent versions to Infrequent Access after 10 days.
ID: oss.Ptr("rule2"),
Prefix: oss.Ptr("dir/"),
Status: oss.Ptr("Enabled"),
Expiration: &oss.LifecycleRuleExpiration{
Days: oss.Ptr(int32(10)),
ExpiredObjectDeleteMarker: oss.Ptr(true),
},
NoncurrentVersionExpiration: &oss.NoncurrentVersionExpiration{
NoncurrentDays: oss.Ptr(int32(30)),
},
NoncurrentVersionTransitions: []oss.NoncurrentVersionTransition{{
NoncurrentDays: oss.Ptr(int32(10)),
StorageClass: oss.StorageClassIA,
IsAccessTime: oss.Ptr(false),
}},
},
},
},
}
result, err := client.PutBucketLifecycle(context.TODO(), request)
if err != nil {
log.Fatalf("failed to put bucket lifecycle %v", err)
}
log.Printf("put bucket lifecycle result:%#v\n", result)
}Transition objects based on last modified time, with exclusion filters
The following example transitions objects to Infrequent Access 30 days after they are last modified. The rule applies to objects under the logs/ prefix with sizes between 500 and 1000 bytes, but excludes objects with the prefix logs/log or the tag key1=value1.
package main
import (
"context"
"flag"
"log"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
var (
region string
bucketName string
)
func init() {
flag.StringVar(®ion, "region", "", "The region in which the bucket is located.")
flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
}
func main() {
flag.Parse()
if len(bucketName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, bucket name required")
}
if len(region) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, region required")
}
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion(region)
client := oss.NewClient(cfg)
request := &oss.PutBucketLifecycleRequest{
Bucket: oss.Ptr(bucketName),
LifecycleConfiguration: &oss.LifecycleConfiguration{
Rules: []oss.LifecycleRule{
{
// rule1: transition objects under "logs/" to Infrequent Access after 30 days.
// Filter: object size between 500 and 1000 bytes.
// Exclusion (Not): skip objects with prefix "logs/log" or tag key1=value1.
ID: oss.Ptr("rule1"),
Status: oss.Ptr("Enabled"),
Prefix: oss.Ptr("logs/"),
Transitions: []oss.LifecycleRuleTransition{
{
Days: oss.Ptr(int32(30)),
StorageClass: oss.StorageClassIA,
IsAccessTime: oss.Ptr(false),
},
},
Filter: &oss.LifecycleRuleFilter{
ObjectSizeGreaterThan: oss.Ptr(int64(500)),
ObjectSizeLessThan: oss.Ptr(int64(1000)),
Not: &oss.LifecycleRuleNot{
Prefix: oss.Ptr("logs/log"),
Tag: &oss.Tag{
Key: oss.Ptr("key1"),
Value: oss.Ptr("value1"),
},
},
},
},
},
},
}
result, err := client.PutBucketLifecycle(context.TODO(), request)
if err != nil {
log.Fatalf("failed to put bucket lifecycle %v", err)
}
log.Printf("put bucket lifecycle result:%#v\n", result)
}Transition objects based on last access time
The following example sets two lifecycle rules using last access time as the trigger. All transitions set IsAccessTime: true and ReturnToStdWhenVisit: false, which means objects stay in the target storage class even if accessed again.
package main
import (
"context"
"flag"
"log"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
var (
region string
bucketName string
)
func init() {
flag.StringVar(®ion, "region", "", "The region in which the bucket is located.")
flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
}
func main() {
flag.Parse()
if len(bucketName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, bucket name required")
}
if len(region) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, region required")
}
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion(region)
client := oss.NewClient(cfg)
request := &oss.PutBucketLifecycleRequest{
Bucket: oss.Ptr(bucketName),
LifecycleConfiguration: &oss.LifecycleConfiguration{
Rules: []oss.LifecycleRule{
{
// rule1: transition objects under "data/" to Infrequent Access
// 200 days after last accessed. Objects stay in IA even if accessed again.
ID: oss.Ptr("rule1"),
Status: oss.Ptr("Enabled"),
Prefix: oss.Ptr("data/"),
Transitions: []oss.LifecycleRuleTransition{
{
Days: oss.Ptr(int32(200)),
StorageClass: oss.StorageClassIA,
IsAccessTime: oss.Ptr(true),
ReturnToStdWhenVisit: oss.Ptr(false),
},
},
},
{
// rule2: transition objects under "log/" through two stages:
// - Infrequent Access after 120 days of no access.
// - Archive after 250 days of no access.
// Objects stay in the target class even if accessed again.
ID: oss.Ptr("rule2"),
Status: oss.Ptr("Enabled"),
Prefix: oss.Ptr("log/"),
Transitions: []oss.LifecycleRuleTransition{
{
Days: oss.Ptr(int32(120)),
StorageClass: oss.StorageClassIA,
IsAccessTime: oss.Ptr(true),
ReturnToStdWhenVisit: oss.Ptr(false),
},
{
Days: oss.Ptr(int32(250)),
StorageClass: oss.StorageClassArchive,
IsAccessTime: oss.Ptr(true),
ReturnToStdWhenVisit: oss.Ptr(false),
},
},
},
},
},
}
result, err := client.PutBucketLifecycle(context.TODO(), request)
if err != nil {
log.Fatalf("failed to put bucket lifecycle %v", err)
}
log.Printf("put bucket lifecycle result:%#v\n", result)
}Query lifecycle rules
The following example retrieves the lifecycle configuration for a bucket and prints each rule's properties, including transitions, expiration settings, noncurrent version policies, and filters.
package main
import (
"context"
"flag"
"fmt"
"log"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
var (
region string
bucketName string
)
func init() {
flag.StringVar(®ion, "region", "", "The region in which the bucket is located.")
flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
}
func main() {
flag.Parse()
if len(bucketName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, bucket name required")
}
if len(region) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, region required")
}
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion(region)
client := oss.NewClient(cfg)
request := &oss.GetBucketLifecycleRequest{
Bucket: oss.Ptr(bucketName),
}
result, err := client.GetBucketLifecycle(context.TODO(), request)
if err != nil {
log.Fatalf("failed to get bucket lifecycle %v", err)
}
for _, rule := range result.LifecycleConfiguration.Rules {
fmt.Println("Lifecycle Rule Id:", rule.ID)
fmt.Println("Lifecycle Rule Prefix:", rule.Prefix)
fmt.Println("Lifecycle Rule Status:", rule.Status)
if rule.Expiration != nil {
fmt.Println("Lifecycle Rule Expiration Days:", rule.Expiration.Days)
fmt.Println("Lifecycle Rule Expiration Created Before Date:", rule.Expiration.CreatedBeforeDate)
if rule.Expiration.ExpiredObjectDeleteMarker != nil {
fmt.Println("Lifecycle Rule Expiration Expired Object DeleteMarker:", *rule.Expiration.ExpiredObjectDeleteMarker)
}
}
for _, tag := range rule.Tags {
fmt.Println("Lifecycle Rule Tag Key:", tag.Key)
fmt.Println("Lifecycle Rule Tag Value:", tag.Value)
}
for _, transition := range rule.Transitions {
fmt.Println("Lifecycle Rule Transition Days:", transition.Days)
fmt.Println("Lifecycle Rule Transition Created Before Date:", transition.CreatedBeforeDate)
fmt.Println("Lifecycle Rule Transition Storage Class:", transition.StorageClass)
if transition.IsAccessTime != nil {
fmt.Println("Lifecycle Rule Transition Is Access Time:", *transition.IsAccessTime)
}
if transition.ReturnToStdWhenVisit != nil {
fmt.Println("Lifecycle Rule Transition Return To Std When Visit:", *transition.ReturnToStdWhenVisit)
}
if transition.AllowSmallFile != nil {
fmt.Println("Lifecycle Rule Transition Allow Small File:", *transition.AllowSmallFile)
}
}
if rule.AbortMultipartUpload != nil {
fmt.Println("Lifecycle Rule Abort Multipart Upload Days:", rule.AbortMultipartUpload.Days)
fmt.Println("Lifecycle Rule Abort Multipart Upload Created Before Date:", rule.AbortMultipartUpload.CreatedBeforeDate)
}
if rule.NoncurrentVersionTransitions != nil {
for _, nonVersionTransition := range rule.NoncurrentVersionTransitions {
fmt.Println("Lifecycle Rule Non Version Transitions Non current Days:", nonVersionTransition.NoncurrentDays)
fmt.Println("Lifecycle Rule Non Version Transition Storage Class:", nonVersionTransition.StorageClass)
if nonVersionTransition.IsAccessTime != nil {
fmt.Println("Lifecycle Rule Non Version Transition Is Access Time:", *nonVersionTransition.IsAccessTime)
}
if nonVersionTransition.ReturnToStdWhenVisit != nil {
fmt.Println("Lifecycle Rule Non Version Transition Return To Std When Visit:", *nonVersionTransition.ReturnToStdWhenVisit)
}
if nonVersionTransition.AllowSmallFile != nil {
fmt.Println("Lifecycle Rule Non Version Allow Small File:", *nonVersionTransition.AllowSmallFile)
}
if rule.Filter != nil {
if rule.Filter.ObjectSizeGreaterThan != nil {
fmt.Println("Lifecycle Rule Filter Object Size Greater Than:", *rule.Filter.ObjectSizeGreaterThan)
}
if rule.Filter.ObjectSizeLessThan != nil {
fmt.Println("Lifecycle Rule Filter Object Size Less Than:", *rule.Filter.ObjectSizeLessThan)
}
if rule.Filter.Not != nil {
fmt.Println("Lifecycle Rule Filter Not Prefix:", rule.Filter.Not.Prefix)
if rule.Filter.Not.Tag != nil {
fmt.Println("Lifecycle Rule Filter Not Tag Key:", rule.Filter.Not.Tag.Key)
fmt.Println("Lifecycle Rule Filter Not Tag Value:", rule.Filter.Not.Tag.Value)
}
}
}
}
}
}
}Delete all lifecycle rules
The following example deletes all lifecycle rules from a bucket. To delete specific rules instead of all of them, see Delete one or more lifecycle rules.
package main
import (
"context"
"flag"
"log"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
var (
region string
bucketName string
)
func init() {
flag.StringVar(®ion, "region", "", "The region in which the bucket is located.")
flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
}
func main() {
flag.Parse()
if len(bucketName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, bucket name required")
}
if len(region) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, region required")
}
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion(region)
client := oss.NewClient(cfg)
request := &oss.DeleteBucketLifecycleRequest{
Bucket: oss.Ptr(bucketName),
}
result, err := client.DeleteBucketLifecycle(context.TODO(), request)
if err != nil {
log.Fatalf("failed to delete bucket lifecycle %v", err)
}
log.Printf("delete bucket lifecycle result:%#v\n", result)
}