From 9935d4028e2d964da49f714262a67a817a8a81b7 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Wed, 16 Oct 2024 20:54:31 +0900 Subject: [PATCH 1/7] feat(s3): support transitionDefaultMinimumObjectSize for life cycle --- .../cdk.out | 1 + ...efaultTestDeployAssert78D699F6.assets.json | 19 ++ ...aultTestDeployAssert78D699F6.template.json | 36 +++ .../integ.json | 12 + .../manifest.json | 133 ++++++++++ .../s3-lifecycle-transition-size.assets.json | 19 ++ ...s3-lifecycle-transition-size.template.json | 106 ++++++++ .../tree.json | 233 ++++++++++++++++++ .../test/integ.lifecycle-transition-size.ts | 55 +++++ packages/aws-cdk-lib/aws-s3/README.md | 28 +++ packages/aws-cdk-lib/aws-s3/lib/bucket.ts | 50 +++- .../aws-cdk-lib/aws-s3/test/bucket.test.ts | 193 +++++++++++++++ 12 files changed, 884 insertions(+), 1 deletion(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/s3-lifecycle-transition-size.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/s3-lifecycle-transition-size.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/cdk.out new file mode 100644 index 0000000000000..c6e612584e352 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"38.0.1"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.assets.json new file mode 100644 index 0000000000000..a150b639a6648 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.assets.json @@ -0,0 +1,19 @@ +{ + "version": "38.0.1", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/integ.json new file mode 100644 index 0000000000000..e1b601a35b7e4 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "38.0.1", + "testCases": { + "cdk-integ-s3-lifecycle-transition-size/DefaultTest": { + "stacks": [ + "s3-lifecycle-transition-size" + ], + "assertionStack": "cdk-integ-s3-lifecycle-transition-size/DefaultTest/DeployAssert", + "assertionStackName": "cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/manifest.json new file mode 100644 index 0000000000000..857a1608d2d90 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/manifest.json @@ -0,0 +1,133 @@ +{ + "version": "38.0.1", + "artifacts": { + "s3-lifecycle-transition-size.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "s3-lifecycle-transition-size.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "s3-lifecycle-transition-size": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "s3-lifecycle-transition-size.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "notificationArns": [], + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/831e3bb8282d40003f0e16f3c10c281d6524628d1d122cb2e64c89b1c32a3a3e.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "s3-lifecycle-transition-size.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "s3-lifecycle-transition-size.assets" + ], + "metadata": { + "/s3-lifecycle-transition-size/AllStorageClasses128K/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "AllStorageClasses128KB8241761" + } + ], + "/s3-lifecycle-transition-size/VariesByStorageClass/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "VariesByStorageClassCD3C88D5" + } + ], + "/s3-lifecycle-transition-size/AllStorageClasses128KWithCustomSizeRule/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "AllStorageClasses128KWithCustomSizeRuleCB96F380" + } + ], + "/s3-lifecycle-transition-size/VariesByStorageClassWithCustomSizeRule/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "VariesByStorageClassWithCustomSizeRule7F7CE7DF" + } + ], + "/s3-lifecycle-transition-size/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/s3-lifecycle-transition-size/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "s3-lifecycle-transition-size" + }, + "cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "notificationArns": [], + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.assets" + ], + "metadata": { + "/cdk-integ-s3-lifecycle-transition-size/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/cdk-integ-s3-lifecycle-transition-size/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "cdk-integ-s3-lifecycle-transition-size/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/s3-lifecycle-transition-size.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/s3-lifecycle-transition-size.assets.json new file mode 100644 index 0000000000000..abefd9f1ce151 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/s3-lifecycle-transition-size.assets.json @@ -0,0 +1,19 @@ +{ + "version": "38.0.1", + "files": { + "831e3bb8282d40003f0e16f3c10c281d6524628d1d122cb2e64c89b1c32a3a3e": { + "source": { + "path": "s3-lifecycle-transition-size.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "831e3bb8282d40003f0e16f3c10c281d6524628d1d122cb2e64c89b1c32a3a3e.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/s3-lifecycle-transition-size.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/s3-lifecycle-transition-size.template.json new file mode 100644 index 0000000000000..6e27514f59662 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/s3-lifecycle-transition-size.template.json @@ -0,0 +1,106 @@ +{ + "Resources": { + "AllStorageClasses128KB8241761": { + "Type": "AWS::S3::Bucket", + "Properties": { + "LifecycleConfiguration": { + "Rules": [ + { + "ExpirationInDays": 30, + "Status": "Enabled" + } + ], + "TransitionDefaultMinimumObjectSize": "all_storage_classes_128K" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VariesByStorageClassCD3C88D5": { + "Type": "AWS::S3::Bucket", + "Properties": { + "LifecycleConfiguration": { + "Rules": [ + { + "ExpirationInDays": 30, + "Status": "Enabled" + } + ], + "TransitionDefaultMinimumObjectSize": "varies_by_storage_class" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "AllStorageClasses128KWithCustomSizeRuleCB96F380": { + "Type": "AWS::S3::Bucket", + "Properties": { + "LifecycleConfiguration": { + "Rules": [ + { + "ExpirationInDays": 30, + "ObjectSizeGreaterThan": 200000, + "ObjectSizeLessThan": 300000, + "Status": "Enabled" + } + ], + "TransitionDefaultMinimumObjectSize": "all_storage_classes_128K" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "VariesByStorageClassWithCustomSizeRule7F7CE7DF": { + "Type": "AWS::S3::Bucket", + "Properties": { + "LifecycleConfiguration": { + "Rules": [ + { + "ExpirationInDays": 30, + "ObjectSizeGreaterThan": 200000, + "ObjectSizeLessThan": 300000, + "Status": "Enabled" + } + ], + "TransitionDefaultMinimumObjectSize": "varies_by_storage_class" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/tree.json new file mode 100644 index 0000000000000..8d1e5e2a6f836 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/tree.json @@ -0,0 +1,233 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "s3-lifecycle-transition-size": { + "id": "s3-lifecycle-transition-size", + "path": "s3-lifecycle-transition-size", + "children": { + "AllStorageClasses128K": { + "id": "AllStorageClasses128K", + "path": "s3-lifecycle-transition-size/AllStorageClasses128K", + "children": { + "Resource": { + "id": "Resource", + "path": "s3-lifecycle-transition-size/AllStorageClasses128K/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::Bucket", + "aws:cdk:cloudformation:props": { + "lifecycleConfiguration": { + "rules": [ + { + "expirationInDays": 30, + "status": "Enabled" + } + ], + "transitionDefaultMinimumObjectSize": "all_storage_classes_128K" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "VariesByStorageClass": { + "id": "VariesByStorageClass", + "path": "s3-lifecycle-transition-size/VariesByStorageClass", + "children": { + "Resource": { + "id": "Resource", + "path": "s3-lifecycle-transition-size/VariesByStorageClass/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::Bucket", + "aws:cdk:cloudformation:props": { + "lifecycleConfiguration": { + "rules": [ + { + "expirationInDays": 30, + "status": "Enabled" + } + ], + "transitionDefaultMinimumObjectSize": "varies_by_storage_class" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "AllStorageClasses128KWithCustomSizeRule": { + "id": "AllStorageClasses128KWithCustomSizeRule", + "path": "s3-lifecycle-transition-size/AllStorageClasses128KWithCustomSizeRule", + "children": { + "Resource": { + "id": "Resource", + "path": "s3-lifecycle-transition-size/AllStorageClasses128KWithCustomSizeRule/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::Bucket", + "aws:cdk:cloudformation:props": { + "lifecycleConfiguration": { + "rules": [ + { + "expirationInDays": 30, + "status": "Enabled", + "objectSizeLessThan": 300000, + "objectSizeGreaterThan": 200000 + } + ], + "transitionDefaultMinimumObjectSize": "all_storage_classes_128K" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "VariesByStorageClassWithCustomSizeRule": { + "id": "VariesByStorageClassWithCustomSizeRule", + "path": "s3-lifecycle-transition-size/VariesByStorageClassWithCustomSizeRule", + "children": { + "Resource": { + "id": "Resource", + "path": "s3-lifecycle-transition-size/VariesByStorageClassWithCustomSizeRule/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::Bucket", + "aws:cdk:cloudformation:props": { + "lifecycleConfiguration": { + "rules": [ + { + "expirationInDays": 30, + "status": "Enabled", + "objectSizeLessThan": 300000, + "objectSizeGreaterThan": 200000 + } + ], + "transitionDefaultMinimumObjectSize": "varies_by_storage_class" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "s3-lifecycle-transition-size/BootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "s3-lifecycle-transition-size/CheckBootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "cdk-integ-s3-lifecycle-transition-size": { + "id": "cdk-integ-s3-lifecycle-transition-size", + "path": "cdk-integ-s3-lifecycle-transition-size", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "cdk-integ-s3-lifecycle-transition-size/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "cdk-integ-s3-lifecycle-transition-size/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "cdk-integ-s3-lifecycle-transition-size/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "cdk-integ-s3-lifecycle-transition-size/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "cdk-integ-s3-lifecycle-transition-size/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.ts new file mode 100644 index 0000000000000..778376f295a21 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.ts @@ -0,0 +1,55 @@ +import { App, Duration, RemovalPolicy, Stack } from 'aws-cdk-lib'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import { Bucket, TransitionDefaultMinimumObjectSize } from 'aws-cdk-lib/aws-s3'; + +const app = new App(); + +const stack = new Stack(app, 's3-lifecycle-transition-size'); + +new Bucket(stack, 'AllStorageClasses128K', { + lifecycleRules: [ + { + expiration: Duration.days(30), + }, + ], + transitionDefaultMinimumObjectSize: TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, + removalPolicy: RemovalPolicy.DESTROY, +}); + +new Bucket(stack, 'VariesByStorageClass', { + lifecycleRules: [ + { + expiration: Duration.days(30), + }, + ], + transitionDefaultMinimumObjectSize: TransitionDefaultMinimumObjectSize.VARIES_BY_STORAGE_CLASS, + removalPolicy: RemovalPolicy.DESTROY, +}); + +new Bucket(stack, 'AllStorageClasses128KWithCustomSizeRule', { + lifecycleRules: [ + { + objectSizeLessThan: 300000, + objectSizeGreaterThan: 200000, + expiration: Duration.days(30), + }, + ], + transitionDefaultMinimumObjectSize: TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, + removalPolicy: RemovalPolicy.DESTROY, +}); + +new Bucket(stack, 'VariesByStorageClassWithCustomSizeRule', { + lifecycleRules: [ + { + objectSizeLessThan: 300000, + objectSizeGreaterThan: 200000, + expiration: Duration.days(30), + }, + ], + transitionDefaultMinimumObjectSize: TransitionDefaultMinimumObjectSize.VARIES_BY_STORAGE_CLASS, + removalPolicy: RemovalPolicy.DESTROY, +}); + +new IntegTest(app, 'cdk-integ-s3-lifecycle-transition-size', { + testCases: [stack], +}); \ No newline at end of file diff --git a/packages/aws-cdk-lib/aws-s3/README.md b/packages/aws-cdk-lib/aws-s3/README.md index 3c400997ceba9..cea462672bdc7 100644 --- a/packages/aws-cdk-lib/aws-s3/README.md +++ b/packages/aws-cdk-lib/aws-s3/README.md @@ -862,6 +862,34 @@ const bucket = new s3.Bucket(this, 'MyBucket', { }); ``` +To indicate which default minimum object size behavior is applied to the lifecycle configuration, use the +`transitionDefaultMinimumObjectSize` property. + +This property can't be specified if all rules for `lifecycleRules` don't have at least one of the following properties: + +- `abortIncompleteMultipartUploadAfter` +- `expiration` +- `expirationDate` +- `expiredObjectDeleteMarker` +- `noncurrentVersionExpiration` +- `noncurrentVersionsToRetain` +- `noncurrentVersionTransitions` +- `transitions` + +To customize the minimum object size for any transition you can add a filter that specifies a custom `objectSizeGreaterThan` +or `objectSizeLessThan` for `lifecycleRules` property. Custom filters always take precedence over the default transition behavior. + +```ts +new s3.Bucket(this, 'MyBucket', { + transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.VARIES_BY_STORAGE_CLASS, + lifecycleRules: [ + { + expiration: Duration.days(30), + }, + ], +}); +``` + ## Object Lock Configuration [Object Lock](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock-overview.html) diff --git a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts index dc542a0a0199c..e6ec36003a27f 100644 --- a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts +++ b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts @@ -1403,6 +1403,24 @@ export abstract class TargetObjectKeyFormat { public abstract _render(): CfnBucket.LoggingConfigurationProperty['targetObjectKeyFormat']; } +/** + * The transition default minimum object size for lifecycle + */ +export enum TransitionDefaultMinimumObjectSize { + /** + * Objects smaller than 128 KB will not transition to any storage class by default. + */ + ALL_STORAGE_CLASSES_128_K = 'all_storage_classes_128K', + + /** + * Objects smaller than 128 KB will transition to Glacier Flexible Retrieval or Glacier + * Deep Archive storage classes. + * + * By default, all other storage classes will prevent transitions smaller than 128 KB. + */ + VARIES_BY_STORAGE_CLASS = 'varies_by_storage_class', +} + export interface BucketProps { /** * The kind of server-side encryption to apply to this bucket. @@ -1528,6 +1546,17 @@ export interface BucketProps { */ readonly lifecycleRules?: LifecycleRule[]; + /** + * Indicates which default minimum object size behavior is applied to the lifecycle configuration. + * + * To customize the minimum object size for any transition you can add a filter that specifies a custom + * `objectSizeGreaterThan` or `objectSizeLessThan` for `lifecycleRules` property. Custom filters always + * take precedence over the default transition behavior. + * + * @default TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K + */ + readonly transitionDefaultMinimumObjectSize?: TransitionDefaultMinimumObjectSize; + /** * The name of the index document (e.g. "index.html") for the website. Enables static website * hosting for this bucket. @@ -1910,6 +1939,7 @@ export class Bucket extends BucketBase { protected disallowPublicAccess?: boolean; private accessControl?: BucketAccessControl; private readonly lifecycleRules: LifecycleRule[] = []; + private readonly transitionDefaultMinimumObjectSize?: TransitionDefaultMinimumObjectSize; private readonly eventBridgeEnabled?: boolean; private readonly metrics: BucketMetrics[] = []; private readonly cors: CorsRule[] = []; @@ -1934,6 +1964,7 @@ export class Bucket extends BucketBase { const objectLockConfiguration = this.parseObjectLockConfig(props); this.objectOwnership = props.objectOwnership; + this.transitionDefaultMinimumObjectSize = props.transitionDefaultMinimumObjectSize; const resource = new CfnBucket(this, 'Resource', { bucketName: this.physicalName, bucketEncryption, @@ -2238,13 +2269,30 @@ export class Bucket extends BucketBase { * @param props Par */ private parseLifecycleConfiguration(): CfnBucket.LifecycleConfigurationProperty | undefined { + const isValidTransitionDefaultMinimumObjectSize = this.lifecycleRules.every((rule: LifecycleRule): boolean => + rule.abortIncompleteMultipartUploadAfter !== undefined || + rule.expiration !== undefined || + rule.expirationDate !== undefined || + rule.expiredObjectDeleteMarker !== undefined || + rule.noncurrentVersionExpiration !== undefined || + rule.noncurrentVersionsToRetain !== undefined || + rule.noncurrentVersionTransitions !== undefined || + rule.transitions !== undefined + ); + if (this.transitionDefaultMinimumObjectSize && !isValidTransitionDefaultMinimumObjectSize) { + throw new Error('TransitionDefaultMinimumObjectSize cannot be specified if all lifecycleRules don\'t have at least one of the following properties: abortIncompleteMultipartUploadAfter, expiration, expirationDate, expiredObjectDeleteMarker, noncurrentVersionExpiration, noncurrentVersionsToRetain, noncurrentVersionTransitions, or transitions'); + } + if (!this.lifecycleRules || this.lifecycleRules.length === 0) { return undefined; } const self = this; - return { rules: this.lifecycleRules.map(parseLifecycleRule) }; + return { + rules: this.lifecycleRules.map(parseLifecycleRule), + transitionDefaultMinimumObjectSize: this.transitionDefaultMinimumObjectSize, + }; function parseLifecycleRule(rule: LifecycleRule): CfnBucket.RuleProperty { const enabled = rule.enabled ?? true; diff --git a/packages/aws-cdk-lib/aws-s3/test/bucket.test.ts b/packages/aws-cdk-lib/aws-s3/test/bucket.test.ts index e526d6150d195..74746a4b92c47 100644 --- a/packages/aws-cdk-lib/aws-s3/test/bucket.test.ts +++ b/packages/aws-cdk-lib/aws-s3/test/bucket.test.ts @@ -3852,5 +3852,198 @@ describe('bucket', () => { }, }); }); + + describe('Bucket with transitionDefaultMinimumObjectSize', () => { + test.each([ + [s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, 'all_storage_classes_128K'], + [s3.TransitionDefaultMinimumObjectSize.VARIES_BY_STORAGE_CLASS, 'varies_by_storage_class'], + ])('transitionDefaultMinimumObjectSize %s can be specified', (key, value) => { + const stack = new cdk.Stack(); + new s3.Bucket(stack, 'MyBucket', { + transitionDefaultMinimumObjectSize: key, + lifecycleRules: [ + { + expiration: cdk.Duration.days(365), + }, + ], + }); + + Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { + LifecycleConfiguration: { + TransitionDefaultMinimumObjectSize: value, + Rules: [{ + ExpirationInDays: 365, + }], + }, + }); + }); + + test('throw if there is a rule doesn\'t have required properties', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app); + new s3.Bucket(stack, 'MyBucket', { + lifecycleRules: [ + { + objectSizeLessThan: 300000, + objectSizeGreaterThan: 200000, + }, + ], + transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, + }); + expect(() => { + app.synth(); + }).toThrow(/TransitionDefaultMinimumObjectSize cannot be specified if all lifecycleRules don\'t have at least one of the following properties: abortIncompleteMultipartUploadAfter, expiration, expirationDate, expiredObjectDeleteMarker, noncurrentVersionExpiration, noncurrentVersionsToRetain, noncurrentVersionTransitions, or transitions/); + }); + + test('throw if there are a valid rule and a rule that doesn\'t have required properties.', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app); + new s3.Bucket(stack, 'MyBucket', { + lifecycleRules: [ + { + abortIncompleteMultipartUploadAfter: cdk.Duration.days(365), + }, + { + objectSizeLessThan: 300000, + objectSizeGreaterThan: 200000, + }, + ], + transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, + }); + expect(() => { + app.synth(); + }).toThrow(/TransitionDefaultMinimumObjectSize cannot be specified if all lifecycleRules don\'t have at least one of the following properties: abortIncompleteMultipartUploadAfter, expiration, expirationDate, expiredObjectDeleteMarker, noncurrentVersionExpiration, noncurrentVersionsToRetain, noncurrentVersionTransitions, or transitions/); + }); + + test('don\'t throw if transitionDefaultMinimumObjectSize with abortIncompleteMultipartUploadAfter', () => { + const stack = new cdk.Stack(); + new s3.Bucket(stack, 'MyBucket', { + lifecycleRules: [ + { + abortIncompleteMultipartUploadAfter: cdk.Duration.days(365), + }, + ], + transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, + }); + expect(() => { + Template.fromStack(stack); + }).not.toThrow(); + }); + + test('don\'t throw if transitionDefaultMinimumObjectSize with expiration', () => { + const stack = new cdk.Stack(); + new s3.Bucket(stack, 'MyBucket', { + lifecycleRules: [ + { + expiration: cdk.Duration.days(365), + }, + ], + transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, + }); + expect(() => { + Template.fromStack(stack); + }).not.toThrow(); + }); + + test('don\'t throw if transitionDefaultMinimumObjectSize with expirationDate', () => { + const stack = new cdk.Stack(); + new s3.Bucket(stack, 'MyBucket', { + lifecycleRules: [ + { + expirationDate: new Date('2024-01-01'), + }, + ], + transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, + }); + expect(() => { + Template.fromStack(stack); + }).not.toThrow(); + }); + + test('don\'t throw if transitionDefaultMinimumObjectSize with expiredObjectDeleteMarker', () => { + const stack = new cdk.Stack(); + new s3.Bucket(stack, 'MyBucket', { + lifecycleRules: [ + { + expiredObjectDeleteMarker: true, + }, + ], + transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, + }); + expect(() => { + Template.fromStack(stack); + }).not.toThrow(); + }); + + test('don\'t throw if transitionDefaultMinimumObjectSize with noncurrentVersionExpiration', () => { + const stack = new cdk.Stack(); + new s3.Bucket(stack, 'MyBucket', { + lifecycleRules: [ + { + noncurrentVersionExpiration: cdk.Duration.days(365), + }, + ], + transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, + }); + expect(() => { + Template.fromStack(stack); + }).not.toThrow(); + }); + + test('don\'t throw if transitionDefaultMinimumObjectSize with noncurrentVersionsToRetain', () => { + const stack = new cdk.Stack(); + new s3.Bucket(stack, 'MyBucket', { + lifecycleRules: [ + { + noncurrentVersionsToRetain: 10, + }, + ], + transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, + }); + expect(() => { + Template.fromStack(stack); + }).not.toThrow(); + }); + + test('don\'t throw if transitionDefaultMinimumObjectSize with noncurrentVersionTransitions', () => { + const stack = new cdk.Stack(); + new s3.Bucket(stack, 'MyBucket', { + lifecycleRules: [ + { + noncurrentVersionTransitions: [ + { + storageClass: s3.StorageClass.GLACIER_INSTANT_RETRIEVAL, + transitionAfter: cdk.Duration.days(10), + noncurrentVersionsToRetain: 1, + }, + ], + }, + ], + transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, + }); + expect(() => { + Template.fromStack(stack); + }).not.toThrow(); + }); + + test('don\'t throw if transitionDefaultMinimumObjectSize with transitions', () => { + const stack = new cdk.Stack(); + new s3.Bucket(stack, 'MyBucket', { + lifecycleRules: [ + { + transitions: [{ + storageClass: s3.StorageClass.GLACIER, + transitionAfter: cdk.Duration.days(30), + }], + }, + ], + transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, + }); + expect(() => { + Template.fromStack(stack); + }).not.toThrow(); + }); + + }); }); From 3f74d066d3e0f4f16dcb14524e5cda1191ec2155 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Wed, 16 Oct 2024 22:02:39 +0900 Subject: [PATCH 2/7] rm spaces --- packages/aws-cdk-lib/aws-s3/lib/bucket.ts | 20 +++++++++---------- .../aws-cdk-lib/aws-s3/test/bucket.test.ts | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts index e6ec36003a27f..451e8c625ca39 100644 --- a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts +++ b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts @@ -1415,7 +1415,7 @@ export enum TransitionDefaultMinimumObjectSize { /** * Objects smaller than 128 KB will transition to Glacier Flexible Retrieval or Glacier * Deep Archive storage classes. - * + * * By default, all other storage classes will prevent transitions smaller than 128 KB. */ VARIES_BY_STORAGE_CLASS = 'varies_by_storage_class', @@ -1552,7 +1552,7 @@ export interface BucketProps { * To customize the minimum object size for any transition you can add a filter that specifies a custom * `objectSizeGreaterThan` or `objectSizeLessThan` for `lifecycleRules` property. Custom filters always * take precedence over the default transition behavior. - * + * * @default TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K */ readonly transitionDefaultMinimumObjectSize?: TransitionDefaultMinimumObjectSize; @@ -2270,14 +2270,14 @@ export class Bucket extends BucketBase { */ private parseLifecycleConfiguration(): CfnBucket.LifecycleConfigurationProperty | undefined { const isValidTransitionDefaultMinimumObjectSize = this.lifecycleRules.every((rule: LifecycleRule): boolean => - rule.abortIncompleteMultipartUploadAfter !== undefined || - rule.expiration !== undefined || - rule.expirationDate !== undefined || - rule.expiredObjectDeleteMarker !== undefined || - rule.noncurrentVersionExpiration !== undefined || - rule.noncurrentVersionsToRetain !== undefined || - rule.noncurrentVersionTransitions !== undefined || - rule.transitions !== undefined + rule.abortIncompleteMultipartUploadAfter !== undefined || + rule.expiration !== undefined || + rule.expirationDate !== undefined || + rule.expiredObjectDeleteMarker !== undefined || + rule.noncurrentVersionExpiration !== undefined || + rule.noncurrentVersionsToRetain !== undefined || + rule.noncurrentVersionTransitions !== undefined || + rule.transitions !== undefined ); if (this.transitionDefaultMinimumObjectSize && !isValidTransitionDefaultMinimumObjectSize) { throw new Error('TransitionDefaultMinimumObjectSize cannot be specified if all lifecycleRules don\'t have at least one of the following properties: abortIncompleteMultipartUploadAfter, expiration, expirationDate, expiredObjectDeleteMarker, noncurrentVersionExpiration, noncurrentVersionsToRetain, noncurrentVersionTransitions, or transitions'); diff --git a/packages/aws-cdk-lib/aws-s3/test/bucket.test.ts b/packages/aws-cdk-lib/aws-s3/test/bucket.test.ts index 74746a4b92c47..248434fad4b3a 100644 --- a/packages/aws-cdk-lib/aws-s3/test/bucket.test.ts +++ b/packages/aws-cdk-lib/aws-s3/test/bucket.test.ts @@ -3867,7 +3867,7 @@ describe('bucket', () => { }, ], }); - + Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { LifecycleConfiguration: { TransitionDefaultMinimumObjectSize: value, @@ -3891,7 +3891,7 @@ describe('bucket', () => { transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, }); expect(() => { - app.synth(); + app.synth(); }).toThrow(/TransitionDefaultMinimumObjectSize cannot be specified if all lifecycleRules don\'t have at least one of the following properties: abortIncompleteMultipartUploadAfter, expiration, expirationDate, expiredObjectDeleteMarker, noncurrentVersionExpiration, noncurrentVersionsToRetain, noncurrentVersionTransitions, or transitions/); }); @@ -3911,7 +3911,7 @@ describe('bucket', () => { transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, }); expect(() => { - app.synth(); + app.synth(); }).toThrow(/TransitionDefaultMinimumObjectSize cannot be specified if all lifecycleRules don\'t have at least one of the following properties: abortIncompleteMultipartUploadAfter, expiration, expirationDate, expiredObjectDeleteMarker, noncurrentVersionExpiration, noncurrentVersionsToRetain, noncurrentVersionTransitions, or transitions/); }); From 15cb800718be4846a35e9168e45b1a504ace9378 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Wed, 16 Oct 2024 22:24:36 +0900 Subject: [PATCH 3/7] style --- packages/aws-cdk-lib/aws-s3/lib/bucket.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts index 451e8c625ca39..be45ca094d402 100644 --- a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts +++ b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts @@ -2269,15 +2269,16 @@ export class Bucket extends BucketBase { * @param props Par */ private parseLifecycleConfiguration(): CfnBucket.LifecycleConfigurationProperty | undefined { - const isValidTransitionDefaultMinimumObjectSize = this.lifecycleRules.every((rule: LifecycleRule): boolean => - rule.abortIncompleteMultipartUploadAfter !== undefined || - rule.expiration !== undefined || - rule.expirationDate !== undefined || - rule.expiredObjectDeleteMarker !== undefined || - rule.noncurrentVersionExpiration !== undefined || - rule.noncurrentVersionsToRetain !== undefined || - rule.noncurrentVersionTransitions !== undefined || - rule.transitions !== undefined + const isValidTransitionDefaultMinimumObjectSize = this.lifecycleRules.every( + (rule: LifecycleRule): boolean => + rule.abortIncompleteMultipartUploadAfter !== undefined || + rule.expiration !== undefined || + rule.expirationDate !== undefined || + rule.expiredObjectDeleteMarker !== undefined || + rule.noncurrentVersionExpiration !== undefined || + rule.noncurrentVersionsToRetain !== undefined || + rule.noncurrentVersionTransitions !== undefined || + rule.transitions !== undefined, ); if (this.transitionDefaultMinimumObjectSize && !isValidTransitionDefaultMinimumObjectSize) { throw new Error('TransitionDefaultMinimumObjectSize cannot be specified if all lifecycleRules don\'t have at least one of the following properties: abortIncompleteMultipartUploadAfter, expiration, expirationDate, expiredObjectDeleteMarker, noncurrentVersionExpiration, noncurrentVersionsToRetain, noncurrentVersionTransitions, or transitions'); From add54f9ac984d857c4ad96afd5cd0ab3b655821e Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Fri, 18 Oct 2024 16:46:55 +0900 Subject: [PATCH 4/7] scope to this feat only --- .../integ.json | 12 - .../cdk.out | 0 ...faultTestDeployAssert9A611ED6.assets.json} | 2 +- ...ultTestDeployAssert9A611ED6.template.json} | 0 .../integ.json | 12 + .../manifest.json | 54 ++--- .../s3-lifecycle-transitions.assets.json} | 6 +- .../s3-lifecycle-transitions.template.json} | 50 ++--- .../tree.json | 118 +++------- ...size.ts => integ.lifecycle-transitions.ts} | 36 ++- packages/aws-cdk-lib/aws-s3/README.md | 18 +- packages/aws-cdk-lib/aws-s3/lib/bucket.ts | 15 -- .../aws-cdk-lib/aws-s3/test/bucket.test.ts | 205 ++---------------- 13 files changed, 126 insertions(+), 402 deletions(-) delete mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/integ.json rename packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/{integ.lifecycle-transition-size.js.snapshot => integ.lifecycle-transitions.js.snapshot}/cdk.out (100%) rename packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/{integ.lifecycle-transition-size.js.snapshot/cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.assets.json => integ.lifecycle-transitions.js.snapshot/cdkintegs3lifecycletransitionsDefaultTestDeployAssert9A611ED6.assets.json} (86%) rename packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/{integ.lifecycle-transition-size.js.snapshot/cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.template.json => integ.lifecycle-transitions.js.snapshot/cdkintegs3lifecycletransitionsDefaultTestDeployAssert9A611ED6.template.json} (100%) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/integ.json rename packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/{integ.lifecycle-transition-size.js.snapshot => integ.lifecycle-transitions.js.snapshot}/manifest.json (64%) rename packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/{integ.lifecycle-transition-size.js.snapshot/s3-lifecycle-transition-size.assets.json => integ.lifecycle-transitions.js.snapshot/s3-lifecycle-transitions.assets.json} (65%) rename packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/{integ.lifecycle-transition-size.js.snapshot/s3-lifecycle-transition-size.template.json => integ.lifecycle-transitions.js.snapshot/s3-lifecycle-transitions.template.json} (69%) rename packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/{integ.lifecycle-transition-size.js.snapshot => integ.lifecycle-transitions.js.snapshot}/tree.json (56%) rename packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/{integ.lifecycle-transition-size.ts => integ.lifecycle-transitions.ts} (53%) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/integ.json deleted file mode 100644 index e1b601a35b7e4..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/integ.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "version": "38.0.1", - "testCases": { - "cdk-integ-s3-lifecycle-transition-size/DefaultTest": { - "stacks": [ - "s3-lifecycle-transition-size" - ], - "assertionStack": "cdk-integ-s3-lifecycle-transition-size/DefaultTest/DeployAssert", - "assertionStackName": "cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6" - } - } -} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/cdk.out similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/cdk.out rename to packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/cdk.out diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/cdkintegs3lifecycletransitionsDefaultTestDeployAssert9A611ED6.assets.json similarity index 86% rename from packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.assets.json rename to packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/cdkintegs3lifecycletransitionsDefaultTestDeployAssert9A611ED6.assets.json index a150b639a6648..2b97edf118e7d 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/cdkintegs3lifecycletransitionsDefaultTestDeployAssert9A611ED6.assets.json @@ -3,7 +3,7 @@ "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { - "path": "cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.template.json", + "path": "cdkintegs3lifecycletransitionsDefaultTestDeployAssert9A611ED6.template.json", "packaging": "file" }, "destinations": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/cdkintegs3lifecycletransitionsDefaultTestDeployAssert9A611ED6.template.json similarity index 100% rename from packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.template.json rename to packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/cdkintegs3lifecycletransitionsDefaultTestDeployAssert9A611ED6.template.json diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/integ.json new file mode 100644 index 0000000000000..891f7148a6a18 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "38.0.1", + "testCases": { + "cdk-integ-s3-lifecycle-transitions/DefaultTest": { + "stacks": [ + "s3-lifecycle-transitions" + ], + "assertionStack": "cdk-integ-s3-lifecycle-transitions/DefaultTest/DeployAssert", + "assertionStackName": "cdkintegs3lifecycletransitionsDefaultTestDeployAssert9A611ED6" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/manifest.json similarity index 64% rename from packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/manifest.json rename to packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/manifest.json index 857a1608d2d90..c4c807e527c74 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/manifest.json @@ -1,29 +1,29 @@ { "version": "38.0.1", "artifacts": { - "s3-lifecycle-transition-size.assets": { + "s3-lifecycle-transitions.assets": { "type": "cdk:asset-manifest", "properties": { - "file": "s3-lifecycle-transition-size.assets.json", + "file": "s3-lifecycle-transitions.assets.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" } }, - "s3-lifecycle-transition-size": { + "s3-lifecycle-transitions": { "type": "aws:cloudformation:stack", "environment": "aws://unknown-account/unknown-region", "properties": { - "templateFile": "s3-lifecycle-transition-size.template.json", + "templateFile": "s3-lifecycle-transitions.template.json", "terminationProtection": false, "validateOnSynth": false, "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/831e3bb8282d40003f0e16f3c10c281d6524628d1d122cb2e64c89b1c32a3a3e.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/1e0d7f45f8d321fd2829de3312567d3deeb6dd4f6c753d1893936754bff6610e.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ - "s3-lifecycle-transition-size.assets" + "s3-lifecycle-transitions.assets" ], "lookupRole": { "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", @@ -32,61 +32,49 @@ } }, "dependencies": [ - "s3-lifecycle-transition-size.assets" + "s3-lifecycle-transitions.assets" ], "metadata": { - "/s3-lifecycle-transition-size/AllStorageClasses128K/Resource": [ + "/s3-lifecycle-transitions/AllStorageClasses128K/Resource": [ { "type": "aws:cdk:logicalId", "data": "AllStorageClasses128KB8241761" } ], - "/s3-lifecycle-transition-size/VariesByStorageClass/Resource": [ + "/s3-lifecycle-transitions/VariesByStorageClass/Resource": [ { "type": "aws:cdk:logicalId", "data": "VariesByStorageClassCD3C88D5" } ], - "/s3-lifecycle-transition-size/AllStorageClasses128KWithCustomSizeRule/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "AllStorageClasses128KWithCustomSizeRuleCB96F380" - } - ], - "/s3-lifecycle-transition-size/VariesByStorageClassWithCustomSizeRule/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "VariesByStorageClassWithCustomSizeRule7F7CE7DF" - } - ], - "/s3-lifecycle-transition-size/BootstrapVersion": [ + "/s3-lifecycle-transitions/BootstrapVersion": [ { "type": "aws:cdk:logicalId", "data": "BootstrapVersion" } ], - "/s3-lifecycle-transition-size/CheckBootstrapVersion": [ + "/s3-lifecycle-transitions/CheckBootstrapVersion": [ { "type": "aws:cdk:logicalId", "data": "CheckBootstrapVersion" } ] }, - "displayName": "s3-lifecycle-transition-size" + "displayName": "s3-lifecycle-transitions" }, - "cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.assets": { + "cdkintegs3lifecycletransitionsDefaultTestDeployAssert9A611ED6.assets": { "type": "cdk:asset-manifest", "properties": { - "file": "cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.assets.json", + "file": "cdkintegs3lifecycletransitionsDefaultTestDeployAssert9A611ED6.assets.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" } }, - "cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6": { + "cdkintegs3lifecycletransitionsDefaultTestDeployAssert9A611ED6": { "type": "aws:cloudformation:stack", "environment": "aws://unknown-account/unknown-region", "properties": { - "templateFile": "cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.template.json", + "templateFile": "cdkintegs3lifecycletransitionsDefaultTestDeployAssert9A611ED6.template.json", "terminationProtection": false, "validateOnSynth": false, "notificationArns": [], @@ -96,7 +84,7 @@ "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ - "cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.assets" + "cdkintegs3lifecycletransitionsDefaultTestDeployAssert9A611ED6.assets" ], "lookupRole": { "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", @@ -105,23 +93,23 @@ } }, "dependencies": [ - "cdkintegs3lifecycletransitionsizeDefaultTestDeployAssert78D699F6.assets" + "cdkintegs3lifecycletransitionsDefaultTestDeployAssert9A611ED6.assets" ], "metadata": { - "/cdk-integ-s3-lifecycle-transition-size/DefaultTest/DeployAssert/BootstrapVersion": [ + "/cdk-integ-s3-lifecycle-transitions/DefaultTest/DeployAssert/BootstrapVersion": [ { "type": "aws:cdk:logicalId", "data": "BootstrapVersion" } ], - "/cdk-integ-s3-lifecycle-transition-size/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + "/cdk-integ-s3-lifecycle-transitions/DefaultTest/DeployAssert/CheckBootstrapVersion": [ { "type": "aws:cdk:logicalId", "data": "CheckBootstrapVersion" } ] }, - "displayName": "cdk-integ-s3-lifecycle-transition-size/DefaultTest/DeployAssert" + "displayName": "cdk-integ-s3-lifecycle-transitions/DefaultTest/DeployAssert" }, "Tree": { "type": "cdk:tree", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/s3-lifecycle-transition-size.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/s3-lifecycle-transitions.assets.json similarity index 65% rename from packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/s3-lifecycle-transition-size.assets.json rename to packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/s3-lifecycle-transitions.assets.json index abefd9f1ce151..6f2b23e8b20dd 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/s3-lifecycle-transition-size.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/s3-lifecycle-transitions.assets.json @@ -1,15 +1,15 @@ { "version": "38.0.1", "files": { - "831e3bb8282d40003f0e16f3c10c281d6524628d1d122cb2e64c89b1c32a3a3e": { + "1e0d7f45f8d321fd2829de3312567d3deeb6dd4f6c753d1893936754bff6610e": { "source": { - "path": "s3-lifecycle-transition-size.template.json", + "path": "s3-lifecycle-transitions.template.json", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "831e3bb8282d40003f0e16f3c10c281d6524628d1d122cb2e64c89b1c32a3a3e.json", + "objectKey": "1e0d7f45f8d321fd2829de3312567d3deeb6dd4f6c753d1893936754bff6610e.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/s3-lifecycle-transition-size.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/s3-lifecycle-transitions.template.json similarity index 69% rename from packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/s3-lifecycle-transition-size.template.json rename to packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/s3-lifecycle-transitions.template.json index 6e27514f59662..cdac4a1d0d6e2 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/s3-lifecycle-transition-size.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/s3-lifecycle-transitions.template.json @@ -6,37 +6,14 @@ "LifecycleConfiguration": { "Rules": [ { - "ExpirationInDays": 30, - "Status": "Enabled" - } - ], - "TransitionDefaultMinimumObjectSize": "all_storage_classes_128K" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "VariesByStorageClassCD3C88D5": { - "Type": "AWS::S3::Bucket", - "Properties": { - "LifecycleConfiguration": { - "Rules": [ - { - "ExpirationInDays": 30, - "Status": "Enabled" - } - ], - "TransitionDefaultMinimumObjectSize": "varies_by_storage_class" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "AllStorageClasses128KWithCustomSizeRuleCB96F380": { - "Type": "AWS::S3::Bucket", - "Properties": { - "LifecycleConfiguration": { - "Rules": [ + "Status": "Enabled", + "Transitions": [ + { + "StorageClass": "GLACIER", + "TransitionInDays": 30 + } + ] + }, { "ExpirationInDays": 30, "ObjectSizeGreaterThan": 200000, @@ -50,11 +27,20 @@ "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, - "VariesByStorageClassWithCustomSizeRule7F7CE7DF": { + "VariesByStorageClassCD3C88D5": { "Type": "AWS::S3::Bucket", "Properties": { "LifecycleConfiguration": { "Rules": [ + { + "Status": "Enabled", + "Transitions": [ + { + "StorageClass": "GLACIER", + "TransitionInDays": 30 + } + ] + }, { "ExpirationInDays": 30, "ObjectSizeGreaterThan": 200000, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/tree.json similarity index 56% rename from packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/tree.json rename to packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/tree.json index 8d1e5e2a6f836..2020166f73ccf 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/tree.json @@ -4,86 +4,31 @@ "id": "App", "path": "", "children": { - "s3-lifecycle-transition-size": { - "id": "s3-lifecycle-transition-size", - "path": "s3-lifecycle-transition-size", + "s3-lifecycle-transitions": { + "id": "s3-lifecycle-transitions", + "path": "s3-lifecycle-transitions", "children": { "AllStorageClasses128K": { "id": "AllStorageClasses128K", - "path": "s3-lifecycle-transition-size/AllStorageClasses128K", + "path": "s3-lifecycle-transitions/AllStorageClasses128K", "children": { "Resource": { "id": "Resource", - "path": "s3-lifecycle-transition-size/AllStorageClasses128K/Resource", + "path": "s3-lifecycle-transitions/AllStorageClasses128K/Resource", "attributes": { "aws:cdk:cloudformation:type": "AWS::S3::Bucket", "aws:cdk:cloudformation:props": { "lifecycleConfiguration": { "rules": [ { - "expirationInDays": 30, - "status": "Enabled" - } - ], - "transitionDefaultMinimumObjectSize": "all_storage_classes_128K" - } - } - }, - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0" - } - } - }, - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0" - } - }, - "VariesByStorageClass": { - "id": "VariesByStorageClass", - "path": "s3-lifecycle-transition-size/VariesByStorageClass", - "children": { - "Resource": { - "id": "Resource", - "path": "s3-lifecycle-transition-size/VariesByStorageClass/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::S3::Bucket", - "aws:cdk:cloudformation:props": { - "lifecycleConfiguration": { - "rules": [ - { - "expirationInDays": 30, - "status": "Enabled" - } - ], - "transitionDefaultMinimumObjectSize": "varies_by_storage_class" - } - } - }, - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0" - } - } - }, - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.3.0" - } - }, - "AllStorageClasses128KWithCustomSizeRule": { - "id": "AllStorageClasses128KWithCustomSizeRule", - "path": "s3-lifecycle-transition-size/AllStorageClasses128KWithCustomSizeRule", - "children": { - "Resource": { - "id": "Resource", - "path": "s3-lifecycle-transition-size/AllStorageClasses128KWithCustomSizeRule/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::S3::Bucket", - "aws:cdk:cloudformation:props": { - "lifecycleConfiguration": { - "rules": [ + "status": "Enabled", + "transitions": [ + { + "storageClass": "GLACIER", + "transitionInDays": 30 + } + ] + }, { "expirationInDays": 30, "status": "Enabled", @@ -106,18 +51,27 @@ "version": "10.3.0" } }, - "VariesByStorageClassWithCustomSizeRule": { - "id": "VariesByStorageClassWithCustomSizeRule", - "path": "s3-lifecycle-transition-size/VariesByStorageClassWithCustomSizeRule", + "VariesByStorageClass": { + "id": "VariesByStorageClass", + "path": "s3-lifecycle-transitions/VariesByStorageClass", "children": { "Resource": { "id": "Resource", - "path": "s3-lifecycle-transition-size/VariesByStorageClassWithCustomSizeRule/Resource", + "path": "s3-lifecycle-transitions/VariesByStorageClass/Resource", "attributes": { "aws:cdk:cloudformation:type": "AWS::S3::Bucket", "aws:cdk:cloudformation:props": { "lifecycleConfiguration": { "rules": [ + { + "status": "Enabled", + "transitions": [ + { + "storageClass": "GLACIER", + "transitionInDays": 30 + } + ] + }, { "expirationInDays": 30, "status": "Enabled", @@ -142,7 +96,7 @@ }, "BootstrapVersion": { "id": "BootstrapVersion", - "path": "s3-lifecycle-transition-size/BootstrapVersion", + "path": "s3-lifecycle-transitions/BootstrapVersion", "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0" @@ -150,7 +104,7 @@ }, "CheckBootstrapVersion": { "id": "CheckBootstrapVersion", - "path": "s3-lifecycle-transition-size/CheckBootstrapVersion", + "path": "s3-lifecycle-transitions/CheckBootstrapVersion", "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0" @@ -162,17 +116,17 @@ "version": "10.3.0" } }, - "cdk-integ-s3-lifecycle-transition-size": { - "id": "cdk-integ-s3-lifecycle-transition-size", - "path": "cdk-integ-s3-lifecycle-transition-size", + "cdk-integ-s3-lifecycle-transitions": { + "id": "cdk-integ-s3-lifecycle-transitions", + "path": "cdk-integ-s3-lifecycle-transitions", "children": { "DefaultTest": { "id": "DefaultTest", - "path": "cdk-integ-s3-lifecycle-transition-size/DefaultTest", + "path": "cdk-integ-s3-lifecycle-transitions/DefaultTest", "children": { "Default": { "id": "Default", - "path": "cdk-integ-s3-lifecycle-transition-size/DefaultTest/Default", + "path": "cdk-integ-s3-lifecycle-transitions/DefaultTest/Default", "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0" @@ -180,11 +134,11 @@ }, "DeployAssert": { "id": "DeployAssert", - "path": "cdk-integ-s3-lifecycle-transition-size/DefaultTest/DeployAssert", + "path": "cdk-integ-s3-lifecycle-transitions/DefaultTest/DeployAssert", "children": { "BootstrapVersion": { "id": "BootstrapVersion", - "path": "cdk-integ-s3-lifecycle-transition-size/DefaultTest/DeployAssert/BootstrapVersion", + "path": "cdk-integ-s3-lifecycle-transitions/DefaultTest/DeployAssert/BootstrapVersion", "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0" @@ -192,7 +146,7 @@ }, "CheckBootstrapVersion": { "id": "CheckBootstrapVersion", - "path": "cdk-integ-s3-lifecycle-transition-size/DefaultTest/DeployAssert/CheckBootstrapVersion", + "path": "cdk-integ-s3-lifecycle-transitions/DefaultTest/DeployAssert/CheckBootstrapVersion", "constructInfo": { "fqn": "constructs.Construct", "version": "10.3.0" diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.ts similarity index 53% rename from packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.ts rename to packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.ts index 778376f295a21..cba133a5ddee8 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transition-size.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.ts @@ -1,33 +1,19 @@ import { App, Duration, RemovalPolicy, Stack } from 'aws-cdk-lib'; import { IntegTest } from '@aws-cdk/integ-tests-alpha'; -import { Bucket, TransitionDefaultMinimumObjectSize } from 'aws-cdk-lib/aws-s3'; +import { Bucket, StorageClass, TransitionDefaultMinimumObjectSize } from 'aws-cdk-lib/aws-s3'; const app = new App(); -const stack = new Stack(app, 's3-lifecycle-transition-size'); +const stack = new Stack(app, 's3-lifecycle-transitions'); new Bucket(stack, 'AllStorageClasses128K', { lifecycleRules: [ { - expiration: Duration.days(30), - }, - ], - transitionDefaultMinimumObjectSize: TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, - removalPolicy: RemovalPolicy.DESTROY, -}); - -new Bucket(stack, 'VariesByStorageClass', { - lifecycleRules: [ - { - expiration: Duration.days(30), + transitions: [{ + storageClass: StorageClass.GLACIER, + transitionAfter: Duration.days(30), + }], }, - ], - transitionDefaultMinimumObjectSize: TransitionDefaultMinimumObjectSize.VARIES_BY_STORAGE_CLASS, - removalPolicy: RemovalPolicy.DESTROY, -}); - -new Bucket(stack, 'AllStorageClasses128KWithCustomSizeRule', { - lifecycleRules: [ { objectSizeLessThan: 300000, objectSizeGreaterThan: 200000, @@ -38,8 +24,14 @@ new Bucket(stack, 'AllStorageClasses128KWithCustomSizeRule', { removalPolicy: RemovalPolicy.DESTROY, }); -new Bucket(stack, 'VariesByStorageClassWithCustomSizeRule', { +new Bucket(stack, 'VariesByStorageClass', { lifecycleRules: [ + { + transitions: [{ + storageClass: StorageClass.GLACIER, + transitionAfter: Duration.days(30), + }], + }, { objectSizeLessThan: 300000, objectSizeGreaterThan: 200000, @@ -50,6 +42,6 @@ new Bucket(stack, 'VariesByStorageClassWithCustomSizeRule', { removalPolicy: RemovalPolicy.DESTROY, }); -new IntegTest(app, 'cdk-integ-s3-lifecycle-transition-size', { +new IntegTest(app, 'cdk-integ-s3-lifecycle-transitions', { testCases: [stack], }); \ No newline at end of file diff --git a/packages/aws-cdk-lib/aws-s3/README.md b/packages/aws-cdk-lib/aws-s3/README.md index cea462672bdc7..b39347f4dc1a6 100644 --- a/packages/aws-cdk-lib/aws-s3/README.md +++ b/packages/aws-cdk-lib/aws-s3/README.md @@ -863,21 +863,9 @@ const bucket = new s3.Bucket(this, 'MyBucket', { ``` To indicate which default minimum object size behavior is applied to the lifecycle configuration, use the -`transitionDefaultMinimumObjectSize` property. - -This property can't be specified if all rules for `lifecycleRules` don't have at least one of the following properties: - -- `abortIncompleteMultipartUploadAfter` -- `expiration` -- `expirationDate` -- `expiredObjectDeleteMarker` -- `noncurrentVersionExpiration` -- `noncurrentVersionsToRetain` -- `noncurrentVersionTransitions` -- `transitions` - -To customize the minimum object size for any transition you can add a filter that specifies a custom `objectSizeGreaterThan` -or `objectSizeLessThan` for `lifecycleRules` property. Custom filters always take precedence over the default transition behavior. +`transitionDefaultMinimumObjectSize` property. To customize the minimum object size for any transition you +can add a filter that specifies a custom `objectSizeGreaterThan` or `objectSizeLessThan` for `lifecycleRules` +property. Custom filters always take precedence over the default transition behavior. ```ts new s3.Bucket(this, 'MyBucket', { diff --git a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts index be45ca094d402..0915126c309aa 100644 --- a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts +++ b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts @@ -2269,21 +2269,6 @@ export class Bucket extends BucketBase { * @param props Par */ private parseLifecycleConfiguration(): CfnBucket.LifecycleConfigurationProperty | undefined { - const isValidTransitionDefaultMinimumObjectSize = this.lifecycleRules.every( - (rule: LifecycleRule): boolean => - rule.abortIncompleteMultipartUploadAfter !== undefined || - rule.expiration !== undefined || - rule.expirationDate !== undefined || - rule.expiredObjectDeleteMarker !== undefined || - rule.noncurrentVersionExpiration !== undefined || - rule.noncurrentVersionsToRetain !== undefined || - rule.noncurrentVersionTransitions !== undefined || - rule.transitions !== undefined, - ); - if (this.transitionDefaultMinimumObjectSize && !isValidTransitionDefaultMinimumObjectSize) { - throw new Error('TransitionDefaultMinimumObjectSize cannot be specified if all lifecycleRules don\'t have at least one of the following properties: abortIncompleteMultipartUploadAfter, expiration, expirationDate, expiredObjectDeleteMarker, noncurrentVersionExpiration, noncurrentVersionsToRetain, noncurrentVersionTransitions, or transitions'); - } - if (!this.lifecycleRules || this.lifecycleRules.length === 0) { return undefined; } diff --git a/packages/aws-cdk-lib/aws-s3/test/bucket.test.ts b/packages/aws-cdk-lib/aws-s3/test/bucket.test.ts index 248434fad4b3a..0ce54d5a999e4 100644 --- a/packages/aws-cdk-lib/aws-s3/test/bucket.test.ts +++ b/packages/aws-cdk-lib/aws-s3/test/bucket.test.ts @@ -3853,197 +3853,28 @@ describe('bucket', () => { }); }); - describe('Bucket with transitionDefaultMinimumObjectSize', () => { - test.each([ - [s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, 'all_storage_classes_128K'], - [s3.TransitionDefaultMinimumObjectSize.VARIES_BY_STORAGE_CLASS, 'varies_by_storage_class'], - ])('transitionDefaultMinimumObjectSize %s can be specified', (key, value) => { - const stack = new cdk.Stack(); - new s3.Bucket(stack, 'MyBucket', { - transitionDefaultMinimumObjectSize: key, - lifecycleRules: [ - { - expiration: cdk.Duration.days(365), - }, - ], - }); - - Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { - LifecycleConfiguration: { - TransitionDefaultMinimumObjectSize: value, - Rules: [{ - ExpirationInDays: 365, - }], + test.each([ + [s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, 'all_storage_classes_128K'], + [s3.TransitionDefaultMinimumObjectSize.VARIES_BY_STORAGE_CLASS, 'varies_by_storage_class'], + ])('transitionDefaultMinimumObjectSize %s can be specified', (key, value) => { + const stack = new cdk.Stack(); + new s3.Bucket(stack, 'MyBucket', { + transitionDefaultMinimumObjectSize: key, + lifecycleRules: [ + { + expiration: cdk.Duration.days(365), }, - }); - }); - - test('throw if there is a rule doesn\'t have required properties', () => { - const app = new cdk.App(); - const stack = new cdk.Stack(app); - new s3.Bucket(stack, 'MyBucket', { - lifecycleRules: [ - { - objectSizeLessThan: 300000, - objectSizeGreaterThan: 200000, - }, - ], - transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, - }); - expect(() => { - app.synth(); - }).toThrow(/TransitionDefaultMinimumObjectSize cannot be specified if all lifecycleRules don\'t have at least one of the following properties: abortIncompleteMultipartUploadAfter, expiration, expirationDate, expiredObjectDeleteMarker, noncurrentVersionExpiration, noncurrentVersionsToRetain, noncurrentVersionTransitions, or transitions/); - }); - - test('throw if there are a valid rule and a rule that doesn\'t have required properties.', () => { - const app = new cdk.App(); - const stack = new cdk.Stack(app); - new s3.Bucket(stack, 'MyBucket', { - lifecycleRules: [ - { - abortIncompleteMultipartUploadAfter: cdk.Duration.days(365), - }, - { - objectSizeLessThan: 300000, - objectSizeGreaterThan: 200000, - }, - ], - transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, - }); - expect(() => { - app.synth(); - }).toThrow(/TransitionDefaultMinimumObjectSize cannot be specified if all lifecycleRules don\'t have at least one of the following properties: abortIncompleteMultipartUploadAfter, expiration, expirationDate, expiredObjectDeleteMarker, noncurrentVersionExpiration, noncurrentVersionsToRetain, noncurrentVersionTransitions, or transitions/); - }); - - test('don\'t throw if transitionDefaultMinimumObjectSize with abortIncompleteMultipartUploadAfter', () => { - const stack = new cdk.Stack(); - new s3.Bucket(stack, 'MyBucket', { - lifecycleRules: [ - { - abortIncompleteMultipartUploadAfter: cdk.Duration.days(365), - }, - ], - transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, - }); - expect(() => { - Template.fromStack(stack); - }).not.toThrow(); - }); - - test('don\'t throw if transitionDefaultMinimumObjectSize with expiration', () => { - const stack = new cdk.Stack(); - new s3.Bucket(stack, 'MyBucket', { - lifecycleRules: [ - { - expiration: cdk.Duration.days(365), - }, - ], - transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, - }); - expect(() => { - Template.fromStack(stack); - }).not.toThrow(); - }); - - test('don\'t throw if transitionDefaultMinimumObjectSize with expirationDate', () => { - const stack = new cdk.Stack(); - new s3.Bucket(stack, 'MyBucket', { - lifecycleRules: [ - { - expirationDate: new Date('2024-01-01'), - }, - ], - transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, - }); - expect(() => { - Template.fromStack(stack); - }).not.toThrow(); - }); - - test('don\'t throw if transitionDefaultMinimumObjectSize with expiredObjectDeleteMarker', () => { - const stack = new cdk.Stack(); - new s3.Bucket(stack, 'MyBucket', { - lifecycleRules: [ - { - expiredObjectDeleteMarker: true, - }, - ], - transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, - }); - expect(() => { - Template.fromStack(stack); - }).not.toThrow(); - }); - - test('don\'t throw if transitionDefaultMinimumObjectSize with noncurrentVersionExpiration', () => { - const stack = new cdk.Stack(); - new s3.Bucket(stack, 'MyBucket', { - lifecycleRules: [ - { - noncurrentVersionExpiration: cdk.Duration.days(365), - }, - ], - transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, - }); - expect(() => { - Template.fromStack(stack); - }).not.toThrow(); - }); - - test('don\'t throw if transitionDefaultMinimumObjectSize with noncurrentVersionsToRetain', () => { - const stack = new cdk.Stack(); - new s3.Bucket(stack, 'MyBucket', { - lifecycleRules: [ - { - noncurrentVersionsToRetain: 10, - }, - ], - transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, - }); - expect(() => { - Template.fromStack(stack); - }).not.toThrow(); - }); - - test('don\'t throw if transitionDefaultMinimumObjectSize with noncurrentVersionTransitions', () => { - const stack = new cdk.Stack(); - new s3.Bucket(stack, 'MyBucket', { - lifecycleRules: [ - { - noncurrentVersionTransitions: [ - { - storageClass: s3.StorageClass.GLACIER_INSTANT_RETRIEVAL, - transitionAfter: cdk.Duration.days(10), - noncurrentVersionsToRetain: 1, - }, - ], - }, - ], - transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, - }); - expect(() => { - Template.fromStack(stack); - }).not.toThrow(); + ], }); - test('don\'t throw if transitionDefaultMinimumObjectSize with transitions', () => { - const stack = new cdk.Stack(); - new s3.Bucket(stack, 'MyBucket', { - lifecycleRules: [ - { - transitions: [{ - storageClass: s3.StorageClass.GLACIER, - transitionAfter: cdk.Duration.days(30), - }], - }, - ], - transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, - }); - expect(() => { - Template.fromStack(stack); - }).not.toThrow(); + Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { + LifecycleConfiguration: { + TransitionDefaultMinimumObjectSize: value, + Rules: [{ + ExpirationInDays: 365, + }], + }, }); - }); }); From 67d099e234b710735eecfbb70a74d9edc766db3e Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Fri, 18 Oct 2024 16:52:05 +0900 Subject: [PATCH 5/7] improve --- packages/aws-cdk-lib/aws-s3/README.md | 8 ++++++++ packages/aws-cdk-lib/aws-s3/lib/bucket.ts | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-s3/README.md b/packages/aws-cdk-lib/aws-s3/README.md index b39347f4dc1a6..20bda082ea24b 100644 --- a/packages/aws-cdk-lib/aws-s3/README.md +++ b/packages/aws-cdk-lib/aws-s3/README.md @@ -872,6 +872,14 @@ new s3.Bucket(this, 'MyBucket', { transitionDefaultMinimumObjectSize: s3.TransitionDefaultMinimumObjectSize.VARIES_BY_STORAGE_CLASS, lifecycleRules: [ { + transitions: [{ + storageClass: StorageClass.GLACIER, + transitionAfter: Duration.days(30), + }], + }, + { + objectSizeLessThan: 300000, + objectSizeGreaterThan: 200000, expiration: Duration.days(30), }, ], diff --git a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts index 0915126c309aa..f139bf9bdddee 100644 --- a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts +++ b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts @@ -1553,7 +1553,8 @@ export interface BucketProps { * `objectSizeGreaterThan` or `objectSizeLessThan` for `lifecycleRules` property. Custom filters always * take precedence over the default transition behavior. * - * @default TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K + * @default - TransitionDefaultMinimumObjectSize.VARIES_BY_STORAGE_CLASS before September 2024, + * otherwise TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K. */ readonly transitionDefaultMinimumObjectSize?: TransitionDefaultMinimumObjectSize; From 7151d66670c0e847632240d21aff3af9e8e60332 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Fri, 18 Oct 2024 17:03:27 +0900 Subject: [PATCH 6/7] change samples --- .../manifest.json | 2 +- .../s3-lifecycle-transitions.assets.json | 4 ++-- .../s3-lifecycle-transitions.template.json | 22 ++++++++++++++----- .../tree.json | 18 +++++++++++---- .../test/integ.lifecycle-transitions.ts | 14 ++++++++---- packages/aws-cdk-lib/aws-s3/README.md | 7 ++++-- 6 files changed, 48 insertions(+), 19 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/manifest.json index c4c807e527c74..a3ae1e633c8fb 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/manifest.json @@ -19,7 +19,7 @@ "notificationArns": [], "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/1e0d7f45f8d321fd2829de3312567d3deeb6dd4f6c753d1893936754bff6610e.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/ddad2eaffb71d50ee55436f9aff0d51b46f314389ef9056ee42d2c2cf1e0ca83.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/s3-lifecycle-transitions.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/s3-lifecycle-transitions.assets.json index 6f2b23e8b20dd..be5669105e6a6 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/s3-lifecycle-transitions.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/s3-lifecycle-transitions.assets.json @@ -1,7 +1,7 @@ { "version": "38.0.1", "files": { - "1e0d7f45f8d321fd2829de3312567d3deeb6dd4f6c753d1893936754bff6610e": { + "ddad2eaffb71d50ee55436f9aff0d51b46f314389ef9056ee42d2c2cf1e0ca83": { "source": { "path": "s3-lifecycle-transitions.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "1e0d7f45f8d321fd2829de3312567d3deeb6dd4f6c753d1893936754bff6610e.json", + "objectKey": "ddad2eaffb71d50ee55436f9aff0d51b46f314389ef9056ee42d2c2cf1e0ca83.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/s3-lifecycle-transitions.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/s3-lifecycle-transitions.template.json index cdac4a1d0d6e2..920525ca1009d 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/s3-lifecycle-transitions.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/s3-lifecycle-transitions.template.json @@ -9,16 +9,21 @@ "Status": "Enabled", "Transitions": [ { - "StorageClass": "GLACIER", + "StorageClass": "DEEP_ARCHIVE", "TransitionInDays": 30 } ] }, { - "ExpirationInDays": 30, "ObjectSizeGreaterThan": 200000, "ObjectSizeLessThan": 300000, - "Status": "Enabled" + "Status": "Enabled", + "Transitions": [ + { + "StorageClass": "ONEZONE_IA", + "TransitionInDays": 30 + } + ] } ], "TransitionDefaultMinimumObjectSize": "all_storage_classes_128K" @@ -36,16 +41,21 @@ "Status": "Enabled", "Transitions": [ { - "StorageClass": "GLACIER", + "StorageClass": "DEEP_ARCHIVE", "TransitionInDays": 30 } ] }, { - "ExpirationInDays": 30, "ObjectSizeGreaterThan": 200000, "ObjectSizeLessThan": 300000, - "Status": "Enabled" + "Status": "Enabled", + "Transitions": [ + { + "StorageClass": "ONEZONE_IA", + "TransitionInDays": 30 + } + ] } ], "TransitionDefaultMinimumObjectSize": "varies_by_storage_class" diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/tree.json index 2020166f73ccf..de565fbb364c5 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.js.snapshot/tree.json @@ -24,14 +24,19 @@ "status": "Enabled", "transitions": [ { - "storageClass": "GLACIER", + "storageClass": "DEEP_ARCHIVE", "transitionInDays": 30 } ] }, { - "expirationInDays": 30, "status": "Enabled", + "transitions": [ + { + "storageClass": "ONEZONE_IA", + "transitionInDays": 30 + } + ], "objectSizeLessThan": 300000, "objectSizeGreaterThan": 200000 } @@ -67,14 +72,19 @@ "status": "Enabled", "transitions": [ { - "storageClass": "GLACIER", + "storageClass": "DEEP_ARCHIVE", "transitionInDays": 30 } ] }, { - "expirationInDays": 30, "status": "Enabled", + "transitions": [ + { + "storageClass": "ONEZONE_IA", + "transitionInDays": 30 + } + ], "objectSizeLessThan": 300000, "objectSizeGreaterThan": 200000 } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.ts index cba133a5ddee8..fd192ee4531e5 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.lifecycle-transitions.ts @@ -10,14 +10,17 @@ new Bucket(stack, 'AllStorageClasses128K', { lifecycleRules: [ { transitions: [{ - storageClass: StorageClass.GLACIER, + storageClass: StorageClass.DEEP_ARCHIVE, transitionAfter: Duration.days(30), }], }, { objectSizeLessThan: 300000, objectSizeGreaterThan: 200000, - expiration: Duration.days(30), + transitions: [{ + storageClass: StorageClass.ONE_ZONE_INFREQUENT_ACCESS, + transitionAfter: Duration.days(30), + }], }, ], transitionDefaultMinimumObjectSize: TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K, @@ -28,14 +31,17 @@ new Bucket(stack, 'VariesByStorageClass', { lifecycleRules: [ { transitions: [{ - storageClass: StorageClass.GLACIER, + storageClass: StorageClass.DEEP_ARCHIVE, transitionAfter: Duration.days(30), }], }, { objectSizeLessThan: 300000, objectSizeGreaterThan: 200000, - expiration: Duration.days(30), + transitions: [{ + storageClass: StorageClass.ONE_ZONE_INFREQUENT_ACCESS, + transitionAfter: Duration.days(30), + }], }, ], transitionDefaultMinimumObjectSize: TransitionDefaultMinimumObjectSize.VARIES_BY_STORAGE_CLASS, diff --git a/packages/aws-cdk-lib/aws-s3/README.md b/packages/aws-cdk-lib/aws-s3/README.md index 20bda082ea24b..83bd66ccd7399 100644 --- a/packages/aws-cdk-lib/aws-s3/README.md +++ b/packages/aws-cdk-lib/aws-s3/README.md @@ -873,14 +873,17 @@ new s3.Bucket(this, 'MyBucket', { lifecycleRules: [ { transitions: [{ - storageClass: StorageClass.GLACIER, + storageClass: s3.StorageClass.DEEP_ARCHIVE, transitionAfter: Duration.days(30), }], }, { objectSizeLessThan: 300000, objectSizeGreaterThan: 200000, - expiration: Duration.days(30), + transitions: [{ + storageClass: s3.StorageClass.ONE_ZONE_INFREQUENT_ACCESS, + transitionAfter: Duration.days(30), + }], }, ], }); From 7a81153f59ad32e8fda7a00cb327c18745b70055 Mon Sep 17 00:00:00 2001 From: go-to-k <24818752+go-to-k@users.noreply.github.com> Date: Sat, 19 Oct 2024 00:25:49 +0900 Subject: [PATCH 7/7] review --- packages/aws-cdk-lib/aws-s3/README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-s3/README.md b/packages/aws-cdk-lib/aws-s3/README.md index 83bd66ccd7399..c93aa152c1d58 100644 --- a/packages/aws-cdk-lib/aws-s3/README.md +++ b/packages/aws-cdk-lib/aws-s3/README.md @@ -863,7 +863,14 @@ const bucket = new s3.Bucket(this, 'MyBucket', { ``` To indicate which default minimum object size behavior is applied to the lifecycle configuration, use the -`transitionDefaultMinimumObjectSize` property. To customize the minimum object size for any transition you +`transitionDefaultMinimumObjectSize` property. + +The default value of the property before September 2024 is `TransitionDefaultMinimumObjectSize.VARIES_BY_STORAGE_CLASS` +that allows objects smaller than 128 KB to be transitioned only to the S3 Glacier and S3 Glacier Deep Archive storage classes, +otherwise `TransitionDefaultMinimumObjectSize.ALL_STORAGE_CLASSES_128_K` that prevents objects smaller than 128 KB from being +transitioned to any storage class. + +To customize the minimum object size for any transition you can add a filter that specifies a custom `objectSizeGreaterThan` or `objectSizeLessThan` for `lifecycleRules` property. Custom filters always take precedence over the default transition behavior.