From 87b007b1a01b1b2e2e4f89cfe96ffe06f0f57ed2 Mon Sep 17 00:00:00 2001 From: sakurai-ryo Date: Sat, 20 Jan 2024 17:20:02 +0900 Subject: [PATCH 1/5] feat: partitioned key format for log objects --- .../aws-cdk-s3-access-logs.assets.json | 6 +- .../aws-cdk-s3-access-logs.template.json | 160 ++++++++++++ .../cdk.out | 2 +- ...efaultTestDeployAssert37A16466.assets.json | 2 +- .../integ.json | 2 +- .../manifest.json | 24 +- .../tree.json | 242 ++++++++++++++++-- .../test/integ.bucket.server-access-logs.ts | 23 +- packages/aws-cdk-lib/aws-s3/README.md | 36 +++ packages/aws-cdk-lib/aws-s3/lib/bucket.ts | 69 +++++ .../aws-cdk-lib/aws-s3/test/bucket.test.ts | 72 ++++++ 11 files changed, 612 insertions(+), 26 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.assets.json index 9c6efb372abf0..a445112b4cb96 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.assets.json @@ -1,7 +1,7 @@ { - "version": "30.1.0", + "version": "36.0.0", "files": { - "f58a2b25314952a1a5a6b42c6b9092caf2710430af09ba4f5d807e60f2fd3542": { + "1e864d28ce4b6485c2f33c2ae301f5a43b674db7f30f7938fc7df5ce80cf8499": { "source": { "path": "aws-cdk-s3-access-logs.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "f58a2b25314952a1a5a6b42c6b9092caf2710430af09ba4f5d807e60f2fd3542.json", + "objectKey": "1e864d28ce4b6485c2f33c2ae301f5a43b674db7f30f7938fc7df5ce80cf8499.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.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.template.json index 532e9c171c422..81189cc74f4a7 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.template.json @@ -48,6 +48,114 @@ ] ] } + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "MyBucket26E0C3623", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyAccessLogsBucketF7FE6635", + "Arn" + ] + }, + "/example*" + ] + ] + } + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "MyBucket3CC4F8735", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyAccessLogsBucketF7FE6635", + "Arn" + ] + }, + "/example*" + ] + ] + } + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "MyBucket43E0A113B", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyAccessLogsBucketF7FE6635", + "Arn" + ] + }, + "/example*" + ] + ] + } } ], "Version": "2012-10-17" @@ -66,6 +174,58 @@ }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" + }, + "MyBucket26E0C3623": { + "Type": "AWS::S3::Bucket", + "Properties": { + "LoggingConfiguration": { + "DestinationBucketName": { + "Ref": "MyAccessLogsBucketF7FE6635" + }, + "LogFilePrefix": "example", + "TargetObjectKeyFormat": { + "SimplePrefix": {} + } + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "MyBucket3CC4F8735": { + "Type": "AWS::S3::Bucket", + "Properties": { + "LoggingConfiguration": { + "DestinationBucketName": { + "Ref": "MyAccessLogsBucketF7FE6635" + }, + "LogFilePrefix": "example", + "TargetObjectKeyFormat": { + "PartitionedPrefix": { + "PartitionDateSource": "EventTime" + } + } + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "MyBucket43E0A113B": { + "Type": "AWS::S3::Bucket", + "Properties": { + "LoggingConfiguration": { + "DestinationBucketName": { + "Ref": "MyAccessLogsBucketF7FE6635" + }, + "LogFilePrefix": "example", + "TargetObjectKeyFormat": { + "PartitionedPrefix": { + "PartitionDateSource": "DeliveryTime" + } + } + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" } }, "Parameters": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/cdk.out index b72fef144f05c..1f0068d32659a 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"30.1.0"} \ No newline at end of file +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/cdkintegs3accesslogsDefaultTestDeployAssert37A16466.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/cdkintegs3accesslogsDefaultTestDeployAssert37A16466.assets.json index 44d48a4bd52ea..2af6ed5d8020a 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/cdkintegs3accesslogsDefaultTestDeployAssert37A16466.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/cdkintegs3accesslogsDefaultTestDeployAssert37A16466.assets.json @@ -1,5 +1,5 @@ { - "version": "30.1.0", + "version": "36.0.0", "files": { "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { "source": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/integ.json index db07e940c872b..77b2ab1a83688 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "30.1.0", + "version": "36.0.0", "testCases": { "cdk-integ-s3-access-logs/DefaultTest": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/manifest.json index f8bde1cb1a252..d274353ea4052 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/manifest.json @@ -1,5 +1,5 @@ { - "version": "30.1.0", + "version": "36.0.0", "artifacts": { "aws-cdk-s3-access-logs.assets": { "type": "cdk:asset-manifest", @@ -14,10 +14,11 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "aws-cdk-s3-access-logs.template.json", + "terminationProtection": false, "validateOnSynth": false, "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}/f58a2b25314952a1a5a6b42c6b9092caf2710430af09ba4f5d807e60f2fd3542.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/1e864d28ce4b6485c2f33c2ae301f5a43b674db7f30f7938fc7df5ce80cf8499.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -51,6 +52,24 @@ "data": "MyBucketF68F3FF0" } ], + "/aws-cdk-s3-access-logs/MyBucket2/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyBucket26E0C3623" + } + ], + "/aws-cdk-s3-access-logs/MyBucket3/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyBucket3CC4F8735" + } + ], + "/aws-cdk-s3-access-logs/MyBucket4/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyBucket43E0A113B" + } + ], "/aws-cdk-s3-access-logs/BootstrapVersion": [ { "type": "aws:cdk:logicalId", @@ -79,6 +98,7 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "cdkintegs3accesslogsDefaultTestDeployAssert37A16466.template.json", + "terminationProtection": false, "validateOnSynth": false, "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}", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/tree.json index dc67221905049..95dbb1490c3ec 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/tree.json @@ -20,7 +20,7 @@ "aws:cdk:cloudformation:props": {} }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucket", + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", "version": "0.0.0" } }, @@ -74,6 +74,114 @@ ] ] } + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "MyBucket26E0C3623", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyAccessLogsBucketF7FE6635", + "Arn" + ] + }, + "/example*" + ] + ] + } + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "MyBucket3CC4F8735", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyAccessLogsBucketF7FE6635", + "Arn" + ] + }, + "/example*" + ] + ] + } + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "MyBucket43E0A113B", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyAccessLogsBucketF7FE6635", + "Arn" + ] + }, + "/example*" + ] + ] + } } ], "Version": "2012-10-17" @@ -81,19 +189,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucketPolicy", + "fqn": "aws-cdk-lib.aws_s3.CfnBucketPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.BucketPolicy", + "fqn": "aws-cdk-lib.aws_s3.BucketPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.Bucket", + "fqn": "aws-cdk-lib.aws_s3.Bucket", "version": "0.0.0" } }, @@ -116,13 +224,113 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucket", + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.Bucket", + "version": "0.0.0" + } + }, + "MyBucket2": { + "id": "MyBucket2", + "path": "aws-cdk-s3-access-logs/MyBucket2", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-s3-access-logs/MyBucket2/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::Bucket", + "aws:cdk:cloudformation:props": { + "loggingConfiguration": { + "destinationBucketName": { + "Ref": "MyAccessLogsBucketF7FE6635" + }, + "logFilePrefix": "example", + "targetObjectKeyFormat": { + "simplePrefix": {} + } + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.Bucket", + "version": "0.0.0" + } + }, + "MyBucket3": { + "id": "MyBucket3", + "path": "aws-cdk-s3-access-logs/MyBucket3", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-s3-access-logs/MyBucket3/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::Bucket", + "aws:cdk:cloudformation:props": { + "loggingConfiguration": { + "destinationBucketName": { + "Ref": "MyAccessLogsBucketF7FE6635" + }, + "logFilePrefix": "example", + "targetObjectKeyFormat": { + "partitionedPrefix": { + "partitionDateSource": "EventTime" + } + } + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.Bucket", + "version": "0.0.0" + } + }, + "MyBucket4": { + "id": "MyBucket4", + "path": "aws-cdk-s3-access-logs/MyBucket4", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-s3-access-logs/MyBucket4/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::Bucket", + "aws:cdk:cloudformation:props": { + "loggingConfiguration": { + "destinationBucketName": { + "Ref": "MyAccessLogsBucketF7FE6635" + }, + "logFilePrefix": "example", + "targetObjectKeyFormat": { + "partitionedPrefix": { + "partitionDateSource": "DeliveryTime" + } + } + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.Bucket", + "fqn": "aws-cdk-lib.aws_s3.Bucket", "version": "0.0.0" } }, @@ -130,7 +338,7 @@ "id": "BootstrapVersion", "path": "aws-cdk-s3-access-logs/BootstrapVersion", "constructInfo": { - "fqn": "@aws-cdk/core.CfnParameter", + "fqn": "aws-cdk-lib.CfnParameter", "version": "0.0.0" } }, @@ -138,13 +346,13 @@ "id": "CheckBootstrapVersion", "path": "aws-cdk-s3-access-logs/CheckBootstrapVersion", "constructInfo": { - "fqn": "@aws-cdk/core.CfnRule", + "fqn": "aws-cdk-lib.CfnRule", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/core.Stack", + "fqn": "aws-cdk-lib.Stack", "version": "0.0.0" } }, @@ -161,7 +369,7 @@ "path": "cdk-integ-s3-access-logs/DefaultTest/Default", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.252" + "version": "10.3.0" } }, "DeployAssert": { @@ -172,7 +380,7 @@ "id": "BootstrapVersion", "path": "cdk-integ-s3-access-logs/DefaultTest/DeployAssert/BootstrapVersion", "constructInfo": { - "fqn": "@aws-cdk/core.CfnParameter", + "fqn": "aws-cdk-lib.CfnParameter", "version": "0.0.0" } }, @@ -180,25 +388,25 @@ "id": "CheckBootstrapVersion", "path": "cdk-integ-s3-access-logs/DefaultTest/DeployAssert/CheckBootstrapVersion", "constructInfo": { - "fqn": "@aws-cdk/core.CfnRule", + "fqn": "aws-cdk-lib.CfnRule", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/core.Stack", + "fqn": "aws-cdk-lib.Stack", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/integ-tests.IntegTestCase", + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/integ-tests.IntegTest", + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", "version": "0.0.0" } }, @@ -207,12 +415,12 @@ "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.252" + "version": "10.3.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/core.App", + "fqn": "aws-cdk-lib.App", "version": "0.0.0" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.ts index 105eac7716fc0..b3c4c2dc8b6c2 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.ts @@ -17,6 +17,27 @@ new s3.Bucket(stack, 'MyBucket', { removalPolicy: cdk.RemovalPolicy.DESTROY, }); +new s3.Bucket(stack, 'MyBucket2', { + serverAccessLogsBucket: accessLogBucket, + serverAccessLogsPrefix: 'example', + logObjectKeyFormat: s3.LogObjectKeyFormat.simplePrefix(), + removalPolicy: cdk.RemovalPolicy.DESTROY, +}); + +new s3.Bucket(stack, 'MyBucket3', { + serverAccessLogsBucket: accessLogBucket, + serverAccessLogsPrefix: 'example', + logObjectKeyFormat: s3.LogObjectKeyFormat.partitionedPrefix(s3.PartitionDateSource.EVENT_TIME), + removalPolicy: cdk.RemovalPolicy.DESTROY, +}); + +new s3.Bucket(stack, 'MyBucket4', { + serverAccessLogsBucket: accessLogBucket, + serverAccessLogsPrefix: 'example', + logObjectKeyFormat: s3.LogObjectKeyFormat.partitionedPrefix(s3.PartitionDateSource.DELIVERY_TIME), + removalPolicy: cdk.RemovalPolicy.DESTROY, +}); + new IntegTest(app, 'cdk-integ-s3-access-logs', { 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 5be9a411c8860..2d0bc51046170 100644 --- a/packages/aws-cdk-lib/aws-s3/README.md +++ b/packages/aws-cdk-lib/aws-s3/README.md @@ -402,6 +402,42 @@ const bucket = new s3.Bucket(this, 'MyBucket', { }); ``` +You have two options for the log object key format. +`Non-date-based partitioning` is the default log object key format and appears as follows: + +```txt +[DestinationPrefix][YYYY]-[MM]-[DD]-[hh]-[mm]-[ss]-[UniqueString] +``` + +```ts +const accessLogsBucket = new s3.Bucket(this, 'AccessLogsBucket'); + +const bucket = new s3.Bucket(this, 'MyBucket', { + serverAccessLogsBucket: accessLogsBucket, + serverAccessLogsPrefix: 'logs', + // You can use a simple prefix with `LogObjectKeyFormat.simplePrefix()`, but it is the same even if you do not specify it. + logObjectKeyFormat: s3.LogObjectKeyFormat.simplePrefix(), +}); +``` + +Another option is `Date-based partitioning`. +If you choose this format, you can select either the event time or the delivery time of the log file as the date source used in the log format. +This format appears as follows: + +```txt +[DestinationPrefix][SourceAccountId]/[SourceRegion]/[SourceBucket]/[YYYY]/[MM]/[DD]/[YYYY]-[MM]-[DD]-[hh]-[mm]-[ss]-[UniqueString] +``` + +```ts +const accessLogsBucket = new s3.Bucket(this, 'AccessLogsBucket'); + +const bucket = new s3.Bucket(this, 'MyBucket', { + serverAccessLogsBucket: accessLogsBucket, + serverAccessLogsPrefix: 'logs', + logObjectKeyFormat: s3.LogObjectKeyFormat.partitionedPrefix(s3.PartitionDateSource.EVENT_TIME), +}); +``` + ### Allowing access log delivery using a Bucket Policy (recommended) When possible, it is recommended to use a bucket policy to grant access instead of diff --git a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts index 79e3fabddcbe8..b088d4809c635 100644 --- a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts +++ b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts @@ -1336,6 +1336,67 @@ export interface IntelligentTieringConfiguration { readonly deepArchiveAccessTierTime?: Duration; } +/** + * The date source for the partitioned prefix. + */ +export enum PartitionDateSource { + /** + * The year, month, and day will be based on the timestamp of the S3 event in the file that's been delivered. + */ + EVENT_TIME = 'EventTime', + + /** + * The year, month, and day will be based on the time when the log file was delivered to S3. + */ + DELIVERY_TIME = 'DeliveryTime', +} + +/** + * The key format of the log object. + */ +export abstract class LogObjectKeyFormat { + /** + * Use partitioned prefix for log objects. + * + * The partitioned prefix format as follow: + * [DestinationPrefix][SourceAccountId]/​[SourceRegion]/​[SourceBucket]/​[YYYY]/​[MM]/​[DD]/​[YYYY]-[MM]-[DD]-[hh]-[mm]-[ss]-[UniqueString] + */ + public static partitionedPrefix(dateSource?: PartitionDateSource): LogObjectKeyFormat { + return new class extends LogObjectKeyFormat { + public _render(): CfnBucket.LoggingConfigurationProperty['targetObjectKeyFormat'] { + return { + partitionedPrefix: { + partitionDateSource: dateSource, + }, + }; + } + }(); + } + + /** + * Use the simple prefix for log objects. + * + * The simple prefix format as follow: + * [DestinationPrefix][YYYY]-[MM]-[DD]-[hh]-[mm]-[ss]-[UniqueString] + */ + public static simplePrefix(): LogObjectKeyFormat { + return new class extends LogObjectKeyFormat { + public _render(): CfnBucket.LoggingConfigurationProperty['targetObjectKeyFormat'] { + return { + simplePrefix: {}, + }; + } + }(); + } + + /** + * Render the log file key format. + * + * @internal + */ + public abstract _render(): CfnBucket.LoggingConfigurationProperty['targetObjectKeyFormat']; +} + export interface BucketProps { /** * The kind of server-side encryption to apply to this bucket. @@ -1544,6 +1605,13 @@ export interface BucketProps { */ readonly serverAccessLogsPrefix?: string; + /** + * Optional key format for log objects. + * + * @default - the default key format is: [DestinationPrefix][YYYY]-[MM]-[DD]-[hh]-[mm]-[ss]-[UniqueString] + */ + readonly logObjectKeyFormat?: LogObjectKeyFormat; + /** * The inventory configuration of the bucket. * @@ -2213,6 +2281,7 @@ export class Bucket extends BucketBase { return { destinationBucketName: props.serverAccessLogsBucket?.bucketName, logFilePrefix: props.serverAccessLogsPrefix, + targetObjectKeyFormat: props.logObjectKeyFormat?._render(), }; } 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 14f076c419852..0a0953fdf4ada 100644 --- a/packages/aws-cdk-lib/aws-s3/test/bucket.test.ts +++ b/packages/aws-cdk-lib/aws-s3/test/bucket.test.ts @@ -2858,6 +2858,7 @@ describe('bucket', () => { DestinationBucketName: { Ref: 'AccessLogs8B620ECA', }, + TargetObjectKeyFormat: Match.absent(), }, }); }); @@ -2880,6 +2881,7 @@ describe('bucket', () => { Ref: 'AccessLogs8B620ECA', }, LogFilePrefix: 'hello', + TargetObjectKeyFormat: Match.absent(), }, }); }); @@ -2896,6 +2898,76 @@ describe('bucket', () => { Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { LoggingConfiguration: { LogFilePrefix: 'hello', + TargetObjectKeyFormat: Match.absent(), + }, + }); + }); + + test('Use simple prefix for log objects', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + const accessLogBucket = new s3.Bucket(stack, 'AccessLogs'); + new s3.Bucket(stack, 'MyBucket', { + serverAccessLogsBucket: accessLogBucket, + logObjectKeyFormat: s3.LogObjectKeyFormat.simplePrefix(), + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { + LoggingConfiguration: { + DestinationBucketName: { + Ref: 'AccessLogs8B620ECA', + }, + TargetObjectKeyFormat: { + SimplePrefix: {}, + PartitionedPrefix: Match.absent(), + }, + }, + }); + }); + + test('Use partitioned prefix for log objects', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + const accessLogBucket = new s3.Bucket(stack, 'AccessLogs'); + new s3.Bucket(stack, 'MyBucket', { + serverAccessLogsBucket: accessLogBucket, + logObjectKeyFormat: s3.LogObjectKeyFormat.partitionedPrefix(s3.PartitionDateSource.EVENT_TIME), + }); + new s3.Bucket(stack, 'MyBucket2', { + serverAccessLogsBucket: accessLogBucket, + logObjectKeyFormat: s3.LogObjectKeyFormat.partitionedPrefix(s3.PartitionDateSource.DELIVERY_TIME), + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { + LoggingConfiguration: { + DestinationBucketName: { + Ref: 'AccessLogs8B620ECA', + }, + TargetObjectKeyFormat: { + SimplePrefix: Match.absent(), + PartitionedPrefix: { + PartitionDateSource: 'EventTime', + }, + }, + }, + }); + Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { + LoggingConfiguration: { + DestinationBucketName: { + Ref: 'AccessLogs8B620ECA', + }, + TargetObjectKeyFormat: { + SimplePrefix: Match.absent(), + PartitionedPrefix: { + PartitionDateSource: 'DeliveryTime', + }, + }, }, }); }); From 2f823fd30cc106099b8519a67f26a35bd9790ef5 Mon Sep 17 00:00:00 2001 From: sakurai-ryo Date: Sat, 20 Jan 2024 17:44:01 +0900 Subject: [PATCH 2/5] fix comments --- packages/aws-cdk-lib/aws-s3/lib/bucket.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts index b088d4809c635..1e47416fa5c58 100644 --- a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts +++ b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts @@ -1352,7 +1352,7 @@ export enum PartitionDateSource { } /** - * The key format of the log object. + * The key format for the log object. */ export abstract class LogObjectKeyFormat { /** From 2b03fbaed611f3f96766391ed5cfd71511ab5bdd Mon Sep 17 00:00:00 2001 From: sakurai-ryo Date: Sat, 20 Jan 2024 19:10:29 +0900 Subject: [PATCH 3/5] fix integ --- .../aws-cdk-s3-access-logs.assets.json | 4 ++-- .../aws-cdk-s3-access-logs.template.json | 12 ++++++------ .../manifest.json | 2 +- .../tree.json | 12 ++++++------ .../aws-s3/test/integ.bucket.server-access-logs.ts | 6 +++--- packages/aws-cdk-lib/aws-s3/README.md | 2 +- packages/aws-cdk-lib/aws-s3/lib/bucket.ts | 2 +- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.assets.json index a445112b4cb96..74fb874270d1e 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.assets.json @@ -1,7 +1,7 @@ { "version": "36.0.0", "files": { - "1e864d28ce4b6485c2f33c2ae301f5a43b674db7f30f7938fc7df5ce80cf8499": { + "601d0ce9725592b759f3bd2c3b652455c109a6f6e18aad08373bfb5d0c005f56": { "source": { "path": "aws-cdk-s3-access-logs.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "1e864d28ce4b6485c2f33c2ae301f5a43b674db7f30f7938fc7df5ce80cf8499.json", + "objectKey": "601d0ce9725592b759f3bd2c3b652455c109a6f6e18aad08373bfb5d0c005f56.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.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.template.json index 81189cc74f4a7..fda8cbeaee8c3 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.template.json @@ -80,7 +80,7 @@ "Arn" ] }, - "/example*" + "/example2*" ] ] } @@ -116,7 +116,7 @@ "Arn" ] }, - "/example*" + "/example3*" ] ] } @@ -152,7 +152,7 @@ "Arn" ] }, - "/example*" + "/example4*" ] ] } @@ -182,7 +182,7 @@ "DestinationBucketName": { "Ref": "MyAccessLogsBucketF7FE6635" }, - "LogFilePrefix": "example", + "LogFilePrefix": "example2", "TargetObjectKeyFormat": { "SimplePrefix": {} } @@ -198,7 +198,7 @@ "DestinationBucketName": { "Ref": "MyAccessLogsBucketF7FE6635" }, - "LogFilePrefix": "example", + "LogFilePrefix": "example3", "TargetObjectKeyFormat": { "PartitionedPrefix": { "PartitionDateSource": "EventTime" @@ -216,7 +216,7 @@ "DestinationBucketName": { "Ref": "MyAccessLogsBucketF7FE6635" }, - "LogFilePrefix": "example", + "LogFilePrefix": "example4", "TargetObjectKeyFormat": { "PartitionedPrefix": { "PartitionDateSource": "DeliveryTime" diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/manifest.json index d274353ea4052..1506b6d2b3c2b 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/manifest.json @@ -18,7 +18,7 @@ "validateOnSynth": false, "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}/1e864d28ce4b6485c2f33c2ae301f5a43b674db7f30f7938fc7df5ce80cf8499.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/601d0ce9725592b759f3bd2c3b652455c109a6f6e18aad08373bfb5d0c005f56.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/tree.json index 95dbb1490c3ec..d612662bda3aa 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/tree.json @@ -106,7 +106,7 @@ "Arn" ] }, - "/example*" + "/example2*" ] ] } @@ -142,7 +142,7 @@ "Arn" ] }, - "/example*" + "/example3*" ] ] } @@ -178,7 +178,7 @@ "Arn" ] }, - "/example*" + "/example4*" ] ] } @@ -248,7 +248,7 @@ "destinationBucketName": { "Ref": "MyAccessLogsBucketF7FE6635" }, - "logFilePrefix": "example", + "logFilePrefix": "example2", "targetObjectKeyFormat": { "simplePrefix": {} } @@ -280,7 +280,7 @@ "destinationBucketName": { "Ref": "MyAccessLogsBucketF7FE6635" }, - "logFilePrefix": "example", + "logFilePrefix": "example3", "targetObjectKeyFormat": { "partitionedPrefix": { "partitionDateSource": "EventTime" @@ -314,7 +314,7 @@ "destinationBucketName": { "Ref": "MyAccessLogsBucketF7FE6635" }, - "logFilePrefix": "example", + "logFilePrefix": "example4", "targetObjectKeyFormat": { "partitionedPrefix": { "partitionDateSource": "DeliveryTime" diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.ts index b3c4c2dc8b6c2..707221839384d 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.ts @@ -19,21 +19,21 @@ new s3.Bucket(stack, 'MyBucket', { new s3.Bucket(stack, 'MyBucket2', { serverAccessLogsBucket: accessLogBucket, - serverAccessLogsPrefix: 'example', + serverAccessLogsPrefix: 'example2', logObjectKeyFormat: s3.LogObjectKeyFormat.simplePrefix(), removalPolicy: cdk.RemovalPolicy.DESTROY, }); new s3.Bucket(stack, 'MyBucket3', { serverAccessLogsBucket: accessLogBucket, - serverAccessLogsPrefix: 'example', + serverAccessLogsPrefix: 'example3', logObjectKeyFormat: s3.LogObjectKeyFormat.partitionedPrefix(s3.PartitionDateSource.EVENT_TIME), removalPolicy: cdk.RemovalPolicy.DESTROY, }); new s3.Bucket(stack, 'MyBucket4', { serverAccessLogsBucket: accessLogBucket, - serverAccessLogsPrefix: 'example', + serverAccessLogsPrefix: 'example4', logObjectKeyFormat: s3.LogObjectKeyFormat.partitionedPrefix(s3.PartitionDateSource.DELIVERY_TIME), removalPolicy: cdk.RemovalPolicy.DESTROY, }); diff --git a/packages/aws-cdk-lib/aws-s3/README.md b/packages/aws-cdk-lib/aws-s3/README.md index 2d0bc51046170..40210d78227e2 100644 --- a/packages/aws-cdk-lib/aws-s3/README.md +++ b/packages/aws-cdk-lib/aws-s3/README.md @@ -415,7 +415,7 @@ const accessLogsBucket = new s3.Bucket(this, 'AccessLogsBucket'); const bucket = new s3.Bucket(this, 'MyBucket', { serverAccessLogsBucket: accessLogsBucket, serverAccessLogsPrefix: 'logs', - // You can use a simple prefix with `LogObjectKeyFormat.simplePrefix()`, but it is the same even if you do not specify it. + // You can use a simple prefix with `LogObjectKeyFormat.simplePrefix()`, but it is the same even if you do not specify `logObjectKeyFormat` property. logObjectKeyFormat: s3.LogObjectKeyFormat.simplePrefix(), }); ``` diff --git a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts index 1e47416fa5c58..332bc819d89cb 100644 --- a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts +++ b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts @@ -1390,7 +1390,7 @@ export abstract class LogObjectKeyFormat { } /** - * Render the log file key format. + * Render the log object key format. * * @internal */ From 8fc98572e0948899151060f5657a510ebedb8bfb Mon Sep 17 00:00:00 2001 From: sakurai-ryo Date: Tue, 23 Jan 2024 12:38:52 +0900 Subject: [PATCH 4/5] Update S3 bucket log object key format --- .../aws-s3/test/integ.bucket.server-access-logs.ts | 6 +++--- packages/aws-cdk-lib/aws-s3/README.md | 6 +++--- packages/aws-cdk-lib/aws-s3/lib/bucket.ts | 14 +++++++------- packages/aws-cdk-lib/aws-s3/test/bucket.test.ts | 6 +++--- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.ts index 707221839384d..0322c70047960 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.ts @@ -20,21 +20,21 @@ new s3.Bucket(stack, 'MyBucket', { new s3.Bucket(stack, 'MyBucket2', { serverAccessLogsBucket: accessLogBucket, serverAccessLogsPrefix: 'example2', - logObjectKeyFormat: s3.LogObjectKeyFormat.simplePrefix(), + targetObjectKeyFormat: s3.TargetObjectKeyFormat.simplePrefix(), removalPolicy: cdk.RemovalPolicy.DESTROY, }); new s3.Bucket(stack, 'MyBucket3', { serverAccessLogsBucket: accessLogBucket, serverAccessLogsPrefix: 'example3', - logObjectKeyFormat: s3.LogObjectKeyFormat.partitionedPrefix(s3.PartitionDateSource.EVENT_TIME), + targetObjectKeyFormat: s3.TargetObjectKeyFormat.partitionedPrefix(s3.PartitionDateSource.EVENT_TIME), removalPolicy: cdk.RemovalPolicy.DESTROY, }); new s3.Bucket(stack, 'MyBucket4', { serverAccessLogsBucket: accessLogBucket, serverAccessLogsPrefix: 'example4', - logObjectKeyFormat: s3.LogObjectKeyFormat.partitionedPrefix(s3.PartitionDateSource.DELIVERY_TIME), + targetObjectKeyFormat: s3.TargetObjectKeyFormat.partitionedPrefix(s3.PartitionDateSource.DELIVERY_TIME), removalPolicy: cdk.RemovalPolicy.DESTROY, }); diff --git a/packages/aws-cdk-lib/aws-s3/README.md b/packages/aws-cdk-lib/aws-s3/README.md index 40210d78227e2..247dadc0b1373 100644 --- a/packages/aws-cdk-lib/aws-s3/README.md +++ b/packages/aws-cdk-lib/aws-s3/README.md @@ -415,8 +415,8 @@ const accessLogsBucket = new s3.Bucket(this, 'AccessLogsBucket'); const bucket = new s3.Bucket(this, 'MyBucket', { serverAccessLogsBucket: accessLogsBucket, serverAccessLogsPrefix: 'logs', - // You can use a simple prefix with `LogObjectKeyFormat.simplePrefix()`, but it is the same even if you do not specify `logObjectKeyFormat` property. - logObjectKeyFormat: s3.LogObjectKeyFormat.simplePrefix(), + // You can use a simple prefix with `TargetObjectKeyFormat.simplePrefix()`, but it is the same even if you do not specify `targetObjectKeyFormat` property. + targetObjectKeyFormat: s3.TargetObjectKeyFormat.simplePrefix(), }); ``` @@ -434,7 +434,7 @@ const accessLogsBucket = new s3.Bucket(this, 'AccessLogsBucket'); const bucket = new s3.Bucket(this, 'MyBucket', { serverAccessLogsBucket: accessLogsBucket, serverAccessLogsPrefix: 'logs', - logObjectKeyFormat: s3.LogObjectKeyFormat.partitionedPrefix(s3.PartitionDateSource.EVENT_TIME), + targetObjectKeyFormat: s3.TargetObjectKeyFormat.partitionedPrefix(s3.PartitionDateSource.EVENT_TIME), }); ``` diff --git a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts index 332bc819d89cb..142a579f15038 100644 --- a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts +++ b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts @@ -1354,15 +1354,15 @@ export enum PartitionDateSource { /** * The key format for the log object. */ -export abstract class LogObjectKeyFormat { +export abstract class TargetObjectKeyFormat { /** * Use partitioned prefix for log objects. * * The partitioned prefix format as follow: * [DestinationPrefix][SourceAccountId]/​[SourceRegion]/​[SourceBucket]/​[YYYY]/​[MM]/​[DD]/​[YYYY]-[MM]-[DD]-[hh]-[mm]-[ss]-[UniqueString] */ - public static partitionedPrefix(dateSource?: PartitionDateSource): LogObjectKeyFormat { - return new class extends LogObjectKeyFormat { + public static partitionedPrefix(dateSource?: PartitionDateSource): TargetObjectKeyFormat { + return new class extends TargetObjectKeyFormat { public _render(): CfnBucket.LoggingConfigurationProperty['targetObjectKeyFormat'] { return { partitionedPrefix: { @@ -1379,8 +1379,8 @@ export abstract class LogObjectKeyFormat { * The simple prefix format as follow: * [DestinationPrefix][YYYY]-[MM]-[DD]-[hh]-[mm]-[ss]-[UniqueString] */ - public static simplePrefix(): LogObjectKeyFormat { - return new class extends LogObjectKeyFormat { + public static simplePrefix(): TargetObjectKeyFormat { + return new class extends TargetObjectKeyFormat { public _render(): CfnBucket.LoggingConfigurationProperty['targetObjectKeyFormat'] { return { simplePrefix: {}, @@ -1610,7 +1610,7 @@ export interface BucketProps { * * @default - the default key format is: [DestinationPrefix][YYYY]-[MM]-[DD]-[hh]-[mm]-[ss]-[UniqueString] */ - readonly logObjectKeyFormat?: LogObjectKeyFormat; + readonly targetObjectKeyFormat?: TargetObjectKeyFormat; /** * The inventory configuration of the bucket. @@ -2281,7 +2281,7 @@ export class Bucket extends BucketBase { return { destinationBucketName: props.serverAccessLogsBucket?.bucketName, logFilePrefix: props.serverAccessLogsPrefix, - targetObjectKeyFormat: props.logObjectKeyFormat?._render(), + targetObjectKeyFormat: props.targetObjectKeyFormat?._render(), }; } 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 0a0953fdf4ada..956f66e7d12e6 100644 --- a/packages/aws-cdk-lib/aws-s3/test/bucket.test.ts +++ b/packages/aws-cdk-lib/aws-s3/test/bucket.test.ts @@ -2911,7 +2911,7 @@ describe('bucket', () => { const accessLogBucket = new s3.Bucket(stack, 'AccessLogs'); new s3.Bucket(stack, 'MyBucket', { serverAccessLogsBucket: accessLogBucket, - logObjectKeyFormat: s3.LogObjectKeyFormat.simplePrefix(), + targetObjectKeyFormat: s3.TargetObjectKeyFormat.simplePrefix(), }); // THEN @@ -2936,11 +2936,11 @@ describe('bucket', () => { const accessLogBucket = new s3.Bucket(stack, 'AccessLogs'); new s3.Bucket(stack, 'MyBucket', { serverAccessLogsBucket: accessLogBucket, - logObjectKeyFormat: s3.LogObjectKeyFormat.partitionedPrefix(s3.PartitionDateSource.EVENT_TIME), + targetObjectKeyFormat: s3.TargetObjectKeyFormat.partitionedPrefix(s3.PartitionDateSource.EVENT_TIME), }); new s3.Bucket(stack, 'MyBucket2', { serverAccessLogsBucket: accessLogBucket, - logObjectKeyFormat: s3.LogObjectKeyFormat.partitionedPrefix(s3.PartitionDateSource.DELIVERY_TIME), + targetObjectKeyFormat: s3.TargetObjectKeyFormat.partitionedPrefix(s3.PartitionDateSource.DELIVERY_TIME), }); // THEN From 1755012d897acbfc991d6f729739cff1b812d0f9 Mon Sep 17 00:00:00 2001 From: sakurai-ryo Date: Thu, 25 Jan 2024 10:52:16 +0900 Subject: [PATCH 5/5] Add server access logs configuration for MyBucket5 --- .../aws-cdk-s3-access-logs.assets.json | 4 +- .../aws-cdk-s3-access-logs.template.json | 52 ++++++++++++++ .../manifest.json | 8 ++- .../tree.json | 68 +++++++++++++++++++ .../test/integ.bucket.server-access-logs.ts | 7 ++ packages/aws-cdk-lib/aws-s3/lib/bucket.ts | 1 + 6 files changed, 137 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.assets.json index 74fb874270d1e..710c7bc9c332b 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.assets.json @@ -1,7 +1,7 @@ { "version": "36.0.0", "files": { - "601d0ce9725592b759f3bd2c3b652455c109a6f6e18aad08373bfb5d0c005f56": { + "680224db1786deb417c994d38f450f115dd410266ba1ffc919b54991e5a73e4a": { "source": { "path": "aws-cdk-s3-access-logs.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "601d0ce9725592b759f3bd2c3b652455c109a6f6e18aad08373bfb5d0c005f56.json", + "objectKey": "680224db1786deb417c994d38f450f115dd410266ba1ffc919b54991e5a73e4a.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.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.template.json index fda8cbeaee8c3..35aad51534a6e 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/aws-cdk-s3-access-logs.template.json @@ -156,6 +156,42 @@ ] ] } + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "MyBucket53983D51A", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyAccessLogsBucketF7FE6635", + "Arn" + ] + }, + "/example5*" + ] + ] + } } ], "Version": "2012-10-17" @@ -226,6 +262,22 @@ }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" + }, + "MyBucket53983D51A": { + "Type": "AWS::S3::Bucket", + "Properties": { + "LoggingConfiguration": { + "DestinationBucketName": { + "Ref": "MyAccessLogsBucketF7FE6635" + }, + "LogFilePrefix": "example5", + "TargetObjectKeyFormat": { + "PartitionedPrefix": {} + } + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" } }, "Parameters": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/manifest.json index 1506b6d2b3c2b..52a79daade82a 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/manifest.json @@ -18,7 +18,7 @@ "validateOnSynth": false, "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}/601d0ce9725592b759f3bd2c3b652455c109a6f6e18aad08373bfb5d0c005f56.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/680224db1786deb417c994d38f450f115dd410266ba1ffc919b54991e5a73e4a.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -70,6 +70,12 @@ "data": "MyBucket43E0A113B" } ], + "/aws-cdk-s3-access-logs/MyBucket5/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyBucket53983D51A" + } + ], "/aws-cdk-s3-access-logs/BootstrapVersion": [ { "type": "aws:cdk:logicalId", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/tree.json index d612662bda3aa..2368702adab26 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.js.snapshot/tree.json @@ -182,6 +182,42 @@ ] ] } + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "MyBucket53983D51A", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "MyAccessLogsBucketF7FE6635", + "Arn" + ] + }, + "/example5*" + ] + ] + } } ], "Version": "2012-10-17" @@ -334,6 +370,38 @@ "version": "0.0.0" } }, + "MyBucket5": { + "id": "MyBucket5", + "path": "aws-cdk-s3-access-logs/MyBucket5", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-s3-access-logs/MyBucket5/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::Bucket", + "aws:cdk:cloudformation:props": { + "loggingConfiguration": { + "destinationBucketName": { + "Ref": "MyAccessLogsBucketF7FE6635" + }, + "logFilePrefix": "example5", + "targetObjectKeyFormat": { + "partitionedPrefix": {} + } + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.Bucket", + "version": "0.0.0" + } + }, "BootstrapVersion": { "id": "BootstrapVersion", "path": "aws-cdk-s3-access-logs/BootstrapVersion", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.ts index 0322c70047960..6aca1b8ac4f66 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-s3/test/integ.bucket.server-access-logs.ts @@ -38,6 +38,13 @@ new s3.Bucket(stack, 'MyBucket4', { removalPolicy: cdk.RemovalPolicy.DESTROY, }); +new s3.Bucket(stack, 'MyBucket5', { + serverAccessLogsBucket: accessLogBucket, + serverAccessLogsPrefix: 'example5', + targetObjectKeyFormat: s3.TargetObjectKeyFormat.partitionedPrefix(), + removalPolicy: cdk.RemovalPolicy.DESTROY, +}); + new IntegTest(app, 'cdk-integ-s3-access-logs', { testCases: [stack], }); diff --git a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts index 142a579f15038..91dd452c71d4d 100644 --- a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts +++ b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts @@ -1357,6 +1357,7 @@ export enum PartitionDateSource { export abstract class TargetObjectKeyFormat { /** * Use partitioned prefix for log objects. + * If you do not specify the dateSource argument, the default is EventTime. * * The partitioned prefix format as follow: * [DestinationPrefix][SourceAccountId]/​[SourceRegion]/​[SourceBucket]/​[YYYY]/​[MM]/​[DD]/​[YYYY]-[MM]-[DD]-[hh]-[mm]-[ss]-[UniqueString]