-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(msk): support ServerlessCluster
- Loading branch information
Showing
14 changed files
with
3,331 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
{ | ||
"exclude": [ | ||
"props-physical-name:@aws-cdk/aws-msk-alpha.ServerlessClusterProps" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
export * from './cluster'; | ||
export * from './cluster-version'; | ||
export * from './serverless-cluster'; | ||
|
||
// AWS::MSK CloudFormation Resources: |
157 changes: 157 additions & 0 deletions
157
packages/@aws-cdk/aws-msk-alpha/lib/serverless-cluster.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
import * as ec2 from 'aws-cdk-lib/aws-ec2'; | ||
import { Fn, Lazy, Names, Token } from 'aws-cdk-lib'; | ||
import * as constructs from 'constructs'; | ||
import { ClusterBase, ICluster } from '.'; | ||
import { CfnServerlessCluster } from 'aws-cdk-lib/aws-msk'; | ||
|
||
/** | ||
* Properties for a MSK Serverless Cluster | ||
*/ | ||
export interface ServerlessClusterProps { | ||
/** | ||
* The physical name of the cluster. | ||
* | ||
* @default - auto generate | ||
*/ | ||
readonly clusterName?: string; | ||
|
||
/** | ||
* The configuration of the Amazon VPCs for the cluster. | ||
* You can specify up to 5 VPC configurations. | ||
*/ | ||
readonly vpcConfigs: VpcConfig[]; | ||
} | ||
|
||
/** | ||
* The configuration of the Amazon VPCs for the cluster. | ||
*/ | ||
export interface VpcConfig { | ||
/** | ||
* Defines the virtual networking environment for this cluster. | ||
* Must have at least 2 subnets in two different AZs. | ||
*/ | ||
readonly vpc: ec2.IVpc; | ||
|
||
/** | ||
* The subnets associated with the cluster. | ||
* | ||
* @default - the Vpc default strategy if not specified. | ||
*/ | ||
readonly vpcSubnets?: ec2.SubnetSelection; | ||
|
||
/** | ||
* The security groups associated with the cluster. | ||
* You can specify up to 5 security groups. | ||
* | ||
* @default - create new security group | ||
*/ | ||
readonly securityGroups?: ec2.ISecurityGroup[]; | ||
} | ||
|
||
/** | ||
* Create a MSK Serverless Cluster. | ||
* | ||
* @resource AWS::MSK::ServerlessCluster | ||
*/ | ||
export class ServerlessCluster extends ClusterBase { | ||
/** | ||
* Reference an existing cluster, defined outside of the CDK code, by name. | ||
*/ | ||
public static fromClusterArn( | ||
scope: constructs.Construct, | ||
id: string, | ||
clusterArn: string, | ||
): ICluster { | ||
class Import extends ClusterBase { | ||
public readonly clusterArn = clusterArn; | ||
public readonly clusterName = Fn.select(1, Fn.split('/', clusterArn)); // ['arn:partition:kafka:region:account-id', clusterName, clusterId] | ||
} | ||
|
||
return new Import(scope, id); | ||
} | ||
|
||
public readonly clusterArn: string; | ||
public readonly clusterName: string; | ||
|
||
private _securityGroups: ec2.ISecurityGroup[] = []; | ||
|
||
constructor(scope: constructs.Construct, id: string, props: ServerlessClusterProps) { | ||
if (!Token.isUnresolved(props.clusterName) && props.clusterName !== undefined) { | ||
if (!/^[a-zA-Z0-9]+$/.test(props.clusterName)) { | ||
throw Error(`The cluster name must only contain alphanumeric characters. got: ${props.clusterName}.`); | ||
} | ||
|
||
if (props.clusterName.length > 64) { | ||
throw Error(`The cluster name must not exceed 64 characters. got: ${props.clusterName.length} characters.`); | ||
} | ||
} | ||
|
||
super(scope, id, { | ||
physicalName: props.clusterName ?? | ||
Lazy.string({ | ||
produce: () => Names.uniqueResourceName(this, { maxLength: 64 }), | ||
}), | ||
}); | ||
|
||
if (props.vpcConfigs.length < 1 || props.vpcConfigs.length > 5) { | ||
throw Error(`\`vpcConfigs\` must contain between 1 and 5 configurations, got ${props.vpcConfigs.length} configurations.`); | ||
} | ||
|
||
const vpcConfigs = props.vpcConfigs.map((vpcConfig, index) => this._renderVpcConfig(vpcConfig, index)); | ||
|
||
this._connections = new ec2.Connections({ | ||
securityGroups: this._securityGroups, | ||
}); | ||
|
||
const resource = new CfnServerlessCluster(this, 'Resource', { | ||
clusterName: this.physicalName, | ||
clientAuthentication: { | ||
sasl: { | ||
iam: { | ||
enabled: true, | ||
}, | ||
}, | ||
}, | ||
vpcConfigs, | ||
}); | ||
|
||
this.clusterName = this.getResourceNameAttribute( | ||
Fn.select(1, Fn.split('/', resource.ref)), | ||
); | ||
this.clusterArn = resource.ref; | ||
} | ||
|
||
/** | ||
* Render Vpc Config property | ||
*/ | ||
private _renderVpcConfig(vpcConfig: VpcConfig, index: number): CfnServerlessCluster.VpcConfigProperty { | ||
const subnetSelection = vpcConfig.vpc.selectSubnets(vpcConfig.vpcSubnets); | ||
|
||
if (subnetSelection.subnets.length < 2) { | ||
throw Error( | ||
`Cluster requires at least 2 subnets, got ${subnetSelection.subnets.length}.`, | ||
); | ||
} | ||
|
||
let securityGroups: ec2.ISecurityGroup[] = []; | ||
|
||
if (vpcConfig.securityGroups) { | ||
if (vpcConfig.securityGroups.length > 5) { | ||
throw Error(`\`securityGroups\` must not exceed 5 elements, got ${vpcConfig.securityGroups.length} elements.`); | ||
} | ||
securityGroups = vpcConfig.securityGroups; | ||
} else { | ||
securityGroups.push(new ec2.SecurityGroup(this, `SecurityGroup-${index}`, { | ||
description: 'MSK Serverless security group', | ||
vpc: vpcConfig.vpc, | ||
})); | ||
} | ||
|
||
this._securityGroups.push(...securityGroups); | ||
|
||
return { | ||
subnetIds: subnetSelection.subnets.map((subnet) => subnet.subnetId), | ||
securityGroups: securityGroups?.map((securityGroup) => securityGroup.securityGroupId), | ||
}; | ||
} | ||
} |
1 change: 1 addition & 0 deletions
1
packages/@aws-cdk/aws-msk-alpha/test/integ.serverless-cluster.js.snapshot/cdk.out
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
12 changes: 12 additions & 0 deletions
12
packages/@aws-cdk/aws-msk-alpha/test/integ.serverless-cluster.js.snapshot/integ.json
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.