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 3c0c7a751..fe3d7c84d 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 @@ -1,113 +1,198 @@ { "Description": "Integration test for aws-cloudfront-mediastore override properties", "Resources": { - "testcloudfrontmediastoreCloudFrontDistributionED9265B1": { - "Metadata": { - "cfn_nag": { - "rules_to_suppress": [ - { - "id": "W70", - "reason": "Since the distribution uses the CloudFront domain name, CloudFront automatically sets the security policy to TLSv1 regardless of the value of MinimumProtocolVersion" - } - ] - } - }, + "testcloudfrontmediastoreMediaStoreContainerF60A96BB": { + "Type": "AWS::MediaStore::Container", "Properties": { - "DistributionConfig": { - "DefaultCacheBehavior": { + "ContainerName": "MyOwnMediaStoreContainer", + "AccessLoggingEnabled": true, + "CorsPolicy": [ + { + "AllowedHeaders": [ + "*" + ], "AllowedMethods": [ - "GET", - "HEAD", - "OPTIONS", - "PUT", - "PATCH", - "POST", - "DELETE" + "GET" ], - "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6", - "CachedMethods": [ - "GET", - "HEAD" + "AllowedOrigins": [ + "*" ], - "Compress": true, - "LambdaFunctionAssociations": [ + "ExposeHeaders": [ + "*" + ], + "MaxAgeSeconds": 3000 + } + ], + "LifecyclePolicy": "{\"rules\":[{\"definition\":{\"path\":[{\"wildcard\":\"*\"}],\"days_since_create\":[{\"numeric\":[\">\",30]}]},\"action\":\"EXPIRE\"}]}", + "MetricPolicy": { + "ContainerLevelMetrics": "ENABLED" + }, + "Policy": { + "Fn::Join": [ + "", + [ + "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"OverridePolicy\",\"Effect\":\"Allow\",\"Principal\":\"*\",\"Action\":\"mediastore:*\",\"Resource\":\"arn:aws:mediastore:", { - "EventType": "origin-response", - "LambdaFunctionARN": { - "Ref": "testcloudfrontmediastoreSetHttpSecurityHeadersVersionE87B65C3" - } + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":container/MyOwnMediaStoreContainer/*\",\"Condition\":{\"Bool\":{\"aws:SecureTransport\":\"true\"}}}]}" + ] + ] + } + }, + "DeletionPolicy": "Retain" + }, + "testcloudfrontmediastoreSetHttpSecurityHeadersServiceRole2F1F5449": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" } - ], - "OriginRequestPolicyId": { - "Ref": "testcloudfrontmediastoreCloudfrontOriginRequestPolicyA1D988D3" }, - "TargetOriginId": "testcloudfrontmediastoreCloudFrontDistributionOrigin1CB4159BB", - "ViewerProtocolPolicy": "https-only" - }, - "Enabled": true, - "HttpVersion": "http2", - "IPV6Enabled": true, - "Logging": { - "Bucket": { - "Fn::GetAtt": [ - "testcloudfrontmediastoreCloudfrontLoggingBucketA3A51E6A", - "RegionalDomainName" - ] - } - }, - "Origins": [ { - "CustomOriginConfig": { - "OriginProtocolPolicy": "https-only", - "OriginSSLProtocols": [ - "TLSv1.2" - ] - }, - "DomainName": { - "Fn::Select": [ - 0, - { - "Fn::Split": [ - "/", - { - "Fn::Select": [ - 1, - { - "Fn::Split": [ - "://", - { - "Fn::GetAtt": [ - "testcloudfrontmediastoreMediaStoreContainerF60A96BB", - "Endpoint" - ] - } - ] - } - ] - } + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "edgelambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "Policies": [ + { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":log-group:/aws/lambda/*" + ] ] } - ] - }, - "Id": "testcloudfrontmediastoreCloudFrontDistributionOrigin1CB4159BB" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "LambdaFunctionServiceRolePolicy" + } + ] + } + }, + "testcloudfrontmediastoreSetHttpSecurityHeadersServiceRoleDefaultPolicy73DF1407": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "xray:PutTraceSegments", + "xray:PutTelemetryRecords" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "testcloudfrontmediastoreSetHttpSecurityHeadersServiceRoleDefaultPolicy73DF1407", + "Roles": [ + { + "Ref": "testcloudfrontmediastoreSetHttpSecurityHeadersServiceRole2F1F5449" + } + ] + }, + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W12", + "reason": "Lambda needs the following minimum required permissions to send trace data to X-Ray and access ENIs in a VPC." } ] } - }, - "Type": "AWS::CloudFront::Distribution" + } }, - "testcloudfrontmediastoreCloudfrontLoggingBucketA3A51E6A": { - "DeletionPolicy": "Retain", + "testcloudfrontmediastoreSetHttpSecurityHeaders9995A63D": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "exports.handler = (event, context, callback) => { const response = event.Records[0].cf.response; const headers = response.headers; headers['x-xss-protection'] = [ { key: 'X-XSS-Protection', value: '1; mode=block' } ]; headers['x-frame-options'] = [ { key: 'X-Frame-Options', value: 'DENY' } ]; headers['x-content-type-options'] = [ { key: 'X-Content-Type-Options', value: 'nosniff' } ]; headers['strict-transport-security'] = [ { key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubdomains; preload' } ]; headers['referrer-policy'] = [ { key: 'Referrer-Policy', value: 'same-origin' } ]; headers['content-security-policy'] = [ { key: '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'\" } ]; callback(null, response); };" + }, + "Role": { + "Fn::GetAtt": [ + "testcloudfrontmediastoreSetHttpSecurityHeadersServiceRole2F1F5449", + "Arn" + ] + }, + "Handler": "index.handler", + "Runtime": "nodejs12.x", + "TracingConfig": { + "Mode": "Active" + } + }, + "DependsOn": [ + "testcloudfrontmediastoreSetHttpSecurityHeadersServiceRoleDefaultPolicy73DF1407", + "testcloudfrontmediastoreSetHttpSecurityHeadersServiceRole2F1F5449" + ], "Metadata": { "cfn_nag": { "rules_to_suppress": [ { - "id": "W35", - "reason": "This S3 bucket is used as the access logging bucket for CloudFront Distribution" + "id": "W58", + "reason": "Lambda functions has the required permission to write CloudWatch Logs. It uses custom policy instead of arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole with tighter permissions." + }, + { + "id": "W89", + "reason": "This is not a rule for the general case, just for specific use cases/industries" + }, + { + "id": "W92", + "reason": "Impossible for us to define the correct concurrency for clients" } ] } - }, + } + }, + "testcloudfrontmediastoreSetHttpSecurityHeadersVersionE87B65C3": { + "Type": "AWS::Lambda::Version", + "Properties": { + "FunctionName": { + "Ref": "testcloudfrontmediastoreSetHttpSecurityHeaders9995A63D" + } + } + }, + "testcloudfrontmediastoreCloudfrontLoggingBucketA3A51E6A": { + "Type": "AWS::S3::Bucket", "Properties": { "AccessControl": "LogDeliveryWrite", "BucketEncryption": { @@ -126,10 +211,21 @@ "RestrictPublicBuckets": true } }, - "Type": "AWS::S3::Bucket", - "UpdateReplacePolicy": "Retain" + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain", + "Metadata": { + "cfn_nag": { + "rules_to_suppress": [ + { + "id": "W35", + "reason": "This S3 bucket is used as the access logging bucket for CloudFront Distribution" + } + ] + } + } }, "testcloudfrontmediastoreCloudfrontLoggingBucketPolicyF3B44DFD": { + "Type": "AWS::S3::BucketPolicy", "Properties": { "Bucket": { "Ref": "testcloudfrontmediastoreCloudfrontLoggingBucketA3A51E6A" @@ -164,10 +260,10 @@ ], "Version": "2012-10-17" } - }, - "Type": "AWS::S3::BucketPolicy" + } }, "testcloudfrontmediastoreCloudfrontOriginRequestPolicyA1D988D3": { + "Type": "AWS::CloudFront::OriginRequestPolicy", "Properties": { "OriginRequestPolicyConfig": { "Comment": "Policy for Constructs CloudFrontDistributionForMediaStore", @@ -202,183 +298,102 @@ "QueryStringBehavior": "all" } } - }, - "Type": "AWS::CloudFront::OriginRequestPolicy" + } }, - "testcloudfrontmediastoreMediaStoreContainerF60A96BB": { - "DeletionPolicy": "Retain", + "testcloudfrontmediastoreCloudFrontDistributionED9265B1": { + "Type": "AWS::CloudFront::Distribution", "Properties": { - "AccessLoggingEnabled": true, - "ContainerName": "MyMediaStoreContainer", - "CorsPolicy": [ - { - "AllowedHeaders": [ - "*" - ], + "DistributionConfig": { + "DefaultCacheBehavior": { "AllowedMethods": [ - "GET" + "GET", + "HEAD", + "OPTIONS", + "PUT", + "PATCH", + "POST", + "DELETE" ], - "AllowedOrigins": [ - "*" + "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6", + "CachedMethods": [ + "GET", + "HEAD" ], - "ExposeHeaders": [ - "*" + "Compress": true, + "LambdaFunctionAssociations": [ + { + "EventType": "origin-response", + "LambdaFunctionARN": { + "Ref": "testcloudfrontmediastoreSetHttpSecurityHeadersVersionE87B65C3" + } + } ], - "MaxAgeSeconds": 3000 - } - ], - "MetricPolicy": { - "ContainerLevelMetrics": "ENABLED" - }, - "LifecyclePolicy": "{\"rules\":[{\"definition\":{\"path\":[{\"wildcard\":\"*\"}],\"days_since_create\":[{\"numeric\":[\">\",30]}]},\"action\":\"EXPIRE\"}]}", - "Policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"OverridePolicy\",\"Effect\":\"Allow\",\"Principal\":\"*\",\"Action\":\"mediastore:*\",\"Resource\":\"*\"}]}" - }, - "Type": "AWS::MediaStore::Container" - }, - "testcloudfrontmediastoreSetHttpSecurityHeaders9995A63D": { - "DependsOn": [ - "testcloudfrontmediastoreSetHttpSecurityHeadersServiceRoleDefaultPolicy73DF1407", - "testcloudfrontmediastoreSetHttpSecurityHeadersServiceRole2F1F5449" - ], - "Metadata": { - "cfn_nag": { - "rules_to_suppress": [ - { - "id": "W58", - "reason": "Lambda functions has the required permission to write CloudWatch Logs. It uses custom policy instead of arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole with tighter permissions." - }, - { - "id": "W89", - "reason": "This is not a rule for the general case, just for specific use cases/industries" + "OriginRequestPolicyId": { + "Ref": "testcloudfrontmediastoreCloudfrontOriginRequestPolicyA1D988D3" }, - { - "id": "W92", - "reason": "Impossible for us to define the correct concurrency for clients" + "TargetOriginId": "testcloudfrontmediastoreoverridetestcloudfrontmediastoreCloudFrontDistributionOrigin1BD16B15A", + "ViewerProtocolPolicy": "https-only" + }, + "Enabled": true, + "HttpVersion": "http2", + "IPV6Enabled": true, + "Logging": { + "Bucket": { + "Fn::GetAtt": [ + "testcloudfrontmediastoreCloudfrontLoggingBucketA3A51E6A", + "RegionalDomainName" + ] } - ] - } - }, - "Properties": { - "Code": { - "ZipFile": "exports.handler = (event, context, callback) => { const response = event.Records[0].cf.response; const headers = response.headers; headers['x-xss-protection'] = [ { key: 'X-XSS-Protection', value: '1; mode=block' } ]; headers['x-frame-options'] = [ { key: 'X-Frame-Options', value: 'DENY' } ]; headers['x-content-type-options'] = [ { key: 'X-Content-Type-Options', value: 'nosniff' } ]; headers['strict-transport-security'] = [ { key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubdomains; preload' } ]; headers['referrer-policy'] = [ { key: 'Referrer-Policy', value: 'same-origin' } ]; headers['content-security-policy'] = [ { key: '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'\" } ]; callback(null, response); };" - }, - "Handler": "index.handler", - "Role": { - "Fn::GetAtt": [ - "testcloudfrontmediastoreSetHttpSecurityHeadersServiceRole2F1F5449", - "Arn" - ] - }, - "Runtime": "nodejs12.x", - "TracingConfig": { - "Mode": "Active" - } - }, - "Type": "AWS::Lambda::Function" - }, - "testcloudfrontmediastoreSetHttpSecurityHeadersServiceRole2F1F5449": { - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - }, + }, + "Origins": [ { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "edgelambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "Policies": [ - { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "logs:CreateLogGroup", - "logs:CreateLogStream", - "logs:PutLogEvents" - ], - "Effect": "Allow", - "Resource": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":logs:", - { - "Ref": "AWS::Region" - }, - ":", - { - "Ref": "AWS::AccountId" - }, - ":log-group:/aws/lambda/*" - ] + "CustomOriginConfig": { + "OriginProtocolPolicy": "https-only", + "OriginSSLProtocols": [ + "TLSv1.2" + ] + }, + "DomainName": { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "/", + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "://", + { + "Fn::GetAtt": [ + "testcloudfrontmediastoreMediaStoreContainerF60A96BB", + "Endpoint" + ] + } + ] + } + ] + } ] } - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "LambdaFunctionServiceRolePolicy" - } - ] + ] + }, + "Id": "testcloudfrontmediastoreoverridetestcloudfrontmediastoreCloudFrontDistributionOrigin1BD16B15A" + } + ] + } }, - "Type": "AWS::IAM::Role" - }, - "testcloudfrontmediastoreSetHttpSecurityHeadersServiceRoleDefaultPolicy73DF1407": { "Metadata": { "cfn_nag": { "rules_to_suppress": [ { - "id": "W12", - "reason": "Lambda needs the following minimum required permissions to send trace data to X-Ray and access ENIs in a VPC." + "id": "W70", + "reason": "Since the distribution uses the CloudFront domain name, CloudFront automatically sets the security policy to TLSv1 regardless of the value of MinimumProtocolVersion" } ] } - }, - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "xray:PutTraceSegments", - "xray:PutTelemetryRecords" - ], - "Effect": "Allow", - "Resource": "*" - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "testcloudfrontmediastoreSetHttpSecurityHeadersServiceRoleDefaultPolicy73DF1407", - "Roles": [ - { - "Ref": "testcloudfrontmediastoreSetHttpSecurityHeadersServiceRole2F1F5449" - } - ] - }, - "Type": "AWS::IAM::Policy" - }, - "testcloudfrontmediastoreSetHttpSecurityHeadersVersionE87B65C3": { - "Properties": { - "FunctionName": { - "Ref": "testcloudfrontmediastoreSetHttpSecurityHeaders9995A63D" - } - }, - "Type": "AWS::Lambda::Version" + } } } } \ No newline at end of file diff --git a/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.overrideProperties.ts b/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.overrideProperties.ts index 5d3df7cfc..0e8b82d04 100644 --- a/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.overrideProperties.ts +++ b/source/patterns/@aws-solutions-constructs/aws-cloudfront-mediastore/test/integ.overrideProperties.ts @@ -12,17 +12,17 @@ */ // Imports -import { App, Stack } from '@aws-cdk/core'; +import { App, Aws, Stack } from '@aws-cdk/core'; import * as mediastore from '@aws-cdk/aws-mediastore'; import * as cloudfront from '@aws-cdk/aws-cloudfront'; import { CloudFrontToMediaStore } from '../lib'; // Setup const app = new App(); -const stack = new Stack(app, 'test-cloudfront-mediastore'); +const stack = new Stack(app, 'test-cloudfront-mediastore-override'); stack.templateOptions.description = 'Integration test for aws-cloudfront-mediastore override properties'; const mediaStoreContainerProps: mediastore.CfnContainerProps = { - containerName: 'MyMediaStoreContainer', + containerName: 'MyOwnMediaStoreContainer', policy: JSON.stringify({ Version: '2012-10-17', Statement: [{ @@ -30,7 +30,10 @@ const mediaStoreContainerProps: mediastore.CfnContainerProps = { Effect: 'Allow', Principal: '*', Action: 'mediastore:*', - Resource: '*' + Resource: `arn:aws:mediastore:${Aws.REGION}:${Aws.ACCOUNT_ID}:container/MyOwnMediaStoreContainer/*`, + Condition: { + Bool: { "aws:SecureTransport": "true" } + } }] }) };