Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(opensearchservice): L2 properties for offPeakWindowOptions and softwareUpdateOptions #26403

Merged
merged 11 commits into from
Jul 27, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@
"LogPublishingOptions": {},
"NodeToNodeEncryptionOptions": {
"Enabled": true
},
"OffPeakWindowOptions": {
"Enabled": true,
"OffPeakWindow": {
"WindowStartTime": {
"Hours": 0,
"Minutes": 0
}
}
}
},
"UpdateReplacePolicy": "Delete",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@
"LogPublishingOptions": {},
"NodeToNodeEncryptionOptions": {
"Enabled": true
},
"OffPeakWindowOptions": {
"Enabled": true,
"OffPeakWindow": {
"WindowStartTime": {
"Hours": 0,
"Minutes": 0
}
}
}
},
"UpdateReplacePolicy": "Delete",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,15 @@
"LogPublishingOptions": {},
"NodeToNodeEncryptionOptions": {
"Enabled": false
},
"OffPeakWindowOptions": {
"Enabled": true,
"OffPeakWindow": {
"WindowStartTime": {
"Hours": 0,
"Minutes": 0
}
}
}
},
"UpdateReplacePolicy": "Delete",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@
"LogPublishingOptions": {},
"NodeToNodeEncryptionOptions": {
"Enabled": false
},
"OffPeakWindowOptions": {
"Enabled": true,
"OffPeakWindow": {
"WindowStartTime": {
"Hours": 0,
"Minutes": 0
}
}
}
},
"UpdateReplacePolicy": "Delete",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,18 @@
},
"NodeToNodeEncryptionOptions": {
"Enabled": true
},
"OffPeakWindowOptions": {
"Enabled": true,
"OffPeakWindow": {
"WindowStartTime": {
"Hours": 20,
"Minutes": 0
}
}
},
"SoftwareUpdateOptions": {
"AutoSoftwareUpdateEnabled": true
}
},
"DependsOn": [
Expand Down Expand Up @@ -458,6 +470,18 @@
},
"NodeToNodeEncryptionOptions": {
"Enabled": true
},
"OffPeakWindowOptions": {
"Enabled": true,
"OffPeakWindow": {
"WindowStartTime": {
"Hours": 20,
"Minutes": 0
}
}
},
"SoftwareUpdateOptions": {
"AutoSoftwareUpdateEnabled": true
}
},
"DependsOn": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@
"LogPublishingOptions": {},
"NodeToNodeEncryptionOptions": {
"Enabled": false
},
"OffPeakWindowOptions": {
"Enabled": true,
"OffPeakWindow": {
"WindowStartTime": {
"Hours": 0,
"Minutes": 0
}
}
}
},
"UpdateReplacePolicy": "Delete",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@
"LogPublishingOptions": {},
"NodeToNodeEncryptionOptions": {
"Enabled": false
},
"OffPeakWindowOptions": {
"Enabled": true,
"OffPeakWindow": {
"WindowStartTime": {
"Hours": 0,
"Minutes": 0
}
}
}
},
"UpdateReplacePolicy": "Delete",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ class TestStack extends Stack {
capacity: {
multiAzWithStandbyEnabled: false,
},
offPeakWindowOptions: {
enabled: true,
offPeakWindow: {
windowStartTime: {
hours: 20,
minutes: 0,
},
},
},
softwareUpdateOptions: {
autoSoftwareUpdateEnabled: true,
},
};

// create 2 domains to ensure that Cloudwatch Log Group policy names dont conflict
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@
"LogPublishingOptions": {},
"NodeToNodeEncryptionOptions": {
"Enabled": false
},
"OffPeakWindowOptions": {
"Enabled": true,
"OffPeakWindow": {
"WindowStartTime": {
"Hours": 0,
"Minutes": 0
}
}
}
},
"UpdateReplacePolicy": "Delete",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@
"LogPublishingOptions": {},
"NodeToNodeEncryptionOptions": {
"Enabled": true
},
"OffPeakWindowOptions": {
"Enabled": true,
"OffPeakWindow": {
"WindowStartTime": {
"Hours": 0,
"Minutes": 0
}
}
}
},
"UpdateReplacePolicy": "Delete",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,15 @@
"Ref": "VpcPrivateSubnet2Subnet3788AAA1"
}
]
},
"OffPeakWindowOptions": {
"Enabled": true,
"OffPeakWindow": {
"WindowStartTime": {
"Hours": 0,
"Minutes": 0
}
}
}
},
"DependsOn": [
Expand Down
36 changes: 36 additions & 0 deletions packages/aws-cdk-lib/aws-opensearchservice/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -396,4 +396,40 @@ const domain = new Domain(this, 'Domain', {
dataNodes: 3,
},
});
```

## Define off-peak windows

The domain can be configured to use a daily 10-hour window considered as off-peak hours.

> Visit [Defining off-peak windows for Amazon OpenSearch Service](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/off-peak.html) for more details.

```ts
const domain = new Domain(this, 'Domain', {
version: EngineVersion.OPENSEARCH_1_3,
offPeakWindowOptions: {
enabled: true,
offPeakWindow: {
windowStartTime: {
hours: 20,
minutes: 0,
},
},
},
});
```

## Configuring service software updates

The domain can be configured to use service software updates.

> Visit [Service software updates in Amazon OpenSearch Service](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/service-software.html) for more details.

```ts
const domain = new Domain(this, 'Domain', {
version: EngineVersion.OPENSEARCH_1_3,
softwareUpdateOptions: {
autoSoftwareUpdateEnabled: true,
},
});
```
107 changes: 107 additions & 0 deletions packages/aws-cdk-lib/aws-opensearchservice/lib/domain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,65 @@ export interface CustomEndpointOptions {
readonly hostedZone?: route53.IHostedZone;
}

export interface WindowStartTime {
/**
* The start hour of the window in Coordinated Universal Time (UTC), using 24-hour time.
* For example, 17 refers to 5:00 P.M. UTC.
*
* @default - 0
*/
readonly hours: number;
/**
* The start minute of the window, in UTC.
*
* @default - 0
*/
readonly minutes: number;
}

export interface OffPeakWindow {
/**
* A custom start time for the off-peak window, in Coordinated Universal Time (UTC).
* The window length will always be 10 hours, so you can't specify an end time.
* For example, if you specify 11:00 P.M. UTC as a start time, the end time will automatically be set to 9:00 A.M.
*
* @default - 00:00 UTC
*/
readonly windowStartTime?: WindowStartTime;
kaizencc marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Off-peak window settings for the domain.
* You can't disable the off-peak window for a domain after it's enabled.
*/
export interface OffPeakWindowOptions {
/**
* Specifies whether off-peak window settings are enabled for the domain.
*
* @default - true
*/
readonly enabled?: boolean;

/**
* Off-peak window settings for the domain.
*
* @default - default window start time is 00:00 UTC
*/
readonly offPeakWindow?: OffPeakWindow;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this to be an interface either. We should be able to get away with just offPeakWindow?: OffPeakWindow. If its specified, users probably want it to be enabled as well. In general I like to default to a single prop rather than specifying interfaces.

}

/**
* Options for configuring service software updates for a domain.
*/
export interface SoftwareUpdateOptions {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i dont think we need an interface for this, lets default to a flatter API. Think we should just expose a boolean enableAutoSoftwareUpdate

/**
* Specifies whether automatic service software updates are enabled for the domain.
*
* @default - automatic software updates are disabled
*/
readonly autoSoftwareUpdateEnabled?: boolean;
}

/**
* Properties for an Amazon OpenSearch Service domain.
*/
Expand Down Expand Up @@ -511,6 +570,21 @@ export interface DomainProps {
* @default - no custom domain endpoint will be configured
*/
readonly customEndpoint?: CustomEndpointOptions;

/**
* Options for a domain's off-peak window, during which OpenSearch Service can perform mandatory
* configuration changes on the domain.
*
* @default - off-peak window is enabled by default with 00:00 UTC start time.
*/
readonly offPeakWindowOptions?: OffPeakWindowOptions;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

specifically the default for this prop may be confusing. looks like the default should be that it is configured by default and cannot be turned off, but still, what will the default window be?

Off-peak windows were introduced on February 16, 2023. All domains created before this date have the off-peak window disabled by default. You must manually enable and configure the off-peak window for these domains. All domains created after this date will have the off-peak window enabled by default. You can't disable the off-peak window for a domain after it's enabled.

https://docs.aws.amazon.com/opensearch-service/latest/developerguide/off-peak.html

Copy link
Contributor Author

@lpizzinidev lpizzinidev Jul 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I defaulted it to 00:00 UTC

If you don't specify a custom window start time, it defaults to 00:00 UTC.

https://docs.aws.amazon.com/opensearch-service/latest/developerguide/off-peak.html (in Enabling the off-peak window > CLI)


/**
* Options for configuring service software updates for a domain.
*
* @default - no software updates configured for the domain
*/
readonly softwareUpdateOptions?: SoftwareUpdateOptions;
}

/**
Expand Down Expand Up @@ -1558,6 +1632,23 @@ export class Domain extends DomainBase implements IDomain, ec2.IConnectable {
}
}

let offPeakWindowOptions: OffPeakWindowOptions = {
enabled: props.offPeakWindowOptions?.enabled ?? true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All domains created before this date have the off-peak window disabled by default.

So we can't just default to true here, as that will represent a behavior change to existing domains. Rather, without setting offPeakWindow (i.e. offPeakWindow: undefined) what we have to do is document the service-level behavior (enabled post 2/16/23, disabled prior). Then, we just pass undefined into the L1 and let the service handle the default.

};
if (offPeakWindowOptions.enabled) {
offPeakWindowOptions = {
...offPeakWindowOptions,
offPeakWindow: {
windowStartTime: {
hours: props.offPeakWindowOptions?.offPeakWindow?.windowStartTime?.hours ?? 0,
minutes: props.offPeakWindowOptions?.offPeakWindow?.windowStartTime?.minutes ?? 0,
},
},
};
}

this.validateWindowStartTime(offPeakWindowOptions?.offPeakWindow?.windowStartTime);

// Create the domain
this.domain = new CfnDomain(this, 'Resource', {
domainName: this.physicalName,
Expand Down Expand Up @@ -1632,6 +1723,8 @@ export class Domain extends DomainBase implements IDomain, ec2.IConnectable {
}
: undefined,
advancedOptions: props.advancedOptions,
offPeakWindowOptions: offPeakWindowOptions,
softwareUpdateOptions: props.softwareUpdateOptions,
});
this.domain.applyRemovalPolicy(props.removalPolicy);

Expand Down Expand Up @@ -1689,6 +1782,20 @@ export class Domain extends DomainBase implements IDomain, ec2.IConnectable {
}
}

/**
* Validate windowStartTime property according to
* https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-opensearchservice-domain-windowstarttime.html
*/
private validateWindowStartTime(windowStartTime?: WindowStartTime) {
if (!windowStartTime) return;
if (windowStartTime.hours < 0 || windowStartTime.hours > 23) {
throw new Error(`Hours must be a value between 0 and 23, but got ${windowStartTime.hours}.`);
}
if (windowStartTime.minutes < 0 || windowStartTime.minutes > 59) {
throw new Error(`Minutes must be a value between 0 and 59, but got ${windowStartTime.minutes}.`);
}
}

/**
* Manages network connections to the domain. This will throw an error in case the domain
* is not placed inside a VPC.
Expand Down
Loading