diff --git a/packages/@aws-cdk/aws-elasticsearch/lib/domain.ts b/packages/@aws-cdk/aws-elasticsearch/lib/domain.ts index 14c41d3447395..a712e6091fbf4 100644 --- a/packages/@aws-cdk/aws-elasticsearch/lib/domain.ts +++ b/packages/@aws-cdk/aws-elasticsearch/lib/domain.ts @@ -1403,9 +1403,8 @@ export class Domain extends DomainBase implements IDomain, ec2.IConnectable { return instanceTypes.some(isInstanceType); }; - function isEveryInstanceType(...instanceTypes: string[]): Boolean { - return instanceTypes.some(t => dedicatedMasterType.startsWith(t)) - && instanceTypes.some(t => instanceType.startsWith(t)); + function isEveryDatanodeInstanceType(...instanceTypes: string[]): Boolean { + return instanceTypes.some(t => instanceType.startsWith(t)); }; // Validate feature support for the given Elasticsearch version, per @@ -1464,7 +1463,7 @@ export class Domain extends DomainBase implements IDomain, ec2.IConnectable { // Only R3, I3 and r6gd support instance storage, per // https://aws.amazon.com/elasticsearch-service/pricing/ - if (!ebsEnabled && !isEveryInstanceType('r3', 'i3', 'r6gd')) { + if (!ebsEnabled && !isEveryDatanodeInstanceType('r3', 'i3', 'r6gd')) { throw new Error('EBS volumes are required when using instance types other than r3, i3 or r6gd.'); } diff --git a/packages/@aws-cdk/aws-elasticsearch/test/domain.test.ts b/packages/@aws-cdk/aws-elasticsearch/test/domain.test.ts index a6291f0af7685..4b1a935800d42 100644 --- a/packages/@aws-cdk/aws-elasticsearch/test/domain.test.ts +++ b/packages/@aws-cdk/aws-elasticsearch/test/domain.test.ts @@ -1437,7 +1437,7 @@ describe('custom error responses', () => { })).toThrow(/Node-to-node encryption requires Elasticsearch version 6.0 or later/); }); - test('error when i3 instance types are specified with EBS enabled', () => { + test('error when i3 or r6g instance types are specified with EBS enabled', () => { expect(() => new Domain(stack, 'Domain1', { version: ElasticsearchVersion.V7_4, capacity: { @@ -1448,6 +1448,16 @@ describe('custom error responses', () => { volumeType: EbsDeviceVolumeType.GENERAL_PURPOSE_SSD, }, })).toThrow(/I3 and R6GD instance types do not support EBS storage volumes/); + expect(() => new Domain(stack, 'Domain2', { + version: ElasticsearchVersion.V7_4, + capacity: { + dataNodeInstanceType: 'r6gd.large.elasticsearch', + }, + ebs: { + volumeSize: 100, + volumeType: EbsDeviceVolumeType.GENERAL_PURPOSE_SSD, + }, + })).toThrow(/I3 and R6GD instance types do not support EBS storage volumes/); }); test('error when m3, r3, or t2 instance types are specified with encryption at rest enabled', () => { @@ -1500,6 +1510,41 @@ describe('custom error responses', () => { masterNodeInstanceType: 'm5.large.elasticsearch', }, })).toThrow(/EBS volumes are required when using instance types other than r3, i3 or r6gd/); + expect(() => new Domain(stack, 'Domain2', { + version: ElasticsearchVersion.V7_4, + ebs: { + enabled: false, + }, + capacity: { + dataNodeInstanceType: 'm5.large.elasticsearch', + }, + })).toThrow(/EBS volumes are required when using instance types other than r3, i3 or r6gd/); + }); + + test('can use compatible master instance types that does not have local storage when data node type is i3 or r6gd', () => { + new Domain(stack, 'Domain1', { + version: ElasticsearchVersion.V7_4, + ebs: { + enabled: false, + }, + capacity: { + masterNodeInstanceType: 'c5.2xlarge.elasticsearch', + dataNodeInstanceType: 'i3.2xlarge.elasticsearch', + }, + }); + new Domain(stack, 'Domain2', { + version: ElasticsearchVersion.V7_4, + ebs: { + enabled: false, + }, + capacity: { + masterNodes: 3, + masterNodeInstanceType: 'c6g.large.elasticsearch', + dataNodeInstanceType: 'r6gd.large.elasticsearch', + }, + }); + // both configurations pass synth-time validation + expect(stack).toCountResources('AWS::Elasticsearch::Domain', 2); }); test('error when availabilityZoneCount is not 2 or 3', () => { diff --git a/packages/@aws-cdk/aws-opensearchservice/lib/domain.ts b/packages/@aws-cdk/aws-opensearchservice/lib/domain.ts index 3d5eebb6f32d6..8ac9ace6ba0de 100644 --- a/packages/@aws-cdk/aws-opensearchservice/lib/domain.ts +++ b/packages/@aws-cdk/aws-opensearchservice/lib/domain.ts @@ -1320,9 +1320,8 @@ export class Domain extends DomainBase implements IDomain, ec2.IConnectable { return instanceTypes.some(isInstanceType); }; - function isEveryInstanceType(...instanceTypes: string[]): Boolean { - return instanceTypes.some(t => dedicatedMasterType.startsWith(t)) - && instanceTypes.some(t => instanceType.startsWith(t)); + function isEveryDatanodeInstanceType(...instanceTypes: string[]): Boolean { + return instanceTypes.some(t => instanceType.startsWith(t)); }; // Validate feature support for the given Elasticsearch/OpenSearch version, per @@ -1396,7 +1395,7 @@ export class Domain extends DomainBase implements IDomain, ec2.IConnectable { // Only R3, I3 and r6gd support instance storage, per // https://aws.amazon.com/opensearch-service/pricing/ - if (!ebsEnabled && !isEveryInstanceType('r3', 'i3', 'r6gd')) { + if (!ebsEnabled && !isEveryDatanodeInstanceType('r3', 'i3', 'r6gd')) { throw new Error('EBS volumes are required when using instance types other than r3, i3 or r6gd.'); } diff --git a/packages/@aws-cdk/aws-opensearchservice/test/domain.test.ts b/packages/@aws-cdk/aws-opensearchservice/test/domain.test.ts index 5b190e2b71a5c..f714fade3f4e5 100644 --- a/packages/@aws-cdk/aws-opensearchservice/test/domain.test.ts +++ b/packages/@aws-cdk/aws-opensearchservice/test/domain.test.ts @@ -1439,7 +1439,7 @@ describe('custom error responses', () => { })).toThrow(/Node-to-node encryption requires Elasticsearch version 6.0 or later or OpenSearch version 1.0 or later/); }); - test('error when i3 instance types are specified with EBS enabled', () => { + test('error when i3 or r6g instance types are specified with EBS enabled', () => { expect(() => new Domain(stack, 'Domain1', { version: defaultVersion, capacity: { @@ -1450,6 +1450,16 @@ describe('custom error responses', () => { volumeType: EbsDeviceVolumeType.GENERAL_PURPOSE_SSD, }, })).toThrow(/I3 and R6GD instance types do not support EBS storage volumes/); + expect(() => new Domain(stack, 'Domain2', { + version: defaultVersion, + capacity: { + dataNodeInstanceType: 'r6gd.large.search', + }, + ebs: { + volumeSize: 100, + volumeType: EbsDeviceVolumeType.GENERAL_PURPOSE_SSD, + }, + })).toThrow(/I3 and R6GD instance types do not support EBS storage volumes/); }); test('error when m3, r3, or t2 instance types are specified with encryption at rest enabled', () => { @@ -1502,6 +1512,41 @@ describe('custom error responses', () => { masterNodeInstanceType: 'm5.large.search', }, })).toThrow(/EBS volumes are required when using instance types other than r3, i3 or r6gd/); + expect(() => new Domain(stack, 'Domain2', { + version: defaultVersion, + ebs: { + enabled: false, + }, + capacity: { + dataNodeInstanceType: 'm5.large.search', + }, + })).toThrow(/EBS volumes are required when using instance types other than r3, i3 or r6gd/); + }); + + test('can use compatible master instance types that does not have local storage when data node type is i3 or r6gd', () => { + new Domain(stack, 'Domain1', { + version: defaultVersion, + ebs: { + enabled: false, + }, + capacity: { + masterNodeInstanceType: 'c5.2xlarge.search', + dataNodeInstanceType: 'i3.2xlarge.search', + }, + }); + new Domain(stack, 'Domain2', { + version: defaultVersion, + ebs: { + enabled: false, + }, + capacity: { + masterNodes: 3, + masterNodeInstanceType: 'c6g.large.search', + dataNodeInstanceType: 'r6gd.large.search', + }, + }); + // both configurations pass synth-time validation + expect(stack).toCountResources('AWS::OpenSearchService::Domain', 2); }); test('error when availabilityZoneCount is not 2 or 3', () => {