diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/cdk.out index 588d7b269d34f..91e1a8b9901d5 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/cdk.out +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"20.0.0"} \ No newline at end of file +{"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.js.snapshot/cloudfront-origin-group.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/cloudfront-origin-group.assets.json index 0f084c34f51f8..9540a076fcd2d 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/cloudfront-origin-group.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/cloudfront-origin-group.assets.json @@ -1,7 +1,7 @@ { - "version": "20.0.0", + "version": "39.0.0", "files": { - "d2914b9a230a95dad42d7412aa26c3c7e04ad03cd4bd32f66a9c6ef529559393": { + "6cd6815fb994ed9d8e8f37329a05ba8fb469cbefa63ee221ecf52d045c1dcd63": { "source": { "path": "cloudfront-origin-group.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "d2914b9a230a95dad42d7412aa26c3c7e04ad03cd4bd32f66a9c6ef529559393.json", + "objectKey": "6cd6815fb994ed9d8e8f37329a05ba8fb469cbefa63ee221ecf52d045c1dcd63.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/cloudfront-origin-group.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/cloudfront-origin-group.template.json index cdae4462e52ef..618436c6673af 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/cloudfront-origin-group.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/cloudfront-origin-group.template.json @@ -61,14 +61,14 @@ "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6", "Compress": true, "PathPattern": "/api", - "TargetOriginId": "cloudfrontorigingroupDistributionOriginGroup10B57F1D1", + "TargetOriginId": "CustomGroupId", "ViewerProtocolPolicy": "allow-all" } ], "DefaultCacheBehavior": { "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6", "Compress": true, - "TargetOriginId": "cloudfrontorigingroupDistributionOriginGroup10B57F1D1", + "TargetOriginId": "CustomGroupId", "ViewerProtocolPolicy": "allow-all" }, "Enabled": true, @@ -88,7 +88,7 @@ "Quantity": 4 } }, - "Id": "cloudfrontorigingroupDistributionOriginGroup10B57F1D1", + "Id": "CustomGroupId", "Members": { "Items": [ { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/integ.json index 4cb5d5dd14612..86c3632f16e0d 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/integ.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "39.0.0", "testCases": { "integ.origin-group": { "stacks": [ diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/manifest.json index cae445552b43d..e273430328a85 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "39.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "cloudfront-origin-group.assets": { "type": "cdk:asset-manifest", "properties": { @@ -20,10 +14,11 @@ "environment": "aws://unknown-account/unknown-region", "properties": { "templateFile": "cloudfront-origin-group.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}/d2914b9a230a95dad42d7412aa26c3c7e04ad03cd4bd32f66a9c6ef529559393.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/6cd6815fb994ed9d8e8f37329a05ba8fb469cbefa63ee221ecf52d045c1dcd63.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -77,6 +72,12 @@ ] }, "displayName": "cloudfront-origin-group" + }, + "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.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/tree.json index 53f0b95f4f806..3fe5cb426043c 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.js.snapshot/tree.json @@ -4,14 +4,6 @@ "id": "App", "path": "", "children": { - "Tree": { - "id": "Tree", - "path": "Tree", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" - } - }, "cloudfront-origin-group": { "id": "cloudfront-origin-group", "path": "cloudfront-origin-group", @@ -28,7 +20,7 @@ "aws:cdk:cloudformation:props": {} }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucket", + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", "version": "0.0.0" } }, @@ -79,19 +71,19 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.CfnBucketPolicy", + "fqn": "aws-cdk-lib.aws_s3.CfnBucketPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.BucketPolicy", + "fqn": "aws-cdk-lib.aws_s3.BucketPolicy", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-s3.Bucket", + "fqn": "aws-cdk-lib.aws_s3.Bucket", "version": "0.0.0" } }, @@ -119,28 +111,20 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-cloudfront.CfnCloudFrontOriginAccessIdentity", + "fqn": "aws-cdk-lib.aws_cloudfront.CfnCloudFrontOriginAccessIdentity", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-cloudfront.OriginAccessIdentity", + "fqn": "aws-cdk-lib.aws_cloudfront.OriginAccessIdentity", "version": "0.0.0" } } }, "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" - } - }, - "OriginGroup1": { - "id": "OriginGroup1", - "path": "cloudfront-origin-group/Distribution/OriginGroup1", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.4.2" } }, "Origin2": { @@ -148,7 +132,7 @@ "path": "cloudfront-origin-group/Distribution/Origin2", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.4.2" } }, "Resource": { @@ -207,7 +191,7 @@ "quantity": 4 } }, - "id": "cloudfrontorigingroupDistributionOriginGroup10B57F1D1", + "id": "CustomGroupId", "members": { "items": [ { @@ -225,7 +209,7 @@ }, "defaultCacheBehavior": { "pathPattern": "*", - "targetOriginId": "cloudfrontorigingroupDistributionOriginGroup10B57F1D1", + "targetOriginId": "CustomGroupId", "cachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6", "compress": true, "viewerProtocolPolicy": "allow-all" @@ -233,7 +217,7 @@ "cacheBehaviors": [ { "pathPattern": "/api", - "targetOriginId": "cloudfrontorigingroupDistributionOriginGroup10B57F1D1", + "targetOriginId": "CustomGroupId", "cachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6", "compress": true, "viewerProtocolPolicy": "allow-all" @@ -245,26 +229,50 @@ } }, "constructInfo": { - "fqn": "@aws-cdk/aws-cloudfront.CfnDistribution", + "fqn": "aws-cdk-lib.aws_cloudfront.CfnDistribution", "version": "0.0.0" } } }, "constructInfo": { - "fqn": "@aws-cdk/aws-cloudfront.Distribution", + "fqn": "aws-cdk-lib.aws_cloudfront.Distribution", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "cloudfront-origin-group/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "cloudfront-origin-group/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", "version": "0.0.0" } } }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.4.2" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "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.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.ts index f9aedd3ab7384..94f0b47580eb0 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-cloudfront-origins/test/integ.origin-group.ts @@ -13,6 +13,7 @@ const bucket = new s3.Bucket(stack, 'Bucket', { const originGroup = new origins.OriginGroup({ primaryOrigin: new origins.S3Origin(bucket), fallbackOrigin: new origins.HttpOrigin('www.example.com'), + originId: 'CustomGroupId', }); new cloudfront.Distribution(stack, 'Distribution', { diff --git a/packages/aws-cdk-lib/aws-cloudfront-origins/README.md b/packages/aws-cdk-lib/aws-cloudfront-origins/README.md index 4a68683f2c64c..b7b279c15e22a 100644 --- a/packages/aws-cdk-lib/aws-cloudfront-origins/README.md +++ b/packages/aws-cdk-lib/aws-cloudfront-origins/README.md @@ -593,6 +593,7 @@ new cloudfront.Distribution(this, 'myDist', { fallbackOrigin: new origins.HttpOrigin('www.example.com'), // optional, defaults to: 500, 502, 503 and 504 fallbackStatusCodes: [404], + originId: 'myOriginGroup', }), }, }); 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..158ac955e8b60 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[]; + + /** + * A unique identifier for the origin. This value must be unique within the distribution. + * + * @default - an originId will be generated for you + */ + readonly originId?: string; } /** @@ -44,6 +51,7 @@ export class OriginGroup implements cloudfront.IOrigin { failoverOrigin: this.props.fallbackOrigin, statusCodes: this.props.fallbackStatusCodes, }, + originGroupId: this.props.originId, }; } } diff --git a/packages/aws-cdk-lib/aws-cloudfront-origins/test/origin-group.test.ts b/packages/aws-cdk-lib/aws-cloudfront-origins/test/origin-group.test.ts index 23337d50b4960..954923303209c 100644 --- a/packages/aws-cdk-lib/aws-cloudfront-origins/test/origin-group.test.ts +++ b/packages/aws-cdk-lib/aws-cloudfront-origins/test/origin-group.test.ts @@ -7,18 +7,21 @@ import * as origins from '../lib'; let stack: Stack; let bucket: s3.IBucket; let primaryOrigin: cloudfront.IOrigin; +let importedBucket: s3.IBucket; +let fallbackOrigin: cloudfront.IOrigin; beforeEach(() => { stack = new Stack(); bucket = new s3.Bucket(stack, 'Bucket'); primaryOrigin = new origins.S3Origin(bucket); + importedBucket = s3.Bucket.fromBucketName(stack, 'ImportedBucket', 'imported-bucket'); + fallbackOrigin = new origins.S3Origin(importedBucket); }); describe('Origin Groups', () => { test('correctly render the OriginGroups property of DistributionConfig', () => { - const failoverOrigin = new origins.S3Origin(s3.Bucket.fromBucketName(stack, 'ImportedBucket', 'imported-bucket')); const originGroup = new origins.OriginGroup({ primaryOrigin, - fallbackOrigin: failoverOrigin, + fallbackOrigin, fallbackStatusCodes: [500], }); @@ -95,10 +98,10 @@ describe('Origin Groups', () => { }); test('correctly render the OriginGroups property of DistributionConfig with originId set', () => { - const failoverOrigin = new origins.S3Origin(s3.Bucket.fromBucketName(stack, 'ImportedBucket', 'imported-bucket'), { originId: 'MyCustomOrigin1' }); + fallbackOrigin = new origins.S3Origin(importedBucket, { originId: 'MyCustomOrigin1' }); const originGroup = new origins.OriginGroup({ primaryOrigin, - fallbackOrigin: failoverOrigin, + fallbackOrigin, fallbackStatusCodes: [500], }); @@ -173,15 +176,117 @@ describe('Origin Groups', () => { }); }); + test('correctly render custom OriginGroup ID', () => { + const originGroupId = 'CustomOriginGroupId'; + const originGroup = new origins.OriginGroup({ + primaryOrigin, + fallbackOrigin, + fallbackStatusCodes: [500], + originId: originGroupId, + }); + + new cloudfront.Distribution(stack, 'Distribution', { + defaultBehavior: { origin: originGroup }, + }); + + const primaryOriginId = 'DistributionOrigin13547B94F'; + const failoverOriginId = 'DistributionOrigin2C85CC43B'; + Template.fromStack(stack).hasResourceProperties('AWS::CloudFront::Distribution', { + DistributionConfig: { + DefaultCacheBehavior: { + TargetOriginId: originGroupId, + }, + Origins: [ + { + Id: primaryOriginId, + }, + { + Id: failoverOriginId, + }, + ], + OriginGroups: { + Items: [ + { + Id: originGroupId, + Members: { + Items: [ + { OriginId: primaryOriginId }, + { OriginId: failoverOriginId }, + ], + Quantity: 2, + }, + }, + ], + Quantity: 1, + }, + }, + }); + }); + + test('originId cannot be duplicated by another Origin added after the OriginGroup', () => { + const duplicateOriginId = 'DuplicateOrigin'; + const originGroup = new origins.OriginGroup({ + primaryOrigin, + fallbackOrigin, + fallbackStatusCodes: [500], + originId: duplicateOriginId, + }); + const additionalOrigin = new origins.HttpOrigin('test', { originId: duplicateOriginId }); + + const distribution = new cloudfront.Distribution(stack, 'Distribution', { + defaultBehavior: { origin: originGroup }, + }); + + expect(() => { + distribution.addBehavior('/x', additionalOrigin); + }).toThrow(`Origin with id ${duplicateOriginId} already exists`); + }); + + test('originId cannot duplicate a previously added Origin', () => { + const duplicateOriginId = 'DuplicateOrigin'; + const originGroup = new origins.OriginGroup({ + primaryOrigin, + fallbackOrigin, + fallbackStatusCodes: [500], + originId: duplicateOriginId, + }); + + const distribution = new cloudfront.Distribution(stack, 'Distribution', { + defaultBehavior: { + origin: new origins.HttpOrigin('test', { originId: duplicateOriginId }), + }, + }); + + expect(() => { + distribution.addBehavior('/x', originGroup); + }).toThrow(`Origin with id ${duplicateOriginId} already exists`); + }); + + test('originId cannot duplicate primary Origin', () => { + const duplicateOriginId = 'DuplicateOrigin'; + primaryOrigin = new origins.S3Origin(bucket, { originId: duplicateOriginId }); + const originGroup = new origins.OriginGroup({ + primaryOrigin, + fallbackOrigin, + fallbackStatusCodes: [500], + originId: duplicateOriginId, + }); + + expect(() => { + new cloudfront.Distribution(stack, 'Distribution', { + defaultBehavior: { origin: originGroup }, + }); + }).toThrow(`OriginGroup id ${duplicateOriginId} duplicates the primary Origin id`); + }); + test('cannot have an Origin with their own failover configuration as the primary Origin', () => { - const failoverOrigin = new origins.S3Origin(s3.Bucket.fromBucketName(stack, 'ImportedBucket', 'imported-bucket')); const originGroup = new origins.OriginGroup({ primaryOrigin, - fallbackOrigin: failoverOrigin, + fallbackOrigin, }); const groupOfGroups = new origins.OriginGroup({ primaryOrigin: originGroup, - fallbackOrigin: failoverOrigin, + fallbackOrigin, }); expect(() => { @@ -194,7 +299,7 @@ describe('Origin Groups', () => { test('cannot have an Origin with their own failover configuration as the fallback Origin', () => { const originGroup = new origins.OriginGroup({ primaryOrigin, - fallbackOrigin: new origins.S3Origin(s3.Bucket.fromBucketName(stack, 'ImportedBucket', 'imported-bucket')), + fallbackOrigin, }); const groupOfGroups = new origins.OriginGroup({ primaryOrigin, @@ -209,10 +314,9 @@ describe('Origin Groups', () => { }); test('cannot have an empty array of fallbackStatusCodes', () => { - const failoverOrigin = new origins.S3Origin(s3.Bucket.fromBucketName(stack, 'ImportedBucket', 'imported-bucket')); const originGroup = new origins.OriginGroup({ primaryOrigin, - fallbackOrigin: failoverOrigin, + fallbackOrigin, fallbackStatusCodes: [], }); diff --git a/packages/aws-cdk-lib/aws-cloudfront/lib/distribution.ts b/packages/aws-cdk-lib/aws-cloudfront/lib/distribution.ts index 9bed65f41f48e..185e6ee0dbc45 100644 --- a/packages/aws-cdk-lib/aws-cloudfront/lib/distribution.ts +++ b/packages/aws-cdk-lib/aws-cloudfront/lib/distribution.ts @@ -89,7 +89,6 @@ export interface DistributionAttributes { interface BoundOrigin extends OriginBindOptions, OriginBindConfig { readonly origin: IOrigin; - readonly originGroupId?: string; } /** @@ -658,19 +657,16 @@ export class Distribution extends Resource implements IDistribution { const distributionId = this.distributionId; const originBindConfig = origin.bind(scope, { originId: generatedId, distributionId: Lazy.string({ produce: () => this.distributionId }) }); const originId = originBindConfig.originProperty?.id ?? generatedId; - const duplicateId = this.boundOrigins.find(boundOrigin => boundOrigin.originProperty?.id === originBindConfig.originProperty?.id); - if (duplicateId) { - throw new Error(`Origin with id ${duplicateId.originProperty?.id} already exists. OriginIds must be unique within a distribution`); - } if (!originBindConfig.failoverConfig) { - this.boundOrigins.push({ origin, originId, distributionId, ...originBindConfig }); + this.addBoundOrigin({ origin, originId, distributionId, ...originBindConfig }); } else { if (isFailoverOrigin) { throw new Error('An Origin cannot use an Origin with its own failover configuration as its fallback origin!'); } const groupIndex = this.originGroups.length + 1; - const originGroupId = Names.uniqueId(new Construct(this, `OriginGroup${groupIndex}`)).slice(-ORIGIN_ID_MAX_LENGTH); - this.boundOrigins.push({ origin, originId, distributionId, originGroupId, ...originBindConfig }); + const originGroupId = originBindConfig.originGroupId ?? + Names.uniqueId(new Construct(this, `OriginGroup${groupIndex}`)).slice(-ORIGIN_ID_MAX_LENGTH); + this.addBoundOrigin({ origin, originId, distributionId, ...originBindConfig, originGroupId }); const failoverOriginId = this.addOrigin(originBindConfig.failoverConfig.failoverOrigin, true); this.addOriginGroup(originGroupId, originBindConfig.failoverConfig.statusCodes, originId, failoverOriginId); @@ -680,6 +676,24 @@ export class Distribution extends Resource implements IDistribution { } } + private addBoundOrigin(boundOrigin: BoundOrigin) { + const { originId } = boundOrigin; + if (originId === boundOrigin.originGroupId) { + throw new Error(`OriginGroup id ${originId} duplicates the primary Origin id. OriginIds must be unique within a distribution`); + } + const duplicate = this.findDuplicateOriginId(originId) ?? this.findDuplicateOriginId(boundOrigin.originGroupId); + if (duplicate) { + throw new Error(`Origin with id ${duplicate} already exists. OriginIds must be unique within a distribution`); + } + this.boundOrigins.push(boundOrigin); + } + + private findDuplicateOriginId(originId: string | undefined): string | undefined { + const duplicate = originId && this.boundOrigins.some(boundOrigin => + boundOrigin.originId === originId || boundOrigin.originGroupId === originId); + return duplicate ? originId : undefined; + } + private addOriginGroup(originGroupId: string, statusCodes: number[] | undefined, originId: string, failoverOriginId: string): void { statusCodes = statusCodes ?? [500, 502, 503, 504]; if (statusCodes.length === 0) { diff --git a/packages/aws-cdk-lib/aws-cloudfront/lib/origin.ts b/packages/aws-cdk-lib/aws-cloudfront/lib/origin.ts index 041f296d20fef..4e21e8e99d868 100644 --- a/packages/aws-cdk-lib/aws-cloudfront/lib/origin.ts +++ b/packages/aws-cdk-lib/aws-cloudfront/lib/origin.ts @@ -33,6 +33,13 @@ export interface OriginBindConfig { * @default - nothing is returned */ readonly failoverConfig?: OriginFailoverConfig; + + /** + * The Origin ID, if this is an OriginGroup with an explicitly set ID. + * + * @default - nothing is returned + */ + readonly originGroupId?: string; } /**