Skip to content

Commit

Permalink
fix(opensearch): add I4I and R7GD to list of OpenSearch nodes not req…
Browse files Browse the repository at this point in the history
…uiring EBS volumes (#32592)

### Issue # (if applicable)

Closes #32070.
Closes #32138.

### Reason for this change
`I4I` and `R7GD` instances don't require ebs volumes.
But at the moment, a domain with `I4I` and `R7GD` instances cannot be deployed.


### Description of changes
Added `I4I` and `R7GD` to not requiring EBS volumes instances list.


### Describe any new or updated permissions being added
Add unit tests and integ tests.
<!— What new or updated IAM permissions are needed to support the changes being introduced ? -->


### Description of how you validated changes



### Checklist
- [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
mazyu36 authored Dec 23, 2024
1 parent cb985ba commit e364d2b
Show file tree
Hide file tree
Showing 7 changed files with 235 additions and 80 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Resources": {
"Domain66AC69E0": {
"Domain19FCBCB91": {
"Type": "AWS::OpenSearchService::Domain",
"Properties": {
"ClusterConfig": {
Expand All @@ -20,7 +20,65 @@
"EncryptionAtRestOptions": {
"Enabled": false
},
"EngineVersion": "OpenSearch_2.5",
"EngineVersion": "OpenSearch_2.17",
"LogPublishingOptions": {},
"NodeToNodeEncryptionOptions": {
"Enabled": false
}
},
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
},
"Domain2644FE48C": {
"Type": "AWS::OpenSearchService::Domain",
"Properties": {
"ClusterConfig": {
"DedicatedMasterEnabled": false,
"InstanceCount": 1,
"InstanceType": "i4i.xlarge.search",
"MultiAZWithStandbyEnabled": false,
"ZoneAwarenessEnabled": false
},
"DomainEndpointOptions": {
"EnforceHTTPS": false,
"TLSSecurityPolicy": "Policy-Min-TLS-1-0-2019-07"
},
"EBSOptions": {
"EBSEnabled": false
},
"EncryptionAtRestOptions": {
"Enabled": false
},
"EngineVersion": "OpenSearch_2.17",
"LogPublishingOptions": {},
"NodeToNodeEncryptionOptions": {
"Enabled": false
}
},
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
},
"Domain3BE108C7A": {
"Type": "AWS::OpenSearchService::Domain",
"Properties": {
"ClusterConfig": {
"DedicatedMasterEnabled": false,
"InstanceCount": 1,
"InstanceType": "r7gd.xlarge.search",
"MultiAZWithStandbyEnabled": false,
"ZoneAwarenessEnabled": false
},
"DomainEndpointOptions": {
"EnforceHTTPS": false,
"TLSSecurityPolicy": "Policy-Min-TLS-1-0-2019-07"
},
"EBSOptions": {
"EBSEnabled": false
},
"EncryptionAtRestOptions": {
"Enabled": false
},
"EngineVersion": "OpenSearch_2.17",
"LogPublishingOptions": {},
"NodeToNodeEncryptionOptions": {
"Enabled": false
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,24 @@ class TestStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);

// deploy the latest opensearch domain with instance store only (no EBS)
const domainProps: opensearch.DomainProps = {
removalPolicy: RemovalPolicy.DESTROY,
version: opensearch.EngineVersion.OPENSEARCH_2_5,
// specify the instance type that supports instance store
capacity: {
multiAzWithStandbyEnabled: false,
dataNodeInstanceType: 'i4g.large.search',
dataNodes: 1,
},
// force ebs configuration to be disabled
ebs: {
enabled: false,
},
};
const instanceTypes = ['i4g.large.search', 'i4i.xlarge.search', 'r7gd.xlarge.search'];

new opensearch.Domain(this, 'Domain', domainProps);
instanceTypes.forEach((instanceType, index) => {
new opensearch.Domain(this, `Domain${index + 1}`, {
removalPolicy: RemovalPolicy.DESTROY,
version: opensearch.EngineVersion.OPENSEARCH_2_17,
// specify the instance type that supports instance store
capacity: {
multiAzWithStandbyEnabled: false,
dataNodeInstanceType: instanceType,
dataNodes: 1,
},
// force ebs configuration to be disabled
ebs: {
enabled: false,
},
});
});
}
}

Expand Down
37 changes: 31 additions & 6 deletions packages/aws-cdk-lib/aws-opensearchservice/lib/domain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1574,10 +1574,24 @@ export class Domain extends DomainBase implements IDomain, ec2.IConnectable {
}
}

const unSupportEbsInstanceType = [
ec2.InstanceClass.I3,
ec2.InstanceClass.R6GD,
ec2.InstanceClass.I4G,
ec2.InstanceClass.I4I,
ec2.InstanceClass.IM4GN,
ec2.InstanceClass.R7GD,
];

const supportInstanceStorageInstanceType = [
ec2.InstanceClass.R3,
...unSupportEbsInstanceType,
];

// Validate against instance type restrictions, per
// https://docs.aws.amazon.com/opensearch-service/latest/developerguide/supported-instance-types.html
if (isSomeInstanceType('i3', 'r6gd', 'i4g', 'im4gn') && ebsEnabled) {
throw new Error('I3, R6GD, I4G, and IM4GN instance types do not support EBS storage volumes.');
if (isSomeInstanceType(...unSupportEbsInstanceType) && ebsEnabled) {
throw new Error(`${formatInstanceTypesList(unSupportEbsInstanceType, 'and')} instance types do not support EBS storage volumes.`);
}

if (isSomeInstanceType('m3', 'r3', 't2') && encryptionAtRestEnabled) {
Expand All @@ -1592,10 +1606,10 @@ export class Domain extends DomainBase implements IDomain, ec2.IConnectable {
throw new Error('T2 and T3 instance types do not support UltraWarm storage.');
}

// Only R3, I3, R6GD, I4G and IM4GN support instance storage, per
// Only R3, I3, R6GD, I4G, I4I, IM4GN and R7GD support instance storage, per
// https://aws.amazon.com/opensearch-service/pricing/
if (!ebsEnabled && !isEveryDatanodeInstanceType('r3', 'i3', 'r6gd', 'i4g', 'im4gn')) {
throw new Error('EBS volumes are required when using instance types other than R3, I3, R6GD, I4G, or IM4GN.');
if (!ebsEnabled && !isEveryDatanodeInstanceType(...supportInstanceStorageInstanceType)) {
throw new Error(`EBS volumes are required when using instance types other than ${formatInstanceTypesList(supportInstanceStorageInstanceType, 'or')}.`);
}

// Only for a valid ebs volume configuration, per
Expand Down Expand Up @@ -1898,7 +1912,7 @@ export class Domain extends DomainBase implements IDomain, ec2.IConnectable {
identityPoolId: props.cognitoDashboardsAuth?.identityPoolId,
roleArn: props.cognitoDashboardsAuth?.role.roleArn,
userPoolId: props.cognitoDashboardsAuth?.userPoolId,
}: undefined,
} : undefined,
vpcOptions: cfnVpcOptions,
snapshotOptions: props.automatedSnapshotStartHour
? { automatedSnapshotStartHour: props.automatedSnapshotStartHour }
Expand Down Expand Up @@ -2188,3 +2202,14 @@ function initializeInstanceType(defaultInstanceType: string, instanceType?: stri
return defaultInstanceType;
}
}

/**
* Format instance types list for error messages.
*
* @param instanceTypes List of instance types to format
* @param conjunction Word to use as the conjunction (e.g., 'and', 'or')
* @returns Formatted instance types list for error messages
*/
function formatInstanceTypesList(instanceTypes: string[], conjunction: string): string {
return instanceTypes.map((type) => type.toUpperCase()).join(', ').replace(/, ([^,]*)$/, ` ${conjunction} $1`);
}
Loading

0 comments on commit e364d2b

Please sign in to comment.