diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway-lambda/test/integ.customCloudfrontLoggingBucket.expected.json b/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway-lambda/test/integ.customCloudfrontLoggingBucket.expected.json index a37d75a11..0812a32fa 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway-lambda/test/integ.customCloudfrontLoggingBucket.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway-lambda/test/integ.customCloudfrontLoggingBucket.expected.json @@ -589,13 +589,13 @@ "cfapigwlambdaCloudFrontToApiGatewaySetHttpSecurityHeadersE20F2933": { "Type": "AWS::CloudFront::Function", "Properties": { - "Name": "SetHttpSecurityHeadersc8273ed23dc12ef2b23814ad425355213a41659e4f", - "AutoPublish": true, "FunctionCode": "function handler(event) { var response = event.response; var headers = response.headers; headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'}; headers['content-security-policy'] = { value: \"default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'\"}; headers['x-content-type-options'] = { value: 'nosniff'}; headers['x-frame-options'] = {value: 'DENY'}; headers['x-xss-protection'] = {value: '1; mode=block'}; return response; }", "FunctionConfig": { "Comment": "SetHttpSecurityHeadersc8273ed23dc12ef2b23814ad425355213a41659e4f", "Runtime": "cloudfront-js-1.0" - } + }, + "Name": "SetHttpSecurityHeadersc8273ed23dc12ef2b23814ad425355213a41659e4f", + "AutoPublish": true } }, "cfapigwlambdaCloudFrontToApiGatewayCloudfrontLoggingBucket2E8E3DC2": { @@ -611,6 +611,13 @@ } ] }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "ObjectWriter" + } + ] + }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, @@ -884,7 +891,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "15684a15d07860e99d2a8079150ad33dd2cb743677fcd7016dd07345e1b69538.zip" + "S3Key": "40aa87cdf43c4095cec18bc443965f22ab2f8c1ace47e482a0ba4e35d83b0cc9.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway-lambda/test/integ.no-arguments.expected.json b/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway-lambda/test/integ.no-arguments.expected.json index 9a02cb007..35f2917d1 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway-lambda/test/integ.no-arguments.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway-lambda/test/integ.no-arguments.expected.json @@ -589,13 +589,13 @@ "testcloudfrontapigatewaylambdaCloudFrontToApiGatewaySetHttpSecurityHeaders6945414A": { "Type": "AWS::CloudFront::Function", "Properties": { - "Name": "SetHttpSecurityHeadersc8118ca6b46a588ddfb2f1826effa6addb3adda75e", - "AutoPublish": true, "FunctionCode": "function handler(event) { var response = event.response; var headers = response.headers; headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'}; headers['content-security-policy'] = { value: \"default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'\"}; headers['x-content-type-options'] = { value: 'nosniff'}; headers['x-frame-options'] = {value: 'DENY'}; headers['x-xss-protection'] = {value: '1; mode=block'}; return response; }", "FunctionConfig": { "Comment": "SetHttpSecurityHeadersc8118ca6b46a588ddfb2f1826effa6addb3adda75e", "Runtime": "cloudfront-js-1.0" - } + }, + "Name": "SetHttpSecurityHeadersc8118ca6b46a588ddfb2f1826effa6addb3adda75e", + "AutoPublish": true } }, "testcloudfrontapigatewaylambdaCloudFrontToApiGatewayCloudfrontLoggingBucket7F467421": { @@ -611,6 +611,13 @@ } ] }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "ObjectWriter" + } + ] + }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, @@ -884,7 +891,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "15684a15d07860e99d2a8079150ad33dd2cb743677fcd7016dd07345e1b69538.zip" + "S3Key": "40aa87cdf43c4095cec18bc443965f22ab2f8c1ace47e482a0ba4e35d83b0cc9.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway-lambda/test/integ.override-behavior.expected.json b/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway-lambda/test/integ.override-behavior.expected.json index b636fe56f..789660449 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway-lambda/test/integ.override-behavior.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway-lambda/test/integ.override-behavior.expected.json @@ -550,13 +550,13 @@ "cfapilambdaoverrideCloudFrontToApiGatewaySetHttpSecurityHeaders67E61E6E": { "Type": "AWS::CloudFront::Function", "Properties": { - "Name": "SetHttpSecurityHeadersc82a9e79410026b75533b53f0a37eeb986a591fa95", - "AutoPublish": true, "FunctionCode": "function handler(event) { var response = event.response; var headers = response.headers; headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'}; headers['content-security-policy'] = { value: \"default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'\"}; headers['x-content-type-options'] = { value: 'nosniff'}; headers['x-frame-options'] = {value: 'DENY'}; headers['x-xss-protection'] = {value: '1; mode=block'}; return response; }", "FunctionConfig": { "Comment": "SetHttpSecurityHeadersc82a9e79410026b75533b53f0a37eeb986a591fa95", "Runtime": "cloudfront-js-1.0" - } + }, + "Name": "SetHttpSecurityHeadersc82a9e79410026b75533b53f0a37eeb986a591fa95", + "AutoPublish": true } }, "cfapilambdaoverrideCloudFrontToApiGatewayCloudfrontLoggingBucket3A71B9E0": { @@ -572,6 +572,13 @@ } ] }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "ObjectWriter" + } + ] + }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, @@ -923,7 +930,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "15684a15d07860e99d2a8079150ad33dd2cb743677fcd7016dd07345e1b69538.zip" + "S3Key": "40aa87cdf43c4095cec18bc443965f22ab2f8c1ace47e482a0ba4e35d83b0cc9.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway-lambda/test/test.cloudfront-apigateway-lambda.test.ts b/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway-lambda/test/test.cloudfront-apigateway-lambda.test.ts index 975fe8fb5..a44bffeee 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway-lambda/test/test.cloudfront-apigateway-lambda.test.ts +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway-lambda/test/test.cloudfront-apigateway-lambda.test.ts @@ -227,7 +227,7 @@ test('Cloudfront logging bucket with destroy removal policy and auto delete obje const template = Template.fromStack(stack); template.hasResourceProperties("AWS::S3::Bucket", { - AccessControl: "LogDeliveryWrite" + OwnershipControls: { Rules: [ { ObjectOwnership: "ObjectWriter" } ] }, }); template.hasResourceProperties("Custom::S3AutoDeleteObjects", { diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway/test/integ.customCloudfrontLoggingBucket.expected.json b/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway/test/integ.customCloudfrontLoggingBucket.expected.json index 8bdb9fdbc..e422b9d00 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway/test/integ.customCloudfrontLoggingBucket.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway/test/integ.customCloudfrontLoggingBucket.expected.json @@ -589,13 +589,13 @@ "cfapigwSetHttpSecurityHeaders07A0F0C0": { "Type": "AWS::CloudFront::Function", "Properties": { - "Name": "SetHttpSecurityHeadersc8fc067b45a5c199a519a90c3b5f02d380f1625f1d", - "AutoPublish": true, "FunctionCode": "function handler(event) { var response = event.response; var headers = response.headers; headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'}; headers['content-security-policy'] = { value: \"default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'\"}; headers['x-content-type-options'] = { value: 'nosniff'}; headers['x-frame-options'] = {value: 'DENY'}; headers['x-xss-protection'] = {value: '1; mode=block'}; return response; }", "FunctionConfig": { "Comment": "SetHttpSecurityHeadersc8fc067b45a5c199a519a90c3b5f02d380f1625f1d", "Runtime": "cloudfront-js-1.0" - } + }, + "Name": "SetHttpSecurityHeadersc8fc067b45a5c199a519a90c3b5f02d380f1625f1d", + "AutoPublish": true } }, "cfapigwCloudfrontLoggingBucket79FE4195": { @@ -611,6 +611,13 @@ } ] }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "ObjectWriter" + } + ] + }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, @@ -884,7 +891,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "15684a15d07860e99d2a8079150ad33dd2cb743677fcd7016dd07345e1b69538.zip" + "S3Key": "40aa87cdf43c4095cec18bc443965f22ab2f8c1ace47e482a0ba4e35d83b0cc9.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway/test/integ.no-arguments.expected.json b/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway/test/integ.no-arguments.expected.json index 77291c962..821ffb388 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway/test/integ.no-arguments.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway/test/integ.no-arguments.expected.json @@ -589,13 +589,13 @@ "testcloudfrontapigatewaySetHttpSecurityHeadersD8DBA642": { "Type": "AWS::CloudFront::Function", "Properties": { - "Name": "SetHttpSecurityHeadersc86815c5ef0b0f2cdd73c6957ce5bbd25e8f895b9b", - "AutoPublish": true, "FunctionCode": "function handler(event) { var response = event.response; var headers = response.headers; headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'}; headers['content-security-policy'] = { value: \"default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'\"}; headers['x-content-type-options'] = { value: 'nosniff'}; headers['x-frame-options'] = {value: 'DENY'}; headers['x-xss-protection'] = {value: '1; mode=block'}; return response; }", "FunctionConfig": { "Comment": "SetHttpSecurityHeadersc86815c5ef0b0f2cdd73c6957ce5bbd25e8f895b9b", "Runtime": "cloudfront-js-1.0" - } + }, + "Name": "SetHttpSecurityHeadersc86815c5ef0b0f2cdd73c6957ce5bbd25e8f895b9b", + "AutoPublish": true } }, "testcloudfrontapigatewayCloudfrontLoggingBucket9811F6E8": { @@ -611,6 +611,13 @@ } ] }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "ObjectWriter" + } + ] + }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, @@ -884,7 +891,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "15684a15d07860e99d2a8079150ad33dd2cb743677fcd7016dd07345e1b69538.zip" + "S3Key": "40aa87cdf43c4095cec18bc443965f22ab2f8c1ace47e482a0ba4e35d83b0cc9.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway/test/test.cloudfront-apigateway.test.ts b/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway/test/test.cloudfront-apigateway.test.ts index 99492e6f4..d7ad60d05 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway/test/test.cloudfront-apigateway.test.ts +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-apigateway/test/test.cloudfront-apigateway.test.ts @@ -193,7 +193,7 @@ test('Cloudfront logging bucket with destroy removal policy and auto delete obje const template = Template.fromStack(stack); template.hasResourceProperties("AWS::S3::Bucket", { - AccessControl: "LogDeliveryWrite" + OwnershipControls: { Rules: [ { ObjectOwnership: "ObjectWriter" } ] }, }); template.hasResourceProperties("Custom::S3AutoDeleteObjects", { diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/cloudfront-mediastore.test.ts b/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/cloudfront-mediastore.test.ts index 6e7d5586f..73363676c 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/cloudfront-mediastore.test.ts +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/cloudfront-mediastore.test.ts @@ -665,7 +665,7 @@ test('Cloudfront logging bucket with destroy removal policy and auto delete obje const template = Template.fromStack(stack); template.hasResourceProperties("AWS::S3::Bucket", { - AccessControl: "LogDeliveryWrite" + OwnershipControls: { Rules: [ { ObjectOwnership: "ObjectWriter" } ] }, }); template.hasResourceProperties("Custom::S3AutoDeleteObjects", { diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.customCloudFrontLoggingBucket.expected.json b/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.customCloudFrontLoggingBucket.expected.json index 44221344e..cd0f01a50 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.customCloudFrontLoggingBucket.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.customCloudFrontLoggingBucket.expected.json @@ -95,6 +95,13 @@ } ] }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "ObjectWriter" + } + ] + }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, @@ -269,13 +276,13 @@ "cloudfrontmediastoreSetHttpSecurityHeadersC55C3265": { "Type": "AWS::CloudFront::Function", "Properties": { - "Name": "SetHttpSecurityHeadersc80b17555ef95835e434ce55c4536b557a9baf1262", - "AutoPublish": true, "FunctionCode": "function handler(event) { var response = event.response; var headers = response.headers; headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'}; headers['content-security-policy'] = { value: \"default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'\"}; headers['x-content-type-options'] = { value: 'nosniff'}; headers['x-frame-options'] = {value: 'DENY'}; headers['x-xss-protection'] = {value: '1; mode=block'}; return response; }", "FunctionConfig": { "Comment": "SetHttpSecurityHeadersc80b17555ef95835e434ce55c4536b557a9baf1262", "Runtime": "cloudfront-js-1.0" - } + }, + "Name": "SetHttpSecurityHeadersc80b17555ef95835e434ce55c4536b557a9baf1262", + "AutoPublish": true } }, "cloudfrontmediastoreCloudFrontDistribution639346BB": { @@ -410,7 +417,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "15684a15d07860e99d2a8079150ad33dd2cb743677fcd7016dd07345e1b69538.zip" + "S3Key": "40aa87cdf43c4095cec18bc443965f22ab2f8c1ace47e482a0ba4e35d83b0cc9.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.default.expected.json b/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.default.expected.json index 9b73d4b49..232164d28 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.default.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.default.expected.json @@ -95,6 +95,13 @@ } ] }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "ObjectWriter" + } + ] + }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, @@ -269,13 +276,13 @@ "testcloudfrontmediastoreSetHttpSecurityHeaders9995A63D": { "Type": "AWS::CloudFront::Function", "Properties": { - "Name": "SetHttpSecurityHeadersc85e0befbf4ed85d473981453c3bd34f0a97efbe49", - "AutoPublish": true, "FunctionCode": "function handler(event) { var response = event.response; var headers = response.headers; headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'}; headers['content-security-policy'] = { value: \"default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'\"}; headers['x-content-type-options'] = { value: 'nosniff'}; headers['x-frame-options'] = {value: 'DENY'}; headers['x-xss-protection'] = {value: '1; mode=block'}; return response; }", "FunctionConfig": { "Comment": "SetHttpSecurityHeadersc85e0befbf4ed85d473981453c3bd34f0a97efbe49", "Runtime": "cloudfront-js-1.0" - } + }, + "Name": "SetHttpSecurityHeadersc85e0befbf4ed85d473981453c3bd34f0a97efbe49", + "AutoPublish": true } }, "testcloudfrontmediastoreCloudFrontDistributionED9265B1": { @@ -410,7 +417,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "15684a15d07860e99d2a8079150ad33dd2cb743677fcd7016dd07345e1b69538.zip" + "S3Key": "40aa87cdf43c4095cec18bc443965f22ab2f8c1ace47e482a0ba4e35d83b0cc9.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.existingContainer.expected.json b/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.existingContainer.expected.json index 6df3c639e..1d05dc108 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.existingContainer.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.existingContainer.expected.json @@ -20,6 +20,13 @@ } ] }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "ObjectWriter" + } + ] + }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, @@ -194,13 +201,13 @@ "testcloudfrontmediastoreSetHttpSecurityHeaders9995A63D": { "Type": "AWS::CloudFront::Function", "Properties": { - "Name": "SetHttpSecurityHeadersc8671d40ce388b672e8795a9218fe7e3f368379f42", - "AutoPublish": true, "FunctionCode": "function handler(event) { var response = event.response; var headers = response.headers; headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'}; headers['content-security-policy'] = { value: \"default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'\"}; headers['x-content-type-options'] = { value: 'nosniff'}; headers['x-frame-options'] = {value: 'DENY'}; headers['x-xss-protection'] = {value: '1; mode=block'}; return response; }", "FunctionConfig": { "Comment": "SetHttpSecurityHeadersc8671d40ce388b672e8795a9218fe7e3f368379f42", "Runtime": "cloudfront-js-1.0" - } + }, + "Name": "SetHttpSecurityHeadersc8671d40ce388b672e8795a9218fe7e3f368379f42", + "AutoPublish": true } }, "testcloudfrontmediastoreCloudFrontDistributionED9265B1": { @@ -327,7 +334,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "15684a15d07860e99d2a8079150ad33dd2cb743677fcd7016dd07345e1b69538.zip" + "S3Key": "40aa87cdf43c4095cec18bc443965f22ab2f8c1ace47e482a0ba4e35d83b0cc9.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.overrideProperties.expected.json b/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.overrideProperties.expected.json index bc79291e8..1e2c8a88f 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.overrideProperties.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.overrideProperties.expected.json @@ -59,6 +59,13 @@ } ] }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "ObjectWriter" + } + ] + }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, @@ -233,13 +240,13 @@ "testcloudfrontmediastoreSetHttpSecurityHeaders9995A63D": { "Type": "AWS::CloudFront::Function", "Properties": { - "Name": "SetHttpSecurityHeadersc8f338626119f90653fe964a54eb18cb4a8d6406ce", - "AutoPublish": true, "FunctionCode": "function handler(event) { var response = event.response; var headers = response.headers; headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'}; headers['content-security-policy'] = { value: \"default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'\"}; headers['x-content-type-options'] = { value: 'nosniff'}; headers['x-frame-options'] = {value: 'DENY'}; headers['x-xss-protection'] = {value: '1; mode=block'}; return response; }", "FunctionConfig": { "Comment": "SetHttpSecurityHeadersc8f338626119f90653fe964a54eb18cb4a8d6406ce", "Runtime": "cloudfront-js-1.0" - } + }, + "Name": "SetHttpSecurityHeadersc8f338626119f90653fe964a54eb18cb4a8d6406ce", + "AutoPublish": true } }, "testcloudfrontmediastoreCloudFrontDistributionED9265B1": { @@ -369,7 +376,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "15684a15d07860e99d2a8079150ad33dd2cb743677fcd7016dd07345e1b69538.zip" + "S3Key": "40aa87cdf43c4095cec18bc443965f22ab2f8c1ace47e482a0ba4e35d83b0cc9.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.withSecurityHeaderBehavior.expected.json b/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.withSecurityHeaderBehavior.expected.json index c56445571..5d05ca67e 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.withSecurityHeaderBehavior.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.withSecurityHeaderBehavior.expected.json @@ -95,6 +95,13 @@ } ] }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "ObjectWriter" + } + ] + }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.withoutHttpSecurityHeaders.expected.json b/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.withoutHttpSecurityHeaders.expected.json index 5c9253b9b..9c651e913 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.withoutHttpSecurityHeaders.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.withoutHttpSecurityHeaders.expected.json @@ -95,6 +95,13 @@ } ] }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "ObjectWriter" + } + ] + }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, @@ -387,7 +394,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "15684a15d07860e99d2a8079150ad33dd2cb743677fcd7016dd07345e1b69538.zip" + "S3Key": "40aa87cdf43c4095cec18bc443965f22ab2f8c1ace47e482a0ba4e35d83b0cc9.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/lib/index.ts index cbbfc3b54..9e720bb25 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/lib/index.ts +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/lib/index.ts @@ -106,6 +106,11 @@ export class CloudFrontToS3 extends Construct { */ constructor(scope: Construct, id: string, props: CloudFrontToS3Props) { super(scope, id); + + // All our tests are based upon this behavior being on, so we're setting + // context here rather than assuming the client will set it + this.node.setContext("@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy", true); + defaults.CheckProps(props); let bucket: s3.IBucket; diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.custom-originPath.expected.json b/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.custom-originPath.expected.json index 6de2e1d2e..47d50ea9e 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.custom-originPath.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.custom-originPath.expected.json @@ -4,7 +4,6 @@ "testcloudfronts3S3LoggingBucket90D239DD": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -78,6 +77,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testcloudfronts3S3BucketE0C5F76E", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testcloudfronts3S3LoggingBucket90D239DD", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" @@ -276,13 +311,13 @@ "testcloudfronts3SetHttpSecurityHeaders6C5A1E69": { "Type": "AWS::CloudFront::Function", "Properties": { - "Name": "SetHttpSecurityHeadersc824484dfea4176847245e871498ffd7e454223fe4", - "AutoPublish": true, "FunctionCode": "function handler(event) { var response = event.response; var headers = response.headers; headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'}; headers['content-security-policy'] = { value: \"default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'\"}; headers['x-content-type-options'] = { value: 'nosniff'}; headers['x-frame-options'] = {value: 'DENY'}; headers['x-xss-protection'] = {value: '1; mode=block'}; return response; }", "FunctionConfig": { "Comment": "SetHttpSecurityHeadersc824484dfea4176847245e871498ffd7e454223fe4", "Runtime": "cloudfront-js-1.0" - } + }, + "Name": "SetHttpSecurityHeadersc824484dfea4176847245e871498ffd7e454223fe4", + "AutoPublish": true } }, "testcloudfronts3CloudfrontLoggingBucket985C0FE8": { @@ -298,6 +333,13 @@ } ] }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "ObjectWriter" + } + ] + }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, @@ -539,7 +581,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "15684a15d07860e99d2a8079150ad33dd2cb743677fcd7016dd07345e1b69538.zip" + "S3Key": "40aa87cdf43c4095cec18bc443965f22ab2f8c1ace47e482a0ba4e35d83b0cc9.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.custom-security-headers.expected.json b/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.custom-security-headers.expected.json index b7ae8fd09..8443b2707 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.custom-security-headers.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.custom-security-headers.expected.json @@ -4,18 +4,6 @@ "MyFunction3BAA72D1": { "Type": "AWS::CloudFront::Function", "Properties": { - "Name": { - "Fn::Join": [ - "", - [ - { - "Ref": "AWS::Region" - }, - "customsecurityheadersMyFunctionFAC550FB" - ] - ] - }, - "AutoPublish": true, "FunctionCode": "function handler(event) { var response = event.response; var headers = response.headers; headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'}; headers['content-security-policy'] = { value: \"default-src 'none'; base-uri 'self'; img-src 'self'; script-src 'self'; style-src 'self' https:; object-src 'none'; frame-ancestors 'none'; font-src 'self' https:; form-action 'self'; manifest-src 'self'; connect-src 'self'\" }; headers['x-content-type-options'] = { value: 'nosniff'}; headers['x-frame-options'] = {value: 'DENY'}; headers['x-xss-protection'] = {value: '1; mode=block'}; headers['referrer-policy'] = { value: 'same-origin' }; return response; }", "FunctionConfig": { "Comment": { @@ -30,13 +18,24 @@ ] }, "Runtime": "cloudfront-js-1.0" - } + }, + "Name": { + "Fn::Join": [ + "", + [ + { + "Ref": "AWS::Region" + }, + "customsecurityheadersMyFunctionFAC550FB" + ] + ] + }, + "AutoPublish": true } }, "testcloudfronts3S3LoggingBucket90D239DD": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -110,6 +109,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testcloudfronts3S3BucketE0C5F76E", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testcloudfronts3S3LoggingBucket90D239DD", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" @@ -308,13 +343,13 @@ "testcloudfronts3SetHttpSecurityHeaders6C5A1E69": { "Type": "AWS::CloudFront::Function", "Properties": { - "Name": "SetHttpSecurityHeadersc8132e0ba07d4c8fdbdb431ae46eef456c0589cb21", - "AutoPublish": true, "FunctionCode": "function handler(event) { var response = event.response; var headers = response.headers; headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'}; headers['content-security-policy'] = { value: \"default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'\"}; headers['x-content-type-options'] = { value: 'nosniff'}; headers['x-frame-options'] = {value: 'DENY'}; headers['x-xss-protection'] = {value: '1; mode=block'}; return response; }", "FunctionConfig": { "Comment": "SetHttpSecurityHeadersc8132e0ba07d4c8fdbdb431ae46eef456c0589cb21", "Runtime": "cloudfront-js-1.0" - } + }, + "Name": "SetHttpSecurityHeadersc8132e0ba07d4c8fdbdb431ae46eef456c0589cb21", + "AutoPublish": true } }, "testcloudfronts3CloudfrontLoggingBucket985C0FE8": { @@ -330,6 +365,13 @@ } ] }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "ObjectWriter" + } + ] + }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, @@ -570,7 +612,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "15684a15d07860e99d2a8079150ad33dd2cb743677fcd7016dd07345e1b69538.zip" + "S3Key": "40aa87cdf43c4095cec18bc443965f22ab2f8c1ace47e482a0ba4e35d83b0cc9.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.customCloudFrontLoggingBucket.expected.json b/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.customCloudFrontLoggingBucket.expected.json index 6e2ca764c..059909150 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.customCloudFrontLoggingBucket.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.customCloudFrontLoggingBucket.expected.json @@ -4,7 +4,6 @@ "testcloudfronts3S3LoggingBucket90D239DD": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -78,6 +77,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testcloudfronts3S3BucketE0C5F76E", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testcloudfronts3S3LoggingBucket90D239DD", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" @@ -276,13 +311,13 @@ "testcloudfronts3SetHttpSecurityHeaders6C5A1E69": { "Type": "AWS::CloudFront::Function", "Properties": { - "Name": "SetHttpSecurityHeadersc88d4d30b2e66a3bd009aa7f11e35596ee70824ece", - "AutoPublish": true, "FunctionCode": "function handler(event) { var response = event.response; var headers = response.headers; headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'}; headers['content-security-policy'] = { value: \"default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'\"}; headers['x-content-type-options'] = { value: 'nosniff'}; headers['x-frame-options'] = {value: 'DENY'}; headers['x-xss-protection'] = {value: '1; mode=block'}; return response; }", "FunctionConfig": { "Comment": "SetHttpSecurityHeadersc88d4d30b2e66a3bd009aa7f11e35596ee70824ece", "Runtime": "cloudfront-js-1.0" - } + }, + "Name": "SetHttpSecurityHeadersc88d4d30b2e66a3bd009aa7f11e35596ee70824ece", + "AutoPublish": true } }, "testcloudfronts3CloudfrontLoggingBucket985C0FE8": { @@ -298,6 +333,13 @@ } ] }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "ObjectWriter" + } + ] + }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, @@ -538,7 +580,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "15684a15d07860e99d2a8079150ad33dd2cb743677fcd7016dd07345e1b69538.zip" + "S3Key": "40aa87cdf43c4095cec18bc443965f22ab2f8c1ace47e482a0ba4e35d83b0cc9.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.customLoggingBucket.expected.json b/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.customLoggingBucket.expected.json index f48956258..be6d27194 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.customLoggingBucket.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.customLoggingBucket.expected.json @@ -3,7 +3,6 @@ "testcloudfronts3S3LoggingBucket90D239DD": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -122,6 +121,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testcloudfronts3S3BucketE0C5F76E", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testcloudfronts3S3LoggingBucket90D239DD", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" @@ -339,13 +374,13 @@ "testcloudfronts3SetHttpSecurityHeaders6C5A1E69": { "Type": "AWS::CloudFront::Function", "Properties": { - "Name": "SetHttpSecurityHeadersc8adfb824ff76ff8867fe60ef9e02c0d312ebd9f83", - "AutoPublish": true, "FunctionCode": "function handler(event) { var response = event.response; var headers = response.headers; headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'}; headers['content-security-policy'] = { value: \"default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'\"}; headers['x-content-type-options'] = { value: 'nosniff'}; headers['x-frame-options'] = {value: 'DENY'}; headers['x-xss-protection'] = {value: '1; mode=block'}; return response; }", "FunctionConfig": { "Comment": "SetHttpSecurityHeadersc8adfb824ff76ff8867fe60ef9e02c0d312ebd9f83", "Runtime": "cloudfront-js-1.0" - } + }, + "Name": "SetHttpSecurityHeadersc8adfb824ff76ff8867fe60ef9e02c0d312ebd9f83", + "AutoPublish": true } }, "testcloudfronts3CloudfrontLoggingBucket985C0FE8": { @@ -361,6 +396,13 @@ } ] }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "ObjectWriter" + } + ] + }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, @@ -601,7 +643,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "15684a15d07860e99d2a8079150ad33dd2cb743677fcd7016dd07345e1b69538.zip" + "S3Key": "40aa87cdf43c4095cec18bc443965f22ab2f8c1ace47e482a0ba4e35d83b0cc9.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.existing-bucket.expected.json b/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.existing-bucket.expected.json index 7a7c730a9..51c7d8b77 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.existing-bucket.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.existing-bucket.expected.json @@ -204,7 +204,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "15684a15d07860e99d2a8079150ad33dd2cb743677fcd7016dd07345e1b69538.zip" + "S3Key": "40aa87cdf43c4095cec18bc443965f22ab2f8c1ace47e482a0ba4e35d83b0cc9.zip" }, "Timeout": 900, "MemorySize": 128, @@ -254,13 +254,13 @@ "testcloudfronts3SetHttpSecurityHeaders6C5A1E69": { "Type": "AWS::CloudFront::Function", "Properties": { - "Name": "SetHttpSecurityHeadersc87bceb93c12dbe589df4f4994a0258334a9b78e4a", - "AutoPublish": true, "FunctionCode": "function handler(event) { var response = event.response; var headers = response.headers; headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'}; headers['content-security-policy'] = { value: \"default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'\"}; headers['x-content-type-options'] = { value: 'nosniff'}; headers['x-frame-options'] = {value: 'DENY'}; headers['x-xss-protection'] = {value: '1; mode=block'}; return response; }", "FunctionConfig": { "Comment": "SetHttpSecurityHeadersc87bceb93c12dbe589df4f4994a0258334a9b78e4a", "Runtime": "cloudfront-js-1.0" - } + }, + "Name": "SetHttpSecurityHeadersc87bceb93c12dbe589df4f4994a0258334a9b78e4a", + "AutoPublish": true } }, "testcloudfronts3CloudfrontLoggingBucket985C0FE8": { @@ -276,6 +276,13 @@ } ] }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "ObjectWriter" + } + ] + }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.no-arguments.expected.json b/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.no-arguments.expected.json index 5bd334b60..ff20b45dc 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.no-arguments.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.no-arguments.expected.json @@ -198,13 +198,13 @@ "testcloudfronts3SetHttpSecurityHeaders6C5A1E69": { "Type": "AWS::CloudFront::Function", "Properties": { - "Name": "SetHttpSecurityHeadersc8075c5215eb89e52dc0db6c01788e90b8e754531c", - "AutoPublish": true, "FunctionCode": "function handler(event) { var response = event.response; var headers = response.headers; headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'}; headers['content-security-policy'] = { value: \"default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'\"}; headers['x-content-type-options'] = { value: 'nosniff'}; headers['x-frame-options'] = {value: 'DENY'}; headers['x-xss-protection'] = {value: '1; mode=block'}; return response; }", "FunctionConfig": { "Comment": "SetHttpSecurityHeadersc8075c5215eb89e52dc0db6c01788e90b8e754531c", "Runtime": "cloudfront-js-1.0" - } + }, + "Name": "SetHttpSecurityHeadersc8075c5215eb89e52dc0db6c01788e90b8e754531c", + "AutoPublish": true } }, "testcloudfronts3CloudfrontLoggingBucket985C0FE8": { @@ -220,6 +220,13 @@ } ] }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "ObjectWriter" + } + ] + }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, @@ -460,7 +467,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "15684a15d07860e99d2a8079150ad33dd2cb743677fcd7016dd07345e1b69538.zip" + "S3Key": "40aa87cdf43c4095cec18bc443965f22ab2f8c1ace47e482a0ba4e35d83b0cc9.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.no-security-headers.expected.json b/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.no-security-headers.expected.json index 9f46d2543..c232f3e04 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.no-security-headers.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/integ.no-security-headers.expected.json @@ -4,7 +4,6 @@ "testcloudfronts3nosecurityheadersS3LoggingBucketF644B35F": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -78,6 +77,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testcloudfronts3nosecurityheadersS3Bucket4D06173D", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testcloudfronts3nosecurityheadersS3LoggingBucketF644B35F", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" @@ -286,6 +321,13 @@ } ] }, + "OwnershipControls": { + "Rules": [ + { + "ObjectOwnership": "ObjectWriter" + } + ] + }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, @@ -515,7 +557,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "15684a15d07860e99d2a8079150ad33dd2cb743677fcd7016dd07345e1b69538.zip" + "S3Key": "40aa87cdf43c4095cec18bc443965f22ab2f8c1ace47e482a0ba4e35d83b0cc9.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/test.cloudfront-s3.test.ts b/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/test.cloudfront-s3.test.ts index 2a68ec16a..c4e1ee100 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/test.cloudfront-s3.test.ts +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-s3/test/test.cloudfront-s3.test.ts @@ -255,19 +255,21 @@ test('test cloudfront with custom domain names', () => { test('s3 bucket with bucket, loggingBucket, and auto delete objects', () => { const stack = new cdk.Stack(); + const testName = "test-name"; new CloudFrontToS3(stack, 'cloudfront-s3', { bucketProps: { removalPolicy: cdk.RemovalPolicy.DESTROY, }, loggingBucketProps: { removalPolicy: cdk.RemovalPolicy.DESTROY, - autoDeleteObjects: true + autoDeleteObjects: true, + bucketName: testName } }); const template = Template.fromStack(stack); template.hasResourceProperties("AWS::S3::Bucket", { - AccessControl: "LogDeliveryWrite" + BucketName: testName }); template.hasResourceProperties("Custom::S3AutoDeleteObjects", { @@ -289,16 +291,19 @@ test('s3 bucket with bucket, loggingBucket, and auto delete objects', () => { test('Cloudfront logging bucket with destroy removal policy and auto delete objects', () => { const stack = new cdk.Stack(); + const cloudfrontLogBucketName = 'cf-log-bucket'; new CloudFrontToS3(stack, 'cloudfront-s3', { cloudFrontLoggingBucketProps: { removalPolicy: cdk.RemovalPolicy.DESTROY, - autoDeleteObjects: true + autoDeleteObjects: true, + bucketName: cloudfrontLogBucketName } }); const template = Template.fromStack(stack); template.hasResourceProperties("AWS::S3::Bucket", { - AccessControl: "LogDeliveryWrite" + OwnershipControls: { Rules: [ { ObjectOwnership: "ObjectWriter" } ] }, + BucketName: cloudfrontLogBucketName, }); template.hasResourceProperties("Custom::S3AutoDeleteObjects", { diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-kinesisfirehose-s3/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-eventbridge-kinesisfirehose-s3/lib/index.ts index 07a0b0d2b..00e634d20 100644 --- a/source/patterns/@aws-solutions-constructs/aws-eventbridge-kinesisfirehose-s3/lib/index.ts +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-kinesisfirehose-s3/lib/index.ts @@ -103,6 +103,11 @@ export class EventbridgeToKinesisFirehoseToS3 extends Construct { */ constructor(scope: Construct, id: string, props: EventbridgeToKinesisFirehoseToS3Props) { super(scope, id); + + // All our tests are based upon this behavior being on, so we're setting + // context here rather than assuming the client will set it + this.node.setContext("@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy", true); + defaults.CheckProps(props); // Set up the Kinesis Firehose using KinesisFirehoseToS3 construct diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-kinesisfirehose-s3/test/eventbridge-kinesisfirehose-s3.test.ts b/source/patterns/@aws-solutions-constructs/aws-eventbridge-kinesisfirehose-s3/test/eventbridge-kinesisfirehose-s3.test.ts index e770f7125..f15b1394a 100644 --- a/source/patterns/@aws-solutions-constructs/aws-eventbridge-kinesisfirehose-s3/test/eventbridge-kinesisfirehose-s3.test.ts +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-kinesisfirehose-s3/test/eventbridge-kinesisfirehose-s3.test.ts @@ -232,9 +232,7 @@ test('s3 bucket with bucket, loggingBucket, and auto delete objects', () => { }); const template = Template.fromStack(stack); - template.hasResourceProperties("AWS::S3::Bucket", { - AccessControl: "LogDeliveryWrite" - }); + template.resourceCountIs("AWS::S3::Bucket", 2); template.hasResourceProperties("Custom::S3AutoDeleteObjects", { ServiceToken: { diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-kinesisfirehose-s3/test/integ.customLoggingBucket.expected.json b/source/patterns/@aws-solutions-constructs/aws-eventbridge-kinesisfirehose-s3/test/integ.customLoggingBucket.expected.json index 5aca88db1..b9f4c55de 100644 --- a/source/patterns/@aws-solutions-constructs/aws-eventbridge-kinesisfirehose-s3/test/integ.customLoggingBucket.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-kinesisfirehose-s3/test/integ.customLoggingBucket.expected.json @@ -3,7 +3,6 @@ "testkinesisfirehoses3KinesisFirehoseToS3S3LoggingBucketCF5B8A5C": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -78,6 +77,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testkinesisfirehoses3KinesisFirehoseToS3S3Bucket303877FF", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testkinesisfirehoses3KinesisFirehoseToS3S3LoggingBucketCF5B8A5C", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-eventbridge-kinesisfirehose-s3/test/integ.eventbridge-kinesisfirehose-s3-no-arguments.expected.json b/source/patterns/@aws-solutions-constructs/aws-eventbridge-kinesisfirehose-s3/test/integ.eventbridge-kinesisfirehose-s3-no-arguments.expected.json index ddcb7844c..c5bfb2b37 100644 --- a/source/patterns/@aws-solutions-constructs/aws-eventbridge-kinesisfirehose-s3/test/integ.eventbridge-kinesisfirehose-s3-no-arguments.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-eventbridge-kinesisfirehose-s3/test/integ.eventbridge-kinesisfirehose-s3-no-arguments.expected.json @@ -4,7 +4,6 @@ "testeventbridgekinesisfirehoses3KinesisFirehoseToS3S3LoggingBucket703E6C44": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -78,6 +77,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testeventbridgekinesisfirehoses3KinesisFirehoseToS3S3BucketF3A3F845", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testeventbridgekinesisfirehoses3KinesisFirehoseToS3S3LoggingBucket703E6C44", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-fargate-s3/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-fargate-s3/lib/index.ts index 78463e6de..37830ff0e 100644 --- a/source/patterns/@aws-solutions-constructs/aws-fargate-s3/lib/index.ts +++ b/source/patterns/@aws-solutions-constructs/aws-fargate-s3/lib/index.ts @@ -156,6 +156,11 @@ export class FargateToS3 extends Construct { constructor(scope: Construct, id: string, props: FargateToS3Props) { super(scope, id); + + // All our tests are based upon this behavior being on, so we're setting + // context here rather than assuming the client will set it + this.node.setContext("@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy", true); + defaults.CheckProps(props); defaults.CheckFargateProps(props); diff --git a/source/patterns/@aws-solutions-constructs/aws-fargate-s3/test/integ.new-resources.expected.json b/source/patterns/@aws-solutions-constructs/aws-fargate-s3/test/integ.new-resources.expected.json index 38f229063..decf2394b 100644 --- a/source/patterns/@aws-solutions-constructs/aws-fargate-s3/test/integ.new-resources.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-fargate-s3/test/integ.new-resources.expected.json @@ -4,7 +4,6 @@ "testconstructS3LoggingBucketD59856DF": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -78,6 +77,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testconstructS3Bucket81E8552A", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testconstructS3LoggingBucketD59856DF", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" @@ -887,7 +922,6 @@ "Ref": "Vpc8378EB38" }, "ResourceType": "VPC", - "TrafficType": "ALL", "DeliverLogsPermissionArn": { "Fn::GetAtt": [ "VpcFlowLogIAMRole6A475D41", @@ -903,7 +937,8 @@ "Key": "Name", "Value": "new-resources/Vpc" } - ] + ], + "TrafficType": "ALL" } }, "VpcS3A5408339": { @@ -1343,7 +1378,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-us-east-1" }, - "S3Key": "e57c1acaa363d7d2b81736776007a7091bc73dff4aeb8135627c4511a51e7dca.zip" + "S3Key": "40aa87cdf43c4095cec18bc443965f22ab2f8c1ace47e482a0ba4e35d83b0cc9.zip" }, "Timeout": 900, "MemorySize": 128, diff --git a/source/patterns/@aws-solutions-constructs/aws-iot-kinesisfirehose-s3/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-iot-kinesisfirehose-s3/lib/index.ts index 50b6490e8..97431270c 100644 --- a/source/patterns/@aws-solutions-constructs/aws-iot-kinesisfirehose-s3/lib/index.ts +++ b/source/patterns/@aws-solutions-constructs/aws-iot-kinesisfirehose-s3/lib/index.ts @@ -91,6 +91,11 @@ export class IotToKinesisFirehoseToS3 extends Construct { */ constructor(scope: Construct, id: string, props: IotToKinesisFirehoseToS3Props) { super(scope, id); + + // All our tests are based upon this behavior being on, so we're setting + // context here rather than assuming the client will set it + this.node.setContext("@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy", true); + defaults.CheckProps(props); const firehoseToS3 = new KinesisFirehoseToS3(this, 'KinesisFirehoseToS3', { diff --git a/source/patterns/@aws-solutions-constructs/aws-iot-kinesisfirehose-s3/test/integ.customLoggingBucket.expected.json b/source/patterns/@aws-solutions-constructs/aws-iot-kinesisfirehose-s3/test/integ.customLoggingBucket.expected.json index 640dee782..f141a4769 100644 --- a/source/patterns/@aws-solutions-constructs/aws-iot-kinesisfirehose-s3/test/integ.customLoggingBucket.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-iot-kinesisfirehose-s3/test/integ.customLoggingBucket.expected.json @@ -3,7 +3,6 @@ "testiotkinesisfirehoses3KinesisFirehoseToS3S3LoggingBucket03F0BA8E": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -78,6 +77,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testiotkinesisfirehoses3KinesisFirehoseToS3S3BucketAEE2D91B", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testiotkinesisfirehoses3KinesisFirehoseToS3S3LoggingBucket03F0BA8E", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-iot-kinesisfirehose-s3/test/integ.no-arguments.expected.json b/source/patterns/@aws-solutions-constructs/aws-iot-kinesisfirehose-s3/test/integ.no-arguments.expected.json index 42359c02d..b1b5c1364 100644 --- a/source/patterns/@aws-solutions-constructs/aws-iot-kinesisfirehose-s3/test/integ.no-arguments.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-iot-kinesisfirehose-s3/test/integ.no-arguments.expected.json @@ -4,7 +4,6 @@ "testiotfirehoses3KinesisFirehoseToS3S3LoggingBucketC786B050": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -78,6 +77,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testiotfirehoses3KinesisFirehoseToS3S3Bucket19C97D09", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testiotfirehoses3KinesisFirehoseToS3S3LoggingBucketC786B050", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-iot-kinesisfirehose-s3/test/test.iot-kinesisfirehose-s3.test.ts b/source/patterns/@aws-solutions-constructs/aws-iot-kinesisfirehose-s3/test/test.iot-kinesisfirehose-s3.test.ts index 0c3476afd..d9bb4f85a 100644 --- a/source/patterns/@aws-solutions-constructs/aws-iot-kinesisfirehose-s3/test/test.iot-kinesisfirehose-s3.test.ts +++ b/source/patterns/@aws-solutions-constructs/aws-iot-kinesisfirehose-s3/test/test.iot-kinesisfirehose-s3.test.ts @@ -182,9 +182,7 @@ test('s3 bucket with bucket, loggingBucket, and auto delete objects', () => { }); const template = Template.fromStack(stack); - template.hasResourceProperties("AWS::S3::Bucket", { - AccessControl: "LogDeliveryWrite" - }); + template.resourceCountIs("AWS::S3::Bucket", 2); template.hasResourceProperties("Custom::S3AutoDeleteObjects", { ServiceToken: { diff --git a/source/patterns/@aws-solutions-constructs/aws-iot-s3/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-iot-s3/lib/index.ts index 51e6e278b..5afb9a05c 100644 --- a/source/patterns/@aws-solutions-constructs/aws-iot-s3/lib/index.ts +++ b/source/patterns/@aws-solutions-constructs/aws-iot-s3/lib/index.ts @@ -77,6 +77,11 @@ export class IotToS3 extends Construct { */ constructor(scope: Construct, id: string, props: IotToS3Props) { super(scope, id); + + // All our tests are based upon this behavior being on, so we're setting + // context here rather than assuming the client will set it + this.node.setContext("@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy", true); + defaults.CheckProps(props); // Setup S3 Bucket diff --git a/source/patterns/@aws-solutions-constructs/aws-iot-s3/test/integ.iot-s3-new-encrypted-bucket.expected.json b/source/patterns/@aws-solutions-constructs/aws-iot-s3/test/integ.iot-s3-new-encrypted-bucket.expected.json index 2915c0cc5..95a67bf11 100644 --- a/source/patterns/@aws-solutions-constructs/aws-iot-s3/test/integ.iot-s3-new-encrypted-bucket.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-iot-s3/test/integ.iot-s3-new-encrypted-bucket.expected.json @@ -39,7 +39,6 @@ "testiots3integrationS3LoggingBucket606446CC": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -113,6 +112,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testiots3integrationS3Bucket9B8B180C", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testiots3integrationS3LoggingBucket606446CC", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3-and-kinesisanalytics/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3-and-kinesisanalytics/lib/index.ts index d90ede8e0..8798c43e8 100644 --- a/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3-and-kinesisanalytics/lib/index.ts +++ b/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3-and-kinesisanalytics/lib/index.ts @@ -93,6 +93,11 @@ export class KinesisFirehoseToAnalyticsAndS3 extends Construct { */ constructor(scope: Construct, id: string, props: KinesisFirehoseToAnalyticsAndS3Props) { super(scope, id); + + // All our tests are based upon this behavior being on, so we're setting + // context here rather than assuming the client will set it + this.node.setContext("@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy", true); + defaults.CheckProps(props); // Setup the kinesisfirehose-s3 pattern diff --git a/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3-and-kinesisanalytics/test/integ.customLoggingBucket.expected.json b/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3-and-kinesisanalytics/test/integ.customLoggingBucket.expected.json index 4ef30965a..c57d17329 100644 --- a/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3-and-kinesisanalytics/test/integ.customLoggingBucket.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3-and-kinesisanalytics/test/integ.customLoggingBucket.expected.json @@ -3,7 +3,6 @@ "testkinesisfirehoseanalyticss3KinesisFirehoseToS3S3LoggingBucketE14ECC0A": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -78,6 +77,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testkinesisfirehoseanalyticss3KinesisFirehoseToS3S3BucketA83D2E56", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testkinesisfirehoseanalyticss3KinesisFirehoseToS3S3LoggingBucketE14ECC0A", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3-and-kinesisanalytics/test/integ.no-arguments.expected.json b/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3-and-kinesisanalytics/test/integ.no-arguments.expected.json index b19498fb1..b7f3ed208 100644 --- a/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3-and-kinesisanalytics/test/integ.no-arguments.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3-and-kinesisanalytics/test/integ.no-arguments.expected.json @@ -3,7 +3,6 @@ "testfirehoses3andanalyticsstackKinesisFirehoseToS3S3LoggingBucket887A5000": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -77,6 +76,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testfirehoses3andanalyticsstackKinesisFirehoseToS3S3BucketAE659354", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testfirehoses3andanalyticsstackKinesisFirehoseToS3S3LoggingBucket887A5000", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3-and-kinesisanalytics/test/kinesisfirehose-s3-and-kinesisanalytics.test.ts b/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3-and-kinesisanalytics/test/kinesisfirehose-s3-and-kinesisanalytics.test.ts index 2ba2f4e18..c172d05b1 100644 --- a/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3-and-kinesisanalytics/test/kinesisfirehose-s3-and-kinesisanalytics.test.ts +++ b/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3-and-kinesisanalytics/test/kinesisfirehose-s3-and-kinesisanalytics.test.ts @@ -159,9 +159,7 @@ test('s3 bucket with bucket, loggingBucket, and auto delete objects', () => { }); const template = Template.fromStack(stack); - template.hasResourceProperties("AWS::S3::Bucket", { - AccessControl: "LogDeliveryWrite" - }); + template.resourceCountIs("AWS::S3::Bucket", 2); template.hasResourceProperties("Custom::S3AutoDeleteObjects", { ServiceToken: { diff --git a/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3/lib/index.ts index d3940b414..18319b5b7 100644 --- a/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3/lib/index.ts +++ b/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3/lib/index.ts @@ -89,6 +89,11 @@ export class KinesisFirehoseToS3 extends Construct { */ constructor(scope: Construct, id: string, props: KinesisFirehoseToS3Props) { super(scope, id); + + // All our tests are based upon this behavior being on, so we're setting + // context here rather than assuming the client will set it + this.node.setContext("@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy", true); + defaults.CheckProps(props); const firehoseId = 'KinesisFirehose'; diff --git a/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3/test/integ.customLoggingBucket.expected.json b/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3/test/integ.customLoggingBucket.expected.json index 333bc21d1..8863865ec 100644 --- a/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3/test/integ.customLoggingBucket.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3/test/integ.customLoggingBucket.expected.json @@ -3,7 +3,6 @@ "testkinesisfirehoses3S3LoggingBucketDD0F9F56": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -78,6 +77,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testkinesisfirehoses3S3BucketA8942735", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testkinesisfirehoses3S3LoggingBucketDD0F9F56", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3/test/integ.no-arguments.expected.json b/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3/test/integ.no-arguments.expected.json index 604ad54b8..f321ef9d2 100644 --- a/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3/test/integ.no-arguments.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3/test/integ.no-arguments.expected.json @@ -4,7 +4,6 @@ "testfirehoses3S3LoggingBucket31BFDC22": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -78,6 +77,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testfirehoses3S3Bucket93480488", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testfirehoses3S3LoggingBucket31BFDC22", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3/test/kinesisfirehose-s3.test.ts b/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3/test/kinesisfirehose-s3.test.ts index 42a0737a0..9c1cc7ea0 100644 --- a/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3/test/kinesisfirehose-s3.test.ts +++ b/source/patterns/@aws-solutions-constructs/aws-kinesisfirehose-s3/test/kinesisfirehose-s3.test.ts @@ -236,9 +236,7 @@ test('s3 bucket with bucket, loggingBucket, and auto delete objects', () => { }); const template = Template.fromStack(stack); - template.hasResourceProperties("AWS::S3::Bucket", { - AccessControl: "LogDeliveryWrite" - }); + template.resourceCountIs("AWS::S3::Bucket", 2); template.hasResourceProperties("Custom::S3AutoDeleteObjects", { ServiceToken: { diff --git a/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-gluejob/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-gluejob/lib/index.ts index daa211c06..8dc65de36 100644 --- a/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-gluejob/lib/index.ts +++ b/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-gluejob/lib/index.ts @@ -168,6 +168,11 @@ export class KinesisstreamsToGluejob extends Construct { */ constructor(scope: Construct, id: string, props: KinesisstreamsToGluejobProps) { super(scope, id); + + // All our tests are based upon this behavior being on, so we're setting + // context here rather than assuming the client will set it + this.node.setContext("@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy", true); + defaults.CheckProps(props); // custom props check diff --git a/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-gluejob/test/integ.code-asset-job.expected.json b/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-gluejob/test/integ.code-asset-job.expected.json index 7b90bddd5..705c0fe01 100644 --- a/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-gluejob/test/integ.code-asset-job.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-gluejob/test/integ.code-asset-job.expected.json @@ -210,7 +210,6 @@ "testkinesisstreamslambdaS3LoggingBucket48F70267": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -284,6 +283,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testkinesisstreamslambdaS3Bucket54759F5C", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testkinesisstreamslambdaS3LoggingBucket48F70267", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-gluejob/test/integ.no-arguments.expected.json b/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-gluejob/test/integ.no-arguments.expected.json index 5da9ccc78..f18b6a9c1 100644 --- a/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-gluejob/test/integ.no-arguments.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-gluejob/test/integ.no-arguments.expected.json @@ -203,7 +203,6 @@ "testkinesisstreamslambdaS3LoggingBucket48F70267": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -277,6 +276,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testkinesisstreamslambdaS3Bucket54759F5C", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testkinesisstreamslambdaS3LoggingBucket48F70267", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-gluejob/test/kinesisstream-gluejob.test.ts b/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-gluejob/test/kinesisstream-gluejob.test.ts index 2a26f2370..e45c954bf 100644 --- a/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-gluejob/test/kinesisstream-gluejob.test.ts +++ b/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-gluejob/test/kinesisstream-gluejob.test.ts @@ -716,10 +716,6 @@ test('When Asset for local file is defined', () => { const id = 'test-kinesisstreams-lambda'; const construct = new KinesisstreamsToGluejob(stack, id, props); - expect(construct.outputBucket).toBeDefined(); - expect(construct.outputBucket![0]).toBeDefined(); - expect(construct.outputBucket![1]).toBeDefined(); - // Check for properties expect(construct.database).toBeDefined(); expect(construct.glueJob).toBeDefined(); @@ -727,8 +723,14 @@ test('When Asset for local file is defined', () => { expect(construct.kinesisStream).toBeDefined(); expect(construct.glueJobRole).toBeDefined(); expect(construct.cloudwatchAlarms).toBeDefined(); + expect(construct.outputBucket).toBeDefined(); + expect(construct.outputBucket![0]).toBeDefined(); + expect(construct.outputBucket![1]).toBeDefined(); + // Each output bucket should have a logging bucket const template = Template.fromStack(stack); + template.resourceCountIs("AWS::S3::Bucket", 2); + template.hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ diff --git a/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-kinesisfirehose-s3/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-kinesisfirehose-s3/lib/index.ts index 8707b1fac..d71a2bc79 100644 --- a/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-kinesisfirehose-s3/lib/index.ts +++ b/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-kinesisfirehose-s3/lib/index.ts @@ -112,6 +112,11 @@ export class KinesisStreamsToKinesisFirehoseToS3 extends Construct { */ constructor(scope: Construct, id: string, props: KinesisStreamsToKinesisFirehoseToS3Props) { super(scope, id); + + // All our tests are based upon this behavior being on, so we're setting + // context here rather than assuming the client will set it + this.node.setContext("@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy", true); + defaults.CheckProps(props); // Setup the Kinesis Stream diff --git a/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-kinesisfirehose-s3/test/integ.customLoggingBucket.expected.json b/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-kinesisfirehose-s3/test/integ.customLoggingBucket.expected.json index a902352c9..2fbc46ba6 100644 --- a/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-kinesisfirehose-s3/test/integ.customLoggingBucket.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-kinesisfirehose-s3/test/integ.customLoggingBucket.expected.json @@ -17,7 +17,6 @@ "testkinesisfirehoses3KinesisFirehoseToS3S3LoggingBucketCF5B8A5C": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -92,6 +91,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testkinesisfirehoses3KinesisFirehoseToS3S3Bucket303877FF", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testkinesisfirehoses3KinesisFirehoseToS3S3LoggingBucketCF5B8A5C", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-kinesisfirehose-s3/test/integ.no-arguments.expected.json b/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-kinesisfirehose-s3/test/integ.no-arguments.expected.json index aadbad27e..8b46f7bdb 100644 --- a/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-kinesisfirehose-s3/test/integ.no-arguments.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-kinesisfirehose-s3/test/integ.no-arguments.expected.json @@ -18,7 +18,6 @@ "teststreamfirehoses3KinesisFirehoseToS3S3LoggingBucketFB87BEBC": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -92,6 +91,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "teststreamfirehoses3KinesisFirehoseToS3S3Bucket315B67A3", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "teststreamfirehoses3KinesisFirehoseToS3S3LoggingBucketFB87BEBC", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-kinesisfirehose-s3/test/kinesisstreams-kinesisfirehose-s3.test.ts b/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-kinesisfirehose-s3/test/kinesisstreams-kinesisfirehose-s3.test.ts index b7a53748d..5659bf6e1 100644 --- a/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-kinesisfirehose-s3/test/kinesisstreams-kinesisfirehose-s3.test.ts +++ b/source/patterns/@aws-solutions-constructs/aws-kinesisstreams-kinesisfirehose-s3/test/kinesisstreams-kinesisfirehose-s3.test.ts @@ -204,9 +204,7 @@ test('s3 bucket with bucket, loggingBucket, and auto delete objects', () => { }); const template = Template.fromStack(stack); - template.hasResourceProperties("AWS::S3::Bucket", { - AccessControl: "LogDeliveryWrite" - }); + template.resourceCountIs("AWS::S3::Bucket", 2); template.hasResourceProperties("Custom::S3AutoDeleteObjects", { ServiceToken: { diff --git a/source/patterns/@aws-solutions-constructs/aws-lambda-s3/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-lambda-s3/lib/index.ts index 4b8cec0ac..92c805d0d 100644 --- a/source/patterns/@aws-solutions-constructs/aws-lambda-s3/lib/index.ts +++ b/source/patterns/@aws-solutions-constructs/aws-lambda-s3/lib/index.ts @@ -109,6 +109,11 @@ export class LambdaToS3 extends Construct { */ constructor(scope: Construct, id: string, props: LambdaToS3Props) { super(scope, id); + + // All our tests are based upon this behavior being on, so we're setting + // context here rather than assuming the client will set it + this.node.setContext("@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy", true); + defaults.CheckProps(props); if (props.bucketPermissions) { diff --git a/source/patterns/@aws-solutions-constructs/aws-lambda-s3/test/integ.customLoggingBucket.expected.json b/source/patterns/@aws-solutions-constructs/aws-lambda-s3/test/integ.customLoggingBucket.expected.json index 2ed044729..37e83bd90 100644 --- a/source/patterns/@aws-solutions-constructs/aws-lambda-s3/test/integ.customLoggingBucket.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-lambda-s3/test/integ.customLoggingBucket.expected.json @@ -181,7 +181,6 @@ "testlambdas3S3LoggingBucketD42FC73D": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -256,6 +255,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testlambdas3S3Bucket179A52E6", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testlambdas3S3LoggingBucketD42FC73D", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-lambda-s3/test/integ.deployFunctionWithVpc.expected.json b/source/patterns/@aws-solutions-constructs/aws-lambda-s3/test/integ.deployFunctionWithVpc.expected.json index c52d3448b..058678598 100644 --- a/source/patterns/@aws-solutions-constructs/aws-lambda-s3/test/integ.deployFunctionWithVpc.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-lambda-s3/test/integ.deployFunctionWithVpc.expected.json @@ -598,7 +598,6 @@ "Ref": "Vpc8378EB38" }, "ResourceType": "VPC", - "TrafficType": "ALL", "DeliverLogsPermissionArn": { "Fn::GetAtt": [ "VpcFlowLogIAMRole6A475D41", @@ -614,7 +613,8 @@ "Key": "Name", "Value": "deployFunctionWithVpc/Vpc" } - ] + ], + "TrafficType": "ALL" } }, "VpcS3A5408339": { diff --git a/source/patterns/@aws-solutions-constructs/aws-lambda-s3/test/integ.existingFunction.expected.json b/source/patterns/@aws-solutions-constructs/aws-lambda-s3/test/integ.existingFunction.expected.json index 3285914cf..36099ea36 100644 --- a/source/patterns/@aws-solutions-constructs/aws-lambda-s3/test/integ.existingFunction.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-lambda-s3/test/integ.existingFunction.expected.json @@ -182,7 +182,6 @@ "testlambdas3S3LoggingBucketD42FC73D": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -256,6 +255,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "testlambdas3S3Bucket179A52E6", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "testlambdas3S3LoggingBucketD42FC73D", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-lambda-s3/test/lambda-s3.test.ts b/source/patterns/@aws-solutions-constructs/aws-lambda-s3/test/lambda-s3.test.ts index 2b1522287..de17381ff 100644 --- a/source/patterns/@aws-solutions-constructs/aws-lambda-s3/test/lambda-s3.test.ts +++ b/source/patterns/@aws-solutions-constructs/aws-lambda-s3/test/lambda-s3.test.ts @@ -393,9 +393,7 @@ test('s3 bucket with bucket, loggingBucket, and auto delete objects', () => { }); const template = Template.fromStack(stack); - template.hasResourceProperties("AWS::S3::Bucket", { - AccessControl: "LogDeliveryWrite" - }); + template.resourceCountIs("AWS::S3::Bucket", 2); template.hasResourceProperties("Custom::S3AutoDeleteObjects", { ServiceToken: { diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-lambda/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-s3-lambda/lib/index.ts index d9e25271b..ba1d1a59e 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-lambda/lib/index.ts +++ b/source/patterns/@aws-solutions-constructs/aws-s3-lambda/lib/index.ts @@ -84,6 +84,11 @@ export class S3ToLambda extends Construct { */ constructor(scope: Construct, id: string, props: S3ToLambdaProps) { super(scope, id); + + // All our tests are based upon this behavior being on, so we're setting + // context here rather than assuming the client will set it + this.node.setContext("@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy", true); + defaults.CheckProps(props); let bucket: s3.Bucket; diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-lambda/test/integ.no-arguments.expected.json b/source/patterns/@aws-solutions-constructs/aws-s3-lambda/test/integ.no-arguments.expected.json index 10c85e0e7..c60da90fa 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-lambda/test/integ.no-arguments.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-s3-lambda/test/integ.no-arguments.expected.json @@ -138,6 +138,124 @@ } } }, + "tests3lambdaS3LoggingBucket0C3BBFDC": { + "Type": "AWS::S3::Bucket", + "Properties": { + "BucketEncryption": { + "ServerSideEncryptionConfiguration": [ + { + "ServerSideEncryptionByDefault": { + "SSEAlgorithm": "AES256" + } + } + ] + }, + "PublicAccessBlockConfiguration": { + "BlockPublicAcls": true, + "BlockPublicPolicy": true, + "IgnorePublicAcls": true, + "RestrictPublicBuckets": true + }, + "VersioningConfiguration": { + "Status": "Enabled" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete", + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W35", + "reason": "This S3 bucket is used as the access logging bucket for another bucket" + } + ] + } + } + }, + "tests3lambdaS3LoggingBucketPolicyC349F74C": { + "Type": "AWS::S3::BucketPolicy", + "Properties": { + "Bucket": { + "Ref": "tests3lambdaS3LoggingBucket0C3BBFDC" + }, + "PolicyDocument": { + "Statement": [ + { + "Action": "s3:*", + "Condition": { + "Bool": { + "aws:SecureTransport": "false" + } + }, + "Effect": "Deny", + "Principal": { + "AWS": "*" + }, + "Resource": [ + { + "Fn::GetAtt": [ + "tests3lambdaS3LoggingBucket0C3BBFDC", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "tests3lambdaS3LoggingBucket0C3BBFDC", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "tests3lambdaS3BucketBE7C1B8E", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "tests3lambdaS3LoggingBucket0C3BBFDC", + "Arn" + ] + }, + "/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + } + } + }, "tests3lambdaS3BucketBE7C1B8E": { "Type": "AWS::S3::Bucket", "Properties": { @@ -163,6 +281,11 @@ } ] }, + "LoggingConfiguration": { + "DestinationBucketName": { + "Ref": "tests3lambdaS3LoggingBucket0C3BBFDC" + } + }, "PublicAccessBlockConfiguration": { "BlockPublicAcls": true, "BlockPublicPolicy": true, diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-lambda/test/integ.no-arguments.ts b/source/patterns/@aws-solutions-constructs/aws-s3-lambda/test/integ.no-arguments.ts index 85b7b0ce0..f63575983 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-lambda/test/integ.no-arguments.ts +++ b/source/patterns/@aws-solutions-constructs/aws-s3-lambda/test/integ.no-arguments.ts @@ -33,7 +33,9 @@ const props: S3ToLambdaProps = { bucketProps: { removalPolicy: RemovalPolicy.DESTROY, }, - logS3AccessLogs: false + loggingBucketProps: { + removalPolicy: RemovalPolicy.DESTROY, + }, }; const construct = new S3ToLambda(stack, 'test-s3-lambda', props); diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-lambda/test/s3-lambda.test.ts b/source/patterns/@aws-solutions-constructs/aws-s3-lambda/test/s3-lambda.test.ts index ba766158b..6a1a3ea8d 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-lambda/test/s3-lambda.test.ts +++ b/source/patterns/@aws-solutions-constructs/aws-s3-lambda/test/s3-lambda.test.ts @@ -87,9 +87,7 @@ test('s3 bucket with bucket, loggingBucket, and auto delete objects', () => { }); const template = Template.fromStack(stack); - template.hasResourceProperties("AWS::S3::Bucket", { - AccessControl: "LogDeliveryWrite" - }); + template.resourceCountIs("AWS::S3::Bucket", 2); template.hasResourceProperties("Custom::S3AutoDeleteObjects", { ServiceToken: { diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-sns/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-s3-sns/lib/index.ts index 807a3fc14..207622f86 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-sns/lib/index.ts +++ b/source/patterns/@aws-solutions-constructs/aws-s3-sns/lib/index.ts @@ -124,6 +124,11 @@ export class S3ToSns extends Construct { */ constructor(scope: Construct, id: string, props: S3ToSnsProps) { super(scope, id); + + // All our tests are based upon this behavior being on, so we're setting + // context here rather than assuming the client will set it + this.node.setContext("@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy", true); + defaults.CheckProps(props); // If the enableEncryptionWithCustomerManagedKey is undefined, default it to true diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.customLoggingBucket.expected.json b/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.customLoggingBucket.expected.json index 739b14151..a47e32a2a 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.customLoggingBucket.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.customLoggingBucket.expected.json @@ -3,7 +3,6 @@ "tests3snsS3LoggingBucket94DE93BC": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -77,6 +76,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "tests3snsS3Bucket4CA10A65", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "tests3snsS3LoggingBucket94DE93BC", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.existingSnsTopic.expected.json b/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.existingSnsTopic.expected.json index 89663b3fd..2182fa528 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.existingSnsTopic.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.existingSnsTopic.expected.json @@ -166,7 +166,6 @@ "tests3snsS3LoggingBucket94DE93BC": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -240,6 +239,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "tests3snsS3Bucket4CA10A65", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "tests3snsS3LoggingBucket94DE93BC", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.existingUnencryptedSnsTopic.expected.json b/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.existingUnencryptedSnsTopic.expected.json index 51aed0c35..d9190d342 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.existingUnencryptedSnsTopic.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.existingUnencryptedSnsTopic.expected.json @@ -52,7 +52,6 @@ "tests3snsS3LoggingBucket94DE93BC": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -126,6 +125,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "tests3snsS3Bucket4CA10A65", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "tests3snsS3LoggingBucket94DE93BC", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.newTopicFromProps.expected.json b/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.newTopicFromProps.expected.json index 26c04e4f0..fe7840adc 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.newTopicFromProps.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.newTopicFromProps.expected.json @@ -3,7 +3,6 @@ "tests3snsS3LoggingBucket94DE93BC": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -77,6 +76,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "tests3snsS3Bucket4CA10A65", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "tests3snsS3LoggingBucket94DE93BC", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.noArguments.expected.json b/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.noArguments.expected.json index 739b14151..a47e32a2a 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.noArguments.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.noArguments.expected.json @@ -3,7 +3,6 @@ "tests3snsS3LoggingBucket94DE93BC": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -77,6 +76,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "tests3snsS3Bucket4CA10A65", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "tests3snsS3LoggingBucket94DE93BC", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.s3EventTypesAndFilters.expected.json b/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.s3EventTypesAndFilters.expected.json index 981a7972c..1608bdc30 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.s3EventTypesAndFilters.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.s3EventTypesAndFilters.expected.json @@ -3,7 +3,6 @@ "tests3snsS3LoggingBucket94DE93BC": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -77,6 +76,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "tests3snsS3Bucket4CA10A65", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "tests3snsS3LoggingBucket94DE93BC", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.snsTopicWithAwsManagedKey.expected.json b/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.snsTopicWithAwsManagedKey.expected.json index 6bd113e9a..f7f6e850d 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.snsTopicWithAwsManagedKey.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/integ.snsTopicWithAwsManagedKey.expected.json @@ -3,7 +3,6 @@ "tests3snsS3LoggingBucket94DE93BC": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -77,6 +76,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "tests3snsS3Bucket4CA10A65", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "tests3snsS3LoggingBucket94DE93BC", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/test.s3-sns.test.ts b/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/test.s3-sns.test.ts index 9b821fc1f..7a45685ad 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/test.s3-sns.test.ts +++ b/source/patterns/@aws-solutions-constructs/aws-s3-sns/test/test.s3-sns.test.ts @@ -48,6 +48,7 @@ test('construct creates default event notification', () => { ] } }); + template.resourceCountIs("AWS::S3::Bucket", 2); }); test('construct uses existingBucketObj property', () => { diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-sqs/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-s3-sqs/lib/index.ts index e64fe714b..cd41a50e0 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-sqs/lib/index.ts +++ b/source/patterns/@aws-solutions-constructs/aws-s3-sqs/lib/index.ts @@ -134,6 +134,11 @@ export class S3ToSqs extends Construct { */ constructor(scope: Construct, id: string, props: S3ToSqsProps) { super(scope, id); + + // All our tests are based upon this behavior being on, so we're setting + // context here rather than assuming the client will set it + this.node.setContext("@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy", true); + defaults.CheckProps(props); let bucket: s3.Bucket; diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-sqs/test/integ.customLoggingBucket.expected.json b/source/patterns/@aws-solutions-constructs/aws-s3-sqs/test/integ.customLoggingBucket.expected.json index d6704e7c3..2406f51ef 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-sqs/test/integ.customLoggingBucket.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-s3-sqs/test/integ.customLoggingBucket.expected.json @@ -3,7 +3,6 @@ "tests3sqsS3LoggingBucket0B0BC86A": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -78,6 +77,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "tests3sqsS3BucketFF76CDA6", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "tests3sqsS3LoggingBucket0B0BC86A", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-sqs/test/integ.noArguments.expected.json b/source/patterns/@aws-solutions-constructs/aws-s3-sqs/test/integ.noArguments.expected.json index f7a74ef0b..4df7ea0f0 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-sqs/test/integ.noArguments.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-s3-sqs/test/integ.noArguments.expected.json @@ -3,7 +3,6 @@ "tests3sqsS3LoggingBucket0B0BC86A": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -77,6 +76,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "tests3sqsS3BucketFF76CDA6", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "tests3sqsS3LoggingBucket0B0BC86A", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-sqs/test/test.s3-sqs.test.ts b/source/patterns/@aws-solutions-constructs/aws-s3-sqs/test/test.s3-sqs.test.ts index 5800e30d8..34521e7ce 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-sqs/test/test.s3-sqs.test.ts +++ b/source/patterns/@aws-solutions-constructs/aws-s3-sqs/test/test.s3-sqs.test.ts @@ -257,9 +257,7 @@ test('s3 bucket with bucket, loggingBucket, and auto delete objects', () => { }); const template = Template.fromStack(stack); - template.hasResourceProperties("AWS::S3::Bucket", { - AccessControl: "LogDeliveryWrite" - }); + template.resourceCountIs("AWS::S3::Bucket", 2); template.hasResourceProperties("Custom::S3AutoDeleteObjects", { ServiceToken: { diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-stepfunctions/lib/index.ts b/source/patterns/@aws-solutions-constructs/aws-s3-stepfunctions/lib/index.ts index 098f00fce..0ef8ec2fe 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-stepfunctions/lib/index.ts +++ b/source/patterns/@aws-solutions-constructs/aws-s3-stepfunctions/lib/index.ts @@ -101,6 +101,11 @@ export class S3ToStepfunctions extends Construct { */ constructor(scope: Construct, id: string, props: S3ToStepfunctionsProps) { super(scope, id); + + // All our tests are based upon this behavior being on, so we're setting + // context here rather than assuming the client will set it + this.node.setContext("@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy", true); + defaults.CheckProps(props); let bucket: s3.IBucket; diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-stepfunctions/test/integ.customLoggingBucket.expected.json b/source/patterns/@aws-solutions-constructs/aws-s3-stepfunctions/test/integ.customLoggingBucket.expected.json index 568575791..11241541f 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-stepfunctions/test/integ.customLoggingBucket.expected.json +++ b/source/patterns/@aws-solutions-constructs/aws-s3-stepfunctions/test/integ.customLoggingBucket.expected.json @@ -3,7 +3,6 @@ "tests3stepfunctionsS3LoggingBucketF7586A92": { "Type": "AWS::S3::Bucket", "Properties": { - "AccessControl": "LogDeliveryWrite", "BucketEncryption": { "ServerSideEncryptionConfiguration": [ { @@ -78,6 +77,42 @@ ] } ] + }, + { + "Action": "s3:PutObject", + "Condition": { + "ArnLike": { + "aws:SourceArn": { + "Fn::GetAtt": [ + "tests3stepfunctionsS3Bucket2B08AD28", + "Arn" + ] + } + }, + "StringEquals": { + "aws:SourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "Effect": "Allow", + "Principal": { + "Service": "logging.s3.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "tests3stepfunctionsS3LoggingBucketF7586A92", + "Arn" + ] + }, + "/*" + ] + ] + } } ], "Version": "2012-10-17" diff --git a/source/patterns/@aws-solutions-constructs/aws-s3-stepfunctions/test/s3-stepfunctions.test.ts b/source/patterns/@aws-solutions-constructs/aws-s3-stepfunctions/test/s3-stepfunctions.test.ts index e773e4cab..c4cd1a914 100644 --- a/source/patterns/@aws-solutions-constructs/aws-s3-stepfunctions/test/s3-stepfunctions.test.ts +++ b/source/patterns/@aws-solutions-constructs/aws-s3-stepfunctions/test/s3-stepfunctions.test.ts @@ -155,6 +155,7 @@ test('s3 bucket with bucket, loggingBucket, and auto delete objects', () => { const template = Template.fromStack(stack); template.hasResourceProperties("Custom::S3BucketNotifications", {}); + template.resourceCountIs("AWS::S3::Bucket", 2); template.hasResourceProperties("Custom::S3AutoDeleteObjects", { ServiceToken: { diff --git a/source/patterns/@aws-solutions-constructs/core/lib/cloudfront-distribution-helper.ts b/source/patterns/@aws-solutions-constructs/core/lib/cloudfront-distribution-helper.ts index ddf73c3af..d0e51e6df 100644 --- a/source/patterns/@aws-solutions-constructs/core/lib/cloudfront-distribution-helper.ts +++ b/source/patterns/@aws-solutions-constructs/core/lib/cloudfront-distribution-helper.ts @@ -26,7 +26,7 @@ import { DefaultCloudFrontWebDistributionForApiGatewayProps, DefaultCloudFrontDisributionForMediaStoreProps } from './cloudfront-distribution-defaults'; -import { overrideProps, addCfnSuppressRules, consolidateProps } from './utils'; +import { addCfnSuppressRules, consolidateProps } from './utils'; import { createLoggingBucket } from './s3-bucket-helper'; import { DefaultS3Props } from './s3-bucket-defaults'; // Note: To ensure CDKv2 compatibility, keep the import statement for Construct separate @@ -245,12 +245,21 @@ function getLoggingBucket( throw Error('Either cloudFrontDistributionProps.logBucket or cloudFrontLoggingBucketProps can be set.'); } - return isLoggingDisabled - ? undefined - : userSuppliedLogBucket ?? createLoggingBucket( + let bucketResult: s3.Bucket | undefined; + if (isLoggingDisabled) { + bucketResult = undefined; + } else if (userSuppliedLogBucket) { + bucketResult = userSuppliedLogBucket; + } else { + bucketResult = createLoggingBucket( scope, 'CloudfrontLoggingBucket', - cloudFrontLoggingBucketProps ? overrideProps(DefaultS3Props(), cloudFrontLoggingBucketProps) : DefaultS3Props()); + consolidateProps(DefaultS3Props(), cloudFrontLoggingBucketProps, { objectOwnership: s3.ObjectOwnership.OBJECT_WRITER })); + + const loggingBucketResource = bucketResult.node.findChild('Resource') as s3.CfnBucket; + loggingBucketResource.addPropertyOverride('AccessControl', 'LogDeliveryWrite'); + } + return bucketResult; } function getCloudfrontFunction(httpSecurityHeaders: boolean, scope: Construct) { diff --git a/source/tools/cdk-integ-tools/bin/cdk-integ-assert.ts b/source/tools/cdk-integ-tools/bin/cdk-integ-assert.ts index b3988bafd..1dc74efb9 100644 --- a/source/tools/cdk-integ-tools/bin/cdk-integ-assert.ts +++ b/source/tools/cdk-integ-tools/bin/cdk-integ-assert.ts @@ -29,6 +29,7 @@ async function main() { let actual = await test.cdkSynthFast( deepmerge(DEFAULT_SYNTH_OPTIONS, { context: { + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true, "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true, "@aws-cdk/aws-rds:lowercaseDbIdentifier": true, diff --git a/source/tools/cdk-integ-tools/bin/cdk-integ.ts b/source/tools/cdk-integ-tools/bin/cdk-integ.ts index cefb65289..7d9ebb693 100644 --- a/source/tools/cdk-integ-tools/bin/cdk-integ.ts +++ b/source/tools/cdk-integ-tools/bin/cdk-integ.ts @@ -77,6 +77,7 @@ async function main() { const actual = await test.cdkSynthFast( deepmerge(DEFAULT_SYNTH_OPTIONS, { context: { + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true, "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true, "@aws-cdk/aws-rds:lowercaseDbIdentifier": true,