From e8d0f65fd07c7427493cf81046ed7c727f1c3fb9 Mon Sep 17 00:00:00 2001 From: Jamie Mullan <46033424+jamiepmullan@users.noreply.github.com> Date: Sat, 4 Jan 2025 21:47:44 +0000 Subject: [PATCH] add origin selection criteria to L2 Distribution add integration test --- .../cdk.out | 1 + ...rigin-group-selection-criteria.assets.json | 19 ++ ...gin-group-selection-criteria.template.json | 135 +++++++++ .../integ.json | 12 + .../manifest.json | 125 +++++++++ ...efaultTestDeployAssert18CEDA1E.assets.json | 19 ++ ...aultTestDeployAssert18CEDA1E.template.json | 36 +++ .../tree.json | 257 ++++++++++++++++++ .../integ.origin-group-selection-criteria.ts | 35 +++ .../lib/origin-group.ts | 8 + .../aws-cloudfront/lib/distribution.ts | 13 +- .../aws-cdk-lib/aws-cloudfront/lib/origin.ts | 23 ++ .../test/selection-criteria-origin.test.ts | 101 +++++++ 13 files changed, 781 insertions(+), 3 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/cloudfront-origin-group-selection-criteria.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/cloudfront-origin-group-selection-criteria.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/origingroupselectioncriteriaDefaultTestDeployAssert18CEDA1E.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/origingroupselectioncriteriaDefaultTestDeployAssert18CEDA1E.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.ts create mode 100644 packages/aws-cdk-lib/aws-cloudfront/test/selection-criteria-origin.test.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/cdk.out new file mode 100644 index 0000000000000..91e1a8b9901d5 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"39.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/cloudfront-origin-group-selection-criteria.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/cloudfront-origin-group-selection-criteria.assets.json new file mode 100644 index 0000000000000..4d44e7b550cc0 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/cloudfront-origin-group-selection-criteria.assets.json @@ -0,0 +1,19 @@ +{ + "version": "39.0.0", + "files": { + "6e97b9335ad80a29692b43257e7b28d171f619306ac0952ea7b0b92ac4dbb0fa": { + "source": { + "path": "cloudfront-origin-group-selection-criteria.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "6e97b9335ad80a29692b43257e7b28d171f619306ac0952ea7b0b92ac4dbb0fa.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/cloudfront-origin-group-selection-criteria.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/cloudfront-origin-group-selection-criteria.template.json new file mode 100644 index 0000000000000..62d6a96b95f5a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/cloudfront-origin-group-selection-criteria.template.json @@ -0,0 +1,135 @@ +{ + "Resources": { + "cg1": { + "Type": "AWS::MediaPackageV2::ChannelGroup", + "Properties": { + "ChannelGroupName": "channelGroup1" + } + }, + "cg2": { + "Type": "AWS::MediaPackageV2::ChannelGroup", + "Properties": { + "ChannelGroupName": "channelGroup2" + } + }, + "Distribution830FAC52": { + "Type": "AWS::CloudFront::Distribution", + "Properties": { + "DistributionConfig": { + "CacheBehaviors": [ + { + "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6", + "Compress": true, + "PathPattern": "/video", + "TargetOriginId": "cloudfrontorigingroupselectioncriteriaDistributionOriginGroup1518D308D", + "ViewerProtocolPolicy": "allow-all" + } + ], + "DefaultCacheBehavior": { + "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6", + "Compress": true, + "TargetOriginId": "cloudfrontorigingroupselectioncriteriaDistributionOriginGroup1518D308D", + "ViewerProtocolPolicy": "allow-all" + }, + "Enabled": true, + "HttpVersion": "http2", + "IPV6Enabled": true, + "OriginGroups": { + "Items": [ + { + "FailoverCriteria": { + "StatusCodes": { + "Items": [ + 404 + ], + "Quantity": 1 + } + }, + "Id": "cloudfrontorigingroupselectioncriteriaDistributionOriginGroup1518D308D", + "Members": { + "Items": [ + { + "OriginId": "cloudfrontorigingroupselectioncriteriaDistributionOrigin1AA511FA4" + }, + { + "OriginId": "cloudfrontorigingroupselectioncriteriaDistributionOrigin2AFDC8F08" + } + ], + "Quantity": 2 + }, + "SelectionCriteria": "media-quality-based" + } + ], + "Quantity": 1 + }, + "Origins": [ + { + "CustomOriginConfig": { + "OriginProtocolPolicy": "https-only", + "OriginSSLProtocols": [ + "TLSv1.2" + ] + }, + "DomainName": { + "Fn::GetAtt": [ + "cg1", + "EgressDomain" + ] + }, + "Id": "cloudfrontorigingroupselectioncriteriaDistributionOrigin1AA511FA4" + }, + { + "CustomOriginConfig": { + "OriginProtocolPolicy": "https-only", + "OriginSSLProtocols": [ + "TLSv1.2" + ] + }, + "DomainName": { + "Fn::GetAtt": [ + "cg2", + "EgressDomain" + ] + }, + "Id": "cloudfrontorigingroupselectioncriteriaDistributionOrigin2AFDC8F08" + } + ] + } + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/integ.json new file mode 100644 index 0000000000000..a6416fbd09634 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "39.0.0", + "testCases": { + "origin-group-selection-criteria/DefaultTest": { + "stacks": [ + "cloudfront-origin-group-selection-criteria" + ], + "assertionStack": "origin-group-selection-criteria/DefaultTest/DeployAssert", + "assertionStackName": "origingroupselectioncriteriaDefaultTestDeployAssert18CEDA1E" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/manifest.json new file mode 100644 index 0000000000000..116c4688e6126 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/manifest.json @@ -0,0 +1,125 @@ +{ + "version": "39.0.0", + "artifacts": { + "cloudfront-origin-group-selection-criteria.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "cloudfront-origin-group-selection-criteria.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "cloudfront-origin-group-selection-criteria": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "cloudfront-origin-group-selection-criteria.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/6e97b9335ad80a29692b43257e7b28d171f619306ac0952ea7b0b92ac4dbb0fa.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "cloudfront-origin-group-selection-criteria.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "cloudfront-origin-group-selection-criteria.assets" + ], + "metadata": { + "/cloudfront-origin-group-selection-criteria/cg1": [ + { + "type": "aws:cdk:logicalId", + "data": "cg1" + } + ], + "/cloudfront-origin-group-selection-criteria/cg2": [ + { + "type": "aws:cdk:logicalId", + "data": "cg2" + } + ], + "/cloudfront-origin-group-selection-criteria/Distribution/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Distribution830FAC52" + } + ], + "/cloudfront-origin-group-selection-criteria/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/cloudfront-origin-group-selection-criteria/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "cloudfront-origin-group-selection-criteria" + }, + "origingroupselectioncriteriaDefaultTestDeployAssert18CEDA1E.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "origingroupselectioncriteriaDefaultTestDeployAssert18CEDA1E.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "origingroupselectioncriteriaDefaultTestDeployAssert18CEDA1E": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "origingroupselectioncriteriaDefaultTestDeployAssert18CEDA1E.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "origingroupselectioncriteriaDefaultTestDeployAssert18CEDA1E.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "origingroupselectioncriteriaDefaultTestDeployAssert18CEDA1E.assets" + ], + "metadata": { + "/origin-group-selection-criteria/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/origin-group-selection-criteria/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "origin-group-selection-criteria/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/origingroupselectioncriteriaDefaultTestDeployAssert18CEDA1E.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/origingroupselectioncriteriaDefaultTestDeployAssert18CEDA1E.assets.json new file mode 100644 index 0000000000000..a173a6c08b3fc --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/origingroupselectioncriteriaDefaultTestDeployAssert18CEDA1E.assets.json @@ -0,0 +1,19 @@ +{ + "version": "39.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "origingroupselectioncriteriaDefaultTestDeployAssert18CEDA1E.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/origingroupselectioncriteriaDefaultTestDeployAssert18CEDA1E.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/origingroupselectioncriteriaDefaultTestDeployAssert18CEDA1E.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/origingroupselectioncriteriaDefaultTestDeployAssert18CEDA1E.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/tree.json new file mode 100644 index 0000000000000..6853be9c0970c --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.js.snapshot/tree.json @@ -0,0 +1,257 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "cloudfront-origin-group-selection-criteria": { + "id": "cloudfront-origin-group-selection-criteria", + "path": "cloudfront-origin-group-selection-criteria", + "children": { + "cg1": { + "id": "cg1", + "path": "cloudfront-origin-group-selection-criteria/cg1", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::MediaPackageV2::ChannelGroup", + "aws:cdk:cloudformation:props": { + "channelGroupName": "channelGroup1" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_mediapackagev2.CfnChannelGroup", + "version": "0.0.0" + } + }, + "cg2": { + "id": "cg2", + "path": "cloudfront-origin-group-selection-criteria/cg2", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::MediaPackageV2::ChannelGroup", + "aws:cdk:cloudformation:props": { + "channelGroupName": "channelGroup2" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_mediapackagev2.CfnChannelGroup", + "version": "0.0.0" + } + }, + "Distribution": { + "id": "Distribution", + "path": "cloudfront-origin-group-selection-criteria/Distribution", + "children": { + "Origin1": { + "id": "Origin1", + "path": "cloudfront-origin-group-selection-criteria/Distribution/Origin1", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "OriginGroup1": { + "id": "OriginGroup1", + "path": "cloudfront-origin-group-selection-criteria/Distribution/OriginGroup1", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "Origin2": { + "id": "Origin2", + "path": "cloudfront-origin-group-selection-criteria/Distribution/Origin2", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "Resource": { + "id": "Resource", + "path": "cloudfront-origin-group-selection-criteria/Distribution/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CloudFront::Distribution", + "aws:cdk:cloudformation:props": { + "distributionConfig": { + "enabled": true, + "origins": [ + { + "domainName": { + "Fn::GetAtt": [ + "cg1", + "EgressDomain" + ] + }, + "id": "cloudfrontorigingroupselectioncriteriaDistributionOrigin1AA511FA4", + "customOriginConfig": { + "originSslProtocols": [ + "TLSv1.2" + ], + "originProtocolPolicy": "https-only" + } + }, + { + "domainName": { + "Fn::GetAtt": [ + "cg2", + "EgressDomain" + ] + }, + "id": "cloudfrontorigingroupselectioncriteriaDistributionOrigin2AFDC8F08", + "customOriginConfig": { + "originSslProtocols": [ + "TLSv1.2" + ], + "originProtocolPolicy": "https-only" + } + } + ], + "originGroups": { + "items": [ + { + "failoverCriteria": { + "statusCodes": { + "items": [ + 404 + ], + "quantity": 1 + } + }, + "id": "cloudfrontorigingroupselectioncriteriaDistributionOriginGroup1518D308D", + "members": { + "items": [ + { + "originId": "cloudfrontorigingroupselectioncriteriaDistributionOrigin1AA511FA4" + }, + { + "originId": "cloudfrontorigingroupselectioncriteriaDistributionOrigin2AFDC8F08" + } + ], + "quantity": 2 + }, + "selectionCriteria": "media-quality-based" + } + ], + "quantity": 1 + }, + "defaultCacheBehavior": { + "pathPattern": "*", + "targetOriginId": "cloudfrontorigingroupselectioncriteriaDistributionOriginGroup1518D308D", + "cachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6", + "compress": true, + "viewerProtocolPolicy": "allow-all" + }, + "cacheBehaviors": [ + { + "pathPattern": "/video", + "targetOriginId": "cloudfrontorigingroupselectioncriteriaDistributionOriginGroup1518D308D", + "cachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6", + "compress": true, + "viewerProtocolPolicy": "allow-all" + } + ], + "httpVersion": "http2", + "ipv6Enabled": true + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_cloudfront.CfnDistribution", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_cloudfront.Distribution", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "cloudfront-origin-group-selection-criteria/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "cloudfront-origin-group-selection-criteria/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "origin-group-selection-criteria": { + "id": "origin-group-selection-criteria", + "path": "origin-group-selection-criteria", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "origin-group-selection-criteria/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "origin-group-selection-criteria/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "origin-group-selection-criteria/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "origin-group-selection-criteria/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "origin-group-selection-criteria/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.ts new file mode 100644 index 0000000000000..4a1c71e20f6ea --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group-selection-criteria.ts @@ -0,0 +1,35 @@ +import * as cloudfront from 'aws-cdk-lib/aws-cloudfront'; +import * as cdk from 'aws-cdk-lib'; +import * as origins from 'aws-cdk-lib/aws-cloudfront-origins'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import { CfnChannelGroup } from 'aws-cdk-lib/aws-mediapackagev2'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'cloudfront-origin-group-selection-criteria'); + +const channelGroup = new CfnChannelGroup(stack, 'cg1', { + channelGroupName: 'channelGroup1', +}); +const channelGroup2 = new CfnChannelGroup(stack, 'cg2', { + channelGroupName: 'channelGroup2', +}); + +const originGroup = new origins.OriginGroup({ + primaryOrigin: new origins.HttpOrigin(channelGroup.attrEgressDomain), + fallbackOrigin: new origins.HttpOrigin(channelGroup2.attrEgressDomain), + fallbackStatusCodes: [404], + selectionCriteria: cloudfront.OriginGroupSelectionCriteria.MEDIA_QUALITY_BASED, +}); + +new cloudfront.Distribution(stack, 'Distribution', { + defaultBehavior: { origin: originGroup }, + additionalBehaviors: { + '/video': { + origin: originGroup, + }, + }, +}); + +new IntegTest(app, 'origin-group-selection-criteria', { + testCases: [stack], +}); diff --git a/packages/aws-cdk-lib/aws-cloudfront-origins/lib/origin-group.ts b/packages/aws-cdk-lib/aws-cloudfront-origins/lib/origin-group.ts index cf057e2ab3412..53da54115cf2a 100644 --- a/packages/aws-cdk-lib/aws-cloudfront-origins/lib/origin-group.ts +++ b/packages/aws-cdk-lib/aws-cloudfront-origins/lib/origin-group.ts @@ -21,6 +21,13 @@ export interface OriginGroupProps { * @default - 500, 502, 503 and 504 */ readonly fallbackStatusCodes?: number[]; + + /** + * The selection criteria for the origin group. + * + * @default - nothing is returned + */ + readonly selectionCriteria?: cloudfront.OriginGroupSelectionCriteria; } /** @@ -44,6 +51,7 @@ export class OriginGroup implements cloudfront.IOrigin { failoverOrigin: this.props.fallbackOrigin, statusCodes: this.props.fallbackStatusCodes, }, + selectionCriteria: this.props.selectionCriteria, }; } } diff --git a/packages/aws-cdk-lib/aws-cloudfront/lib/distribution.ts b/packages/aws-cdk-lib/aws-cloudfront/lib/distribution.ts index 9bed65f41f48e..16a530a2236ec 100644 --- a/packages/aws-cdk-lib/aws-cloudfront/lib/distribution.ts +++ b/packages/aws-cdk-lib/aws-cloudfront/lib/distribution.ts @@ -4,7 +4,7 @@ import { CfnDistribution, CfnMonitoringSubscription } from './cloudfront.generat import { FunctionAssociation } from './function'; import { GeoRestriction } from './geo-restriction'; import { IKeyGroup } from './key-group'; -import { IOrigin, OriginBindConfig, OriginBindOptions } from './origin'; +import { IOrigin, OriginBindConfig, OriginBindOptions, OriginGroupSelectionCriteria } from './origin'; import { IOriginRequestPolicy } from './origin-request-policy'; import { CacheBehavior } from './private/cache-behavior'; import { formatDistributionArn } from './private/utils'; @@ -673,14 +673,20 @@ export class Distribution extends Resource implements IDistribution { this.boundOrigins.push({ origin, originId, distributionId, originGroupId, ...originBindConfig }); const failoverOriginId = this.addOrigin(originBindConfig.failoverConfig.failoverOrigin, true); - this.addOriginGroup(originGroupId, originBindConfig.failoverConfig.statusCodes, originId, failoverOriginId); + this.addOriginGroup(originGroupId, + originBindConfig.failoverConfig.statusCodes, + originId, failoverOriginId, + originBindConfig.selectionCriteria); return originGroupId; } return originBindConfig.originProperty?.id ?? originId; } } - private addOriginGroup(originGroupId: string, statusCodes: number[] | undefined, originId: string, failoverOriginId: string): void { + private addOriginGroup(originGroupId: string, + statusCodes: number[] | undefined, + originId: string, failoverOriginId: string, + selectionCriteria: OriginGroupSelectionCriteria | undefined): void { statusCodes = statusCodes ?? [500, 502, 503, 504]; if (statusCodes.length === 0) { throw new Error('fallbackStatusCodes cannot be empty'); @@ -700,6 +706,7 @@ export class Distribution extends Resource implements IDistribution { ], quantity: 2, }, + selectionCriteria, }); } diff --git a/packages/aws-cdk-lib/aws-cloudfront/lib/origin.ts b/packages/aws-cdk-lib/aws-cloudfront/lib/origin.ts index 041f296d20fef..4e74243e263e7 100644 --- a/packages/aws-cdk-lib/aws-cloudfront/lib/origin.ts +++ b/packages/aws-cdk-lib/aws-cloudfront/lib/origin.ts @@ -2,6 +2,22 @@ import { Construct } from 'constructs'; import { CfnDistribution } from './cloudfront.generated'; import { Duration, Token } from '../../core'; +/** + * The selection criteria for the origin group. + * + * @default - none + */ +export enum OriginGroupSelectionCriteria { + /** + * Default selection behavior. + */ + DEFAULT='default', + /** + * Selection based on media quality. + */ + MEDIA_QUALITY_BASED='media-quality-based', +} + /** * The failover configuration used for Origin Groups, * returned in `OriginBindConfig.failoverConfig`. @@ -33,6 +49,13 @@ export interface OriginBindConfig { * @default - nothing is returned */ readonly failoverConfig?: OriginFailoverConfig; + + /** + * The failover selection for the Distribution. + * + * @default - nothing is returned + */ + readonly selectionCriteria?: OriginGroupSelectionCriteria; } /** diff --git a/packages/aws-cdk-lib/aws-cloudfront/test/selection-criteria-origin.test.ts b/packages/aws-cdk-lib/aws-cloudfront/test/selection-criteria-origin.test.ts new file mode 100644 index 0000000000000..349fb8b5e31a8 --- /dev/null +++ b/packages/aws-cdk-lib/aws-cloudfront/test/selection-criteria-origin.test.ts @@ -0,0 +1,101 @@ +import * as cloudfront from '../'; +import { Template } from '../../assertions'; +import * as origins from '../../aws-cloudfront-origins'; +import { CfnChannelGroup } from '../../aws-mediapackagev2'; +import { Stack } from '../../core'; + +let stack: Stack; +let otherStack: Stack; + +beforeEach(() => { + stack = new Stack(); + otherStack = new Stack(); +}); + +test('Selection criteria does set Media Quality Based failover', () => { + const channelGroup = new CfnChannelGroup(stack, 'cg1', { + channelGroupName: 'channelGroup1', + }); + const channelGroup2 = new CfnChannelGroup(stack, 'cg2', { + channelGroupName: 'channelGroup2', + }); + + const originGroup = new origins.OriginGroup({ + primaryOrigin: new origins.HttpOrigin(channelGroup.attrEgressDomain), + fallbackOrigin: new origins.HttpOrigin(channelGroup2.attrEgressDomain), + fallbackStatusCodes: [404], + selectionCriteria: cloudfront.OriginGroupSelectionCriteria.MEDIA_QUALITY_BASED, + }); + + new cloudfront.Distribution(stack, 'dist', { + defaultBehavior: { + origin: originGroup, + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::CloudFront::Distribution', { + DistributionConfig: { + DefaultCacheBehavior: { + TargetOriginId: 'distOriginGroup1CE86FDB8', + }, + OriginGroups: { + Items: [{ + FailoverCriteria: { + StatusCodes: { + Items: [404], + }, + }, + Id: 'distOriginGroup1CE86FDB8', + Members: { + Items: [ + { OriginId: 'distOrigin175AC3CB4' }, + { OriginId: 'distOrigin203EDB784' }, + ], + }, + SelectionCriteria: 'media-quality-based', + }], + }, + }, + }); +}); + +test('Ensure default is undefined', () => { + const url1 = new origins.HttpOrigin('myurl.com'); + const url2 = new origins.HttpOrigin('myurl1.com'); + + const og = new origins.OriginGroup({ + primaryOrigin: url1, + fallbackOrigin: url2, + fallbackStatusCodes: [404], + }); + + new cloudfront.Distribution(stack, 'dist', { + defaultBehavior: { + origin: og, + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::CloudFront::Distribution', { + DistributionConfig: { + DefaultCacheBehavior: { + TargetOriginId: 'distOriginGroup1CE86FDB8', + }, + OriginGroups: { + Items: [{ + FailoverCriteria: { + StatusCodes: { + Items: [404], + }, + }, + Id: 'distOriginGroup1CE86FDB8', + Members: { + Items: [ + { OriginId: 'distOrigin175AC3CB4' }, + { OriginId: 'distOrigin203EDB784' }, + ], + }, + }], + }, + }, + }); +});