You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在CDK(TypeScript)应用中创建AWS S3 Glacier堆栈失败求助

问题分析与解决方案

问题描述

使用AWS CDK(TypeScript)创建S3 Glacier归档存储桶时,运行cdk list命令报错:Error: Cannot use 'noncurrent' rules on a nonversioned bucket,相关代码如下:

cdk-app-1.ts

import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { S3GlacierStack } from '../lib/s3-glacier-stack';

const app = new cdk.App();
new S3GlacierStack(app, 'S3GlacierStack', {});

s3-glacier-stack.ts

import * as cdk from 'aws-cdk-lib';
import * as s3 from "aws-cdk-lib/aws-s3";
import { Construct } from 'constructs';

export class S3GlacierStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {

    super(scope, id, props);

    const bucket = new s3.Bucket(this, 's3-glacier', {
      lifecycleRules: [{
        abortIncompleteMultipartUploadAfter: cdk.Duration.minutes(30),
        enabled: false,
        expiration: cdk.Duration.days(30),
        expirationDate: new Date(),
        expiredObjectDeleteMarker: false,
        id: 's3-glacier',
        noncurrentVersionExpiration: cdk.Duration.days(30),
        noncurrentVersionsToRetain: 123,
        noncurrentVersionTransitions: [{
          storageClass: s3.StorageClass.GLACIER,
          transitionAfter: cdk.Duration.days(30),
          noncurrentVersionsToRetain: 123,
        }],
        objectSizeGreaterThan: 500,
        prefix: 'prefix',
        objectSizeLessThan: 10000,
        transitions: [{
          storageClass: s3.StorageClass.GLACIER,
          transitionAfter: cdk.Duration.days(30),
          transitionDate: new Date(),
        }],
      }]
    });
  }
}

package.json

{
  "name": "cdk-app-1",
  "version": "0.1.0",
  "bin": {
    "cdk-app-1": "bin/cdk-app-1.js"
  },
  "scripts": {
    "build": "tsc",
    "watch": "tsc -w",
    "test": "jest",
    "cdk": "cdk"
  },
  "devDependencies": {
    "@types/jest": "^27.5.2",
    "@types/node": "10.17.27",
    "@types/prettier": "2.6.0",
    "jest": "^27.5.1",
    "ts-jest": "^27.1.4",
    "aws-cdk": "2.50.0",
    "ts-node": "^10.9.1",
    "typescript": "~3.9.7"
  },
  "dependencies": {
    "aws-cdk-lib": "2.50.0",
    "constructs": "^10.0.0",
    "source-map-support": "^0.5.21"
  }
}

错误原因

你在生命周期规则中配置了noncurrentVersionExpiration、noncurrentVersionTransitions这类针对非当前对象版本的规则,但AWS S3桶默认是未开启版本控制的。这类规则仅适用于已启用版本控制的桶,因此CDK在验证配置时抛出错误。

推荐方案

根据归档需求,有两种合理的实现方式:

方案1:不需要版本控制(移除非当前版本规则)

如果不需要保留对象历史版本,直接删除所有noncurrent开头的配置项,仅保留当前版本转Glacier的规则即可:

修改后的s3-glacier-stack.ts代码:

import * as cdk from 'aws-cdk-lib';
import * as s3 from "aws-cdk-lib/aws-s3";
import { Construct } from 'constructs';

export class S3GlacierStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const bucket = new s3.Bucket(this, 's3-glacier', {
      lifecycleRules: [{
        abortIncompleteMultipartUploadAfter: cdk.Duration.minutes(30),
        enabled: true, // 启用规则需设为true
        expiration: cdk.Duration.days(30),
        id: 's3-glacier-archive-rule',
        prefix: 'prefix',
        transitions: [{
          storageClass: s3.StorageClass.GLACIER, // 对应Glacier Flexible Retrieval存储类
          transitionAfter: cdk.Duration.days(30),
        }],
      }]
    });
  }
}

方案2:开启版本控制(适合归档场景)

归档场景通常建议开启版本控制,以便误删或修改后恢复历史版本。此时需在桶配置中开启版本控制,同时合理配置非当前版本的生命周期规则:

修改后的s3-glacier-stack.ts代码:

import * as cdk from 'aws-cdk-lib';
import * as s3 from "aws-cdk-lib/aws-s3";
import { Construct } from 'constructs';

export class S3GlacierStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const bucket = new s3.Bucket(this, 's3-glacier', {
      versioned: true, // 开启版本控制
      lifecycleRules: [{
        abortIncompleteMultipartUploadAfter: cdk.Duration.minutes(30),
        enabled: true,
        // 当前版本30天后转Glacier
        transitions: [{
          storageClass: s3.StorageClass.GLACIER,
          transitionAfter: cdk.Duration.days(30),
        }],
        // 非当前版本30天后转Glacier,保留123个版本后删除
        noncurrentVersionTransitions: [{
          storageClass: s3.StorageClass.GLACIER,
          transitionAfter: cdk.Duration.days(30),
        }],
        noncurrentVersionExpiration: cdk.Duration.days(30),
        noncurrentVersionsToRetain: 123,
        prefix: 'prefix',
      }]
    });
  }
}

额外注意事项

  • 原代码中enabled: false会禁用整个生命周期规则,若要启用需设为true
  • expiration和expirationDate不要同时配置,CDK会触发验证错误,建议仅保留其中一种
  • GLACIER对应Glacier Flexible Retrieval存储类,若需更经济的归档选项,可使用GLACIER_IR(即时检索)或DEEP_ARCHIVE(深度归档)

内容的提问来源于stack exchange,提问作者Joseph Katzman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 10:35:24