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..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": "30.1.0", + "version": "36.0.0", "files": { - "f58a2b25314952a1a5a6b42c6b9092caf2710430af09ba4f5d807e60f2fd3542": { + "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": "f58a2b25314952a1a5a6b42c6b9092caf2710430af09ba4f5d807e60f2fd3542.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 532e9c171c422..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 @@ -48,6 +48,150 @@ ] ] } + }, + { + "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" + ] + }, + "/example2*" + ] + ] + } + }, + { + "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" + ] + }, + "/example3*" + ] + ] + } + }, + { + "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" + ] + }, + "/example4*" + ] + ] + } + }, + { + "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" @@ -66,6 +210,74 @@ }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" + }, + "MyBucket26E0C3623": { + "Type": "AWS::S3::Bucket", + "Properties": { + "LoggingConfiguration": { + "DestinationBucketName": { + "Ref": "MyAccessLogsBucketF7FE6635" + }, + "LogFilePrefix": "example2", + "TargetObjectKeyFormat": { + "SimplePrefix": {} + } + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "MyBucket3CC4F8735": { + "Type": "AWS::S3::Bucket", + "Properties": { + "LoggingConfiguration": { + "DestinationBucketName": { + "Ref": "MyAccessLogsBucketF7FE6635" + }, + "LogFilePrefix": "example3", + "TargetObjectKeyFormat": { + "PartitionedPrefix": { + "PartitionDateSource": "EventTime" + } + } + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "MyBucket43E0A113B": { + "Type": "AWS::S3::Bucket", + "Properties": { + "LoggingConfiguration": { + "DestinationBucketName": { + "Ref": "MyAccessLogsBucketF7FE6635" + }, + "LogFilePrefix": "example4", + "TargetObjectKeyFormat": { + "PartitionedPrefix": { + "PartitionDateSource": "DeliveryTime" + } + } + } + }, + "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/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..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 @@ -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}/680224db1786deb417c994d38f450f115dd410266ba1ffc919b54991e5a73e4a.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -51,6 +52,30 @@ "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/MyBucket5/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyBucket53983D51A" + } + ], "/aws-cdk-s3-access-logs/BootstrapVersion": [ { "type": "aws:cdk:logicalId", @@ -79,6 +104,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..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 @@ -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,150 @@ ] ] } + }, + { + "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" + ] + }, + "/example2*" + ] + ] + } + }, + { + "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" + ] + }, + "/example3*" + ] + ] + } + }, + { + "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" + ] + }, + "/example4*" + ] + ] + } + }, + { + "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" @@ -81,19 +225,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 +260,145 @@ } }, "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": "example2", + "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": "example3", + "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": "example4", + "targetObjectKeyFormat": { + "partitionedPrefix": { + "partitionDateSource": "DeliveryTime" + } + } + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.Bucket", + "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/aws-s3.Bucket", + "fqn": "aws-cdk-lib.aws_s3.Bucket", "version": "0.0.0" } }, @@ -130,7 +406,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 +414,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 +437,7 @@ "path": "cdk-integ-s3-access-logs/DefaultTest/Default", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.252" + "version": "10.3.0" } }, "DeployAssert": { @@ -172,7 +448,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 +456,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 +483,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..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 @@ -17,6 +17,34 @@ new s3.Bucket(stack, 'MyBucket', { removalPolicy: cdk.RemovalPolicy.DESTROY, }); +new s3.Bucket(stack, 'MyBucket2', { + serverAccessLogsBucket: accessLogBucket, + serverAccessLogsPrefix: 'example2', + targetObjectKeyFormat: s3.TargetObjectKeyFormat.simplePrefix(), + removalPolicy: cdk.RemovalPolicy.DESTROY, +}); + +new s3.Bucket(stack, 'MyBucket3', { + serverAccessLogsBucket: accessLogBucket, + serverAccessLogsPrefix: 'example3', + targetObjectKeyFormat: s3.TargetObjectKeyFormat.partitionedPrefix(s3.PartitionDateSource.EVENT_TIME), + removalPolicy: cdk.RemovalPolicy.DESTROY, +}); + +new s3.Bucket(stack, 'MyBucket4', { + serverAccessLogsBucket: accessLogBucket, + serverAccessLogsPrefix: 'example4', + targetObjectKeyFormat: s3.TargetObjectKeyFormat.partitionedPrefix(s3.PartitionDateSource.DELIVERY_TIME), + 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], -}); \ 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..247dadc0b1373 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 `TargetObjectKeyFormat.simplePrefix()`, but it is the same even if you do not specify `targetObjectKeyFormat` property. + targetObjectKeyFormat: s3.TargetObjectKeyFormat.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', + targetObjectKeyFormat: s3.TargetObjectKeyFormat.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..91dd452c71d4d 100644 --- a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts +++ b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts @@ -1336,6 +1336,68 @@ 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 for the log object. + */ +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] + */ + public static partitionedPrefix(dateSource?: PartitionDateSource): TargetObjectKeyFormat { + return new class extends TargetObjectKeyFormat { + 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(): TargetObjectKeyFormat { + return new class extends TargetObjectKeyFormat { + public _render(): CfnBucket.LoggingConfigurationProperty['targetObjectKeyFormat'] { + return { + simplePrefix: {}, + }; + } + }(); + } + + /** + * Render the log object 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 +1606,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 targetObjectKeyFormat?: TargetObjectKeyFormat; + /** * The inventory configuration of the bucket. * @@ -2213,6 +2282,7 @@ export class Bucket extends BucketBase { return { destinationBucketName: props.serverAccessLogsBucket?.bucketName, logFilePrefix: props.serverAccessLogsPrefix, + 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 14f076c419852..956f66e7d12e6 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, + targetObjectKeyFormat: s3.TargetObjectKeyFormat.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, + targetObjectKeyFormat: s3.TargetObjectKeyFormat.partitionedPrefix(s3.PartitionDateSource.EVENT_TIME), + }); + new s3.Bucket(stack, 'MyBucket2', { + serverAccessLogsBucket: accessLogBucket, + targetObjectKeyFormat: s3.TargetObjectKeyFormat.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', + }, + }, }, }); });