

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用適用於目錄儲存貯體的 S3 生命週期
<a name="directory-buckets-objects-lifecycle"></a>

 S3 生命週期可協助您將物件儲存在 S3 Express One Zone 中，透過代表您刪除過期物件來實現目錄儲存貯體成本效益。若要管理物件的生命週期，請為您的目錄儲存貯體建立 S3 生命週期組態。S3 生命週期組態是一組定義 Amazon S3 動作的規則，適用於一組物件。您可以使用 AWS 命令列界面 (AWS CLI)、 AWS SDKs、Amazon S3 REST API 和 AWS CloudFormation，在目錄儲存貯體上設定 Amazon S3 生命週期組態。

在生命週期組態中，您可以使用規則來定義希望 Amazon S3 對物件採取的動作。對於儲存在目錄儲存貯體中的物件，您可以建立生命週期規則，在物件老化時使這些物件過期。您也可以建立生命週期規則，每天刪除目錄儲存貯體中未完成的分段上傳。

當您新增儲存貯體的生命週期組態時，組態規則會套用至現有物件以及稍後新增的物件。例如，如果您目前所新增生命週期組態規則包含過期動作，會讓具有特定字首的物件在建立 30 天之後過期，則 S3 會將任何超過 30 天且具有指定字首的現有物件排入佇列，等待移除。

## 適用於目錄儲存貯體的 S3 生命週期有何不同
<a name="directory-bucket-lifecycle-differences"></a>

對於目錄儲存貯體中的物件，您可以建立生命週期規則來使物件過期，並刪除未完成的分段上傳。不過，適用於目錄儲存貯體的 S3 生命週期不支援在儲存類別之間進行轉換的動作。

**CreateSession**

生命週期使用公有 `DeleteObject` 和 `DeleteObjects` API 操作來使目錄儲存貯體中的物件過期。若要使用這些 API 操作，S3 生命週期會使用 `CreateSession` API 建立臨時安全憑證，以存取目錄儲存貯體中的物件。如需詳細資訊，請參閱 [Amazon S3 API 參考**中的`CreateSession`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateSession.html)。

如果您有拒絕刪除生命週期主體許可的作用中政策，此政策將使您無法允許 S3 生命週期代表您刪除物件。

### 使用儲存貯體政策授予 S3 生命週期服務主體許可
<a name="lifecycle-directory-bucket-policy"></a>

下列儲存貯體政策會授予 S3 生命週期服務主體許可，以建立執行 `DeleteObject`和 等操作的工作階段`DeleteObjects`。在`CreateSession`請求中未指定工作階段模式時，工作階段會由 中的許可以最大允許權限建立 (`ReadWrite`首先嘗試，如果`ReadWrite`不允許 `ReadOnly` )。不過，`ReadOnly`工作階段不足以進行修改或刪除物件的生命週期操作。因此，此範例使用 `s3express:SessionMode`條件索引鍵明確需要`ReadWrite`工作階段模式。

**Example – 允許使用明確`ReadWrite`工作階段模式進行生命週期操作的`CreateSession`呼叫的儲存貯體政策**  

```
 { 
   "Version":"2008-10-17",		 	 	  
   "Statement":[
      {
         "Effect":"Allow",
         "Principal": {
            "Service":"lifecycle.s3.amazonaws.com"
          },
          "Action":"s3express:CreateSession", 
          "Condition": { 
             "StringEquals": {
                "s3express:SessionMode": "ReadWrite"
              }
           }, 
           "Resource":"arn:aws:s3express:us-east-2:412345678921:bucket/amzn-s3-demo-bucket--use2-az2--x-s3"
       }
   ] 
}
```

### 監控生命週期規則
<a name="lifecycle-directory-bucket-monitoring"></a>

對於存放在目錄儲存貯體中的物件，S3 生命週期會產生 AWS CloudTrail 管理和資料事件日誌。如需詳細資訊，請參閱 [S3 Express One Zone 的 CloudTrail 日誌檔案範例](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-log-files.html)。

如需建立生命週期組態及對 S3 生命週期相關問題進行故障診斷的詳細資訊，請參閱下列主題：

**Topics**

# 為目錄儲存貯體建立和管理生命週期組態
<a name="directory-bucket-create-lc"></a>

您可以使用 (AWS CLI)、 AWS Command Line Interface AWS SDKs和 REST APIs 來建立目錄儲存貯體的生命週期組態。

## 使用 AWS CLI
<a name="set-lifecycle-config-cli"></a>

您可以使用下列 AWS CLI 命令來管理 S3 生命週期組態：
+ `put-bucket-lifecycle-configuration`
+ `get-bucket-lifecycle-configuration`
+ `delete-bucket-lifecycle`

如需設定 的指示 AWS CLI，請參閱《[Amazon S3 API 參考》中的使用 AWS CLI 開發](https://docs.aws.amazon.com/AmazonS3/latest/API/setup-aws-cli.html) Amazon S3。 *Amazon S3 *

Amazon S3 生命週期組態是 XML 檔案。但是，當您使用 時 AWS CLI，您無法指定 XML 格式。您必須改為指定 JSON 格式。以下是範例 XML 生命週期組態，以及您可以在 AWS CLI命令中指定的同等 JSON 組態。

下列 AWS CLI 範例會在目錄儲存貯體上放置生命週期組態政策。此政策指定，所有包含標記字首 (myprefix) 並具有定義物件大小的物件會在 7 天後過期。若要使用此範例，請以您自己的資訊取代每個*使用者輸入預留位置*。

將生命週期組態原則儲存至 JSON 檔案。在此範例中，檔案會命名為 lifecycle1.json。

**Example**  

```
{
    "Rules": [
        {
        "Expiration": {
            "Days": 7
        },
        "ID": "Lifecycle expiration rule",
        "Filter": {
            "And": {
                "Prefix": "myprefix/",
                "ObjectSizeGreaterThan": 500,
                "ObjectSizeLessThan": 64000
            }
        },
        "Status": "Enabled"
    }
    ]
}
```
提交 JSON 檔案以做為 `put-bucket-lifecycle-configuration` CLI 命令的一部分。若要使用此命令，請以您自己的資訊取代每個*使用者輸入預留位置*。  

```
aws s3api put-bucket-lifecycle-configuration --region us-west-2 --profile default --bucket amzn-s3-demo-bucket--usw2-az1--x-s3 --lifecycle-configuration file://lc-policy.json --checksum-algorithm crc32c 
```

**Example**  

```
<LifecycleConfiguration>
    <Rule>
        <ID>Lifecycle expiration rule</ID>
        <Filter>
            <And>
                <Prefix>myprefix/</Prefix>
                <ObjectSizeGreaterThan>500</ObjectSizeGreaterThan>
                <ObjectSizeLessThan>64000</ObjectSizeLessThan>
            </And>
        </Filter>
        <Status>Enabled</Status>     
        <Expiration>
             <Days>7</Days>
        </Expiration>
    </Rule>
</LifecycleConfiguration>
```

## 使用 AWS SDKs
<a name="directory-bucket-upload-sdks"></a>

------
#### [ SDK for Java ]

**Example**  

```
import software.amazon.awssdk.services.s3.model.PutBucketLifecycleConfigurationRequest;
import software.amazon.awssdk.services.s3.model.PutBucketLifecycleConfigurationResponse;
import software.amazon.awssdk.services.s3.model.ChecksumAlgorithm;
import software.amazon.awssdk.services.s3.model.BucketLifecycleConfiguration;
import software.amazon.awssdk.services.s3.model.LifecycleRule;
import software.amazon.awssdk.services.s3.model.LifecycleRuleFilter;
import software.amazon.awssdk.services.s3.model.LifecycleExpiration;
import software.amazon.awssdk.services.s3.model.LifecycleRuleAndOperator;
import software.amazon.awssdk.services.s3.model.GetBucketLifecycleConfigurationResponse;
import software.amazon.awssdk.services.s3.model.GetBucketLifecycleConfigurationRequest;
import software.amazon.awssdk.services.s3.model.DeleteBucketLifecycleRequest;
import software.amazon.awssdk.services.s3.model.DeleteBucketLifecycleResponse;
import software.amazon.awssdk.services.s3.model.AbortIncompleteMultipartUpload;

// PUT a Lifecycle policy
LifecycleRuleFilter objectExpirationFilter = LifecycleRuleFilter.builder().and(LifecycleRuleAndOperator.builder().prefix("dir1/").objectSizeGreaterThan(3L).objectSizeLessThan(20L).build()).build();
LifecycleRuleFilter mpuExpirationFilter = LifecycleRuleFilter.builder().prefix("dir2/").build();
       
LifecycleRule objectExpirationRule = LifecycleRule.builder().id("lc").filter(objectExpirationFilter).status("Enabled").expiration(LifecycleExpiration.builder()
                    .days(10)
                    .build())
                .build();
LifecycleRule mpuExpirationRule = LifecycleRule.builder().id("lc-mpu").filter(mpuExpirationFilter).status("Enabled").abortIncompleteMultipartUpload(AbortIncompleteMultipartUpload.builder()
                        .daysAfterInitiation(10)
                        .build())
                .build();
        
PutBucketLifecycleConfigurationRequest putLifecycleRequest = PutBucketLifecycleConfigurationRequest.builder()
                .bucket("amzn-s3-demo-bucket--usw2-az1--x-s3")
                .checksumAlgorithm(ChecksumAlgorithm.CRC32)
                .lifecycleConfiguration(
                        BucketLifecycleConfiguration.builder()
                                .rules(objectExpirationRule, mpuExpirationRule)
                                .build()
                ).build();

PutBucketLifecycleConfigurationResponse resp = client.putBucketLifecycleConfiguration(putLifecycleRequest);

// GET the Lifecycle policy 
GetBucketLifecycleConfigurationResponse getResp = client.getBucketLifecycleConfiguration(GetBucketLifecycleConfigurationRequest.builder().bucket("amzn-s3-demo-bucket--usw2-az1--x-s3").build());

// DELETE the Lifecycle policy
DeleteBucketLifecycleResponse delResp = client.deleteBucketLifecycle(DeleteBucketLifecycleRequest.builder().bucket("amzn-s3-demo-bucket--usw2-az1--x-s3").build());
```

------
#### [ SDK for Go ]

**Example**  

```
package main

import (
    "context"
    "log"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/service/s3/types"
)
// PUT a Lifecycle policy
func putBucketLifecycleConfiguration(client *s3.Client, bucketName string ) error {
    lifecycleConfig := &s3.PutBucketLifecycleConfigurationInput{
        Bucket: aws.String(bucketName),
        LifecycleConfiguration: &types.BucketLifecycleConfiguration{
            Rules: []types.LifecycleRule{
                {
                    ID:     aws.String("lc"),
                    Filter: &types.LifecycleRuleFilter{
                        And: &types.LifecycleRuleAndOperator{
                            Prefix: aws.String("foo/"), 
                            ObjectSizeGreaterThan: aws.Int64(1000000), 
                            ObjectSizeLessThan:    aws.Int64(100000000), 
                            },
                        },
                    
                    Status: types.ExpirationStatusEnabled,
                    Expiration: &types.LifecycleExpiration{
                        Days: aws.Int32(int32(1)), 
                    },
                },
                {
                    ID:     aws.String("abortmpu"),
                    Filter: &types.LifecycleRuleFilter{
                        Prefix: aws.String("bar/"), 
                    },
                    Status: types.ExpirationStatusEnabled,
                    AbortIncompleteMultipartUpload: &types.AbortIncompleteMultipartUpload{
                        DaysAfterInitiation: aws.Int32(int32(5)), 
                    },
                },
            },
        },
    }
    _, err := client.PutBucketLifecycleConfiguration(context.Background(), lifecycleConfig)
    return err
}
// Get the Lifecycle policy
func getBucketLifecycleConfiguration(client *s3.Client, bucketName string) error {
    getLifecycleConfig := &s3.GetBucketLifecycleConfigurationInput{
        Bucket: aws.String(bucketName),
    }

    resp, err := client.GetBucketLifecycleConfiguration(context.Background(), getLifecycleConfig)
    if err != nil {
        return err
    }
    return nil
}
// Delete the Lifecycle policy
func deleteBucketLifecycleConfiguration(client *s3.Client, bucketName string) error {
    deleteLifecycleConfig := &s3.DeleteBucketLifecycleInput{
        Bucket: aws.String(bucketName),
    }
    _, err := client.DeleteBucketLifecycle(context.Background(), deleteLifecycleConfig)
    return err
}
func main() {
    cfg, err := config.LoadDefaultConfig(context.Background(), config.WithRegion("us-west-2")) // Specify your region here
    if err != nil {
        log.Fatalf("unable to load SDK config, %v", err)
    }
    s3Client := s3.NewFromConfig(cfg)
    bucketName := "amzn-s3-demo-bucket--usw2-az1--x-s3" 
    putBucketLifecycleConfiguration(s3Client, bucketName)
    getBucketLifecycleConfiguration(s3Client, bucketName)
    deleteBucketLifecycleConfiguration(s3Client, bucketName)
    getBucketLifecycleConfiguration(s3Client, bucketName)
}
```

------
#### [ SDK for .NET ]

**Example**  

```
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Amazon.DocSamples.S3
{
    class LifecycleTest
    {
        private const string bucketName = "amzn-s3-demo-bucket--usw2-az1--x-s3";
        // Specify your bucket region (an example region is shown).
        private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
        private static IAmazonS3 client;
        public static void Main()
        {
            client = new AmazonS3Client(bucketRegion);
            AddUpdateDeleteLifecycleConfigAsync().Wait();
        }

        private static async Task AddUpdateDeleteLifecycleConfigAsync()
        {
            try
            {
                var lifeCycleConfiguration = new LifecycleConfiguration()
                {
                    Rules = new List <LifecycleRule>
                        {
                            new LifecycleRule
                            {
                                 Id = "delete rule",
                                  Filter = new LifecycleFilter()
                                 {
                                     LifecycleFilterPredicate = new LifecyclePrefixPredicate()
                                     {
                                         Prefix = "projectdocs/"
                                     }
                                 },
                                 Status = LifecycleRuleStatus.Enabled,
                                 Expiration = new LifecycleRuleExpiration()
                                 {
                                       Days = 10
                                 }
                            }
                        }
                };

                // Add the configuration to the bucket. 
                await AddExampleLifecycleConfigAsync(client, lifeCycleConfiguration);

                // Retrieve an existing configuration. 
                lifeCycleConfiguration = await RetrieveLifecycleConfigAsync(client);

                // Add a new rule.
                lifeCycleConfiguration.Rules.Add(new LifecycleRule
                {
                    Id = "mpu abort rule",
                    Filter = new LifecycleFilter()
                    {
                        LifecycleFilterPredicate = new LifecyclePrefixPredicate()
                        {
                            Prefix = "YearlyDocuments/"
                        }
                    },
                    Expiration = new LifecycleRuleExpiration()
                    {
                        Days = 10
                    },
                    AbortIncompleteMultipartUpload = new LifecycleRuleAbortIncompleteMultipartUpload()
                    {
                        DaysAfterInitiation = 10
                    }
                });

                // Add the configuration to the bucket. 
                await AddExampleLifecycleConfigAsync(client, lifeCycleConfiguration);

                // Verify that there are now two rules.
                lifeCycleConfiguration = await RetrieveLifecycleConfigAsync(client);
                Console.WriteLine("Expected # of rulest=2; found:{0}", lifeCycleConfiguration.Rules.Count);

                // Delete the configuration.
                await RemoveLifecycleConfigAsync(client);

                // Retrieve a nonexistent configuration.
                lifeCycleConfiguration = await RetrieveLifecycleConfigAsync(client);

            }
            catch (AmazonS3Exception e)
            {
                Console.WriteLine("Error encountered ***. Message:'{0}' when writing an object", e.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message);
            }
        }

        static async Task AddExampleLifecycleConfigAsync(IAmazonS3 client, LifecycleConfiguration configuration)
        {

            PutLifecycleConfigurationRequest request = new PutLifecycleConfigurationRequest
            {
                BucketName = bucketName,
                Configuration = configuration
            };
            var response = await client.PutLifecycleConfigurationAsync(request);
        }

        static async Task <LifecycleConfiguration> RetrieveLifecycleConfigAsync(IAmazonS3 client)
        {
            GetLifecycleConfigurationRequest request = new GetLifecycleConfigurationRequest
            {
                BucketName = bucketName
            };
            var response = await client.GetLifecycleConfigurationAsync(request);
            var configuration = response.Configuration;
            return configuration;
        }

        static async Task RemoveLifecycleConfigAsync(IAmazonS3 client)
        {
            DeleteLifecycleConfigurationRequest request = new DeleteLifecycleConfigurationRequest
            {
                BucketName = bucketName
            };
            await client.DeleteLifecycleConfigurationAsync(request);
        }
    }
}
```

------
#### [ SDK for Python ]

**Example**  

```
import boto3

client = boto3.client("s3", region_name="us-west-2")
bucket_name = 'amzn-s3-demo-bucket--usw2-az1--x-s3'

client.put_bucket_lifecycle_configuration(
    Bucket=bucket_name,
    ChecksumAlgorithm='CRC32',
    LifecycleConfiguration={
        'Rules': [
            {
                'ID': 'lc',
                'Filter': {
                    'And': {
                        'Prefix': 'foo/',
                        'ObjectSizeGreaterThan': 1000000,
                        'ObjectSizeLessThan': 100000000,
                    }
                },
                'Status': 'Enabled',
                'Expiration': {
                    'Days': 1
                }
            },
            {
                'ID': 'abortmpu',
                'Filter': {
                    'Prefix': 'bar/'
                },
                'Status': 'Enabled',
                'AbortIncompleteMultipartUpload': {
                    'DaysAfterInitiation': 5
                }
            }
        ]
    }
)

result = client.get_bucket_lifecycle_configuration(
    Bucket=bucket_name
)

client.delete_bucket_lifecycle(
    Bucket=bucket_name
)
```

------

# 對適用於目錄儲存貯體的 S3 生命週期問題進行故障診斷
<a name="directory-buckets-lifecycle-troubleshooting"></a>

**Topics**
+ [我設定了生命週期組態，但目錄儲存貯體中的物件未能過期](#troubleshoot-directory-bucket-lifecycle-1)
+ [如何監控生命週期規則採取的動作？](#troubleshoot-directory-bucket-lifecycle-2)

## 我設定了生命週期組態，但目錄儲存貯體中的物件未能過期
<a name="troubleshoot-directory-bucket-lifecycle-1"></a>

適用於目錄儲存貯體的 S3 生命週期會使用公有 API 來刪除 S3 Express One Zone 中的物件。若要使用物件層級公有 API，您必須授予 `CreateSession` 許可，並允許 S3 生命週期許可來刪除您的物件。如果您有拒絕刪除的作用中政策，此政策將使您無法允許 S3 生命週期代表您刪除物件。

請務必正確設定儲存貯體政策，以確保要刪除的物件符合過期資格。您可以在 AWS CloudTrail 中檢查`AccessDenied`追蹤 `CreateSession` API 調用的 CloudTrail 日誌，以驗證存取是否遭拒。檢查 CloudTrail 日誌可協助您對存取問題進行故障診斷，並找出存取遭拒錯誤的根本原因。然後，您可以透過更新相關政策來修正不正確的存取控制。

如果您確認儲存貯體政策設定正確，但仍遇到問題，建議您檢閱生命週期規則，確保已將其套用至正確的物件子集。

## 如何監控生命週期規則採取的動作？
<a name="troubleshoot-directory-bucket-lifecycle-2"></a>

 您可以使用 AWS CloudTrail 資料事件日誌來監控 S3 生命週期在目錄儲存貯體中採取的動作。如需詳細資訊，請參閱 [CloudTrail 日誌檔案範例](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-log-files.html)。