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

Alb diagrams #726

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
73227a1
Add create-acm-cert to CDK
AndreKurait May 24, 2024
c503cf8
Add ALB deployment to CDK
AndreKurait May 24, 2024
2db8c9e
add support for ALB and target cluster proxy
AndreKurait May 24, 2024
328a69f
Add Target Cluster Proxy
AndreKurait May 24, 2024
c6c244c
Update ALB configuration
AndreKurait Jun 7, 2024
a7d8023
Update target proxy with sg
AndreKurait Jun 7, 2024
ec817b2
Fix alb passing in cdk
AndreKurait Jun 7, 2024
0a74ee4
Add support for unauthenticated healthcheck
AndreKurait Jun 7, 2024
a0e09e9
Streamline peer and dev dependencies in cdk
AndreKurait Jun 7, 2024
70e2c38
add https for capture-proxy-stack
AndreKurait Jun 10, 2024
86d8a3c
Update package-lock.json
AndreKurait Jun 10, 2024
c6a6a9e
Update cdk options.md for create-acm-cert script
AndreKurait Jun 10, 2024
c5e691f
Remove expectUnauthenticatedHealthcheck
AndreKurait Jun 10, 2024
5a93bff
Inline acm cert creation into cdk
AndreKurait Jun 11, 2024
95b6058
Update acm cert log group removal policy
AndreKurait Jun 11, 2024
84332cc
Create default migrateable listener
AndreKurait Jun 11, 2024
8c65864
Initial restructuring for alb
AndreKurait Jun 11, 2024
e98b738
Add passing es service url
AndreKurait Jun 11, 2024
5aaa035
Fix source cluster endpoint
AndreKurait Jun 11, 2024
f1e43c9
Export var
AndreKurait Jun 11, 2024
f6888e2
Fix export
AndreKurait Jun 11, 2024
188e609
Refactor SSM parameters
AndreKurait Jun 11, 2024
247874f
Refactor SSM Parameters
AndreKurait Jun 12, 2024
f827e81
Fix log stream
AndreKurait Jun 12, 2024
d068f51
Address PR Comments
AndreKurait Jun 17, 2024
444d539
Simplify sourceClusterEndpoint through ssm parameters
AndreKurait Jun 17, 2024
bf2aaa5
Improve descriptions in options.md
AndreKurait Jun 17, 2024
8883503
Update package-lock.json
AndreKurait Jun 17, 2024
0bbe679
Add ALB Diagrams
AndreKurait Jun 18, 2024
795166b
Test
AndreKurait Jun 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions deployment/cdk/opensearch-service-migration/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ dist
# CDK asset staging directory
.cdk.staging
cdk.out
certs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
"trafficReplayerEnableClusterFGACAuth": true,
"captureProxyESServiceEnabled": true,
"fetchMigrationEnabled": true,
"otelCollectorEnabled": true,
"sourceClusterEndpoint": "https://capture-proxy-es.migration.dev.local:19200"
"otelCollectorEnabled": true
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import {Effect, PolicyStatement, Role, ServicePrincipal} from "aws-cdk-lib/aws-iam";
import {Construct} from "constructs";
import {StringParameter} from "aws-cdk-lib/aws-ssm";
import {CpuArchitecture} from "aws-cdk-lib/aws-ecs";
import {RemovalPolicy} from "aws-cdk-lib";
import { IApplicationLoadBalancer } from "aws-cdk-lib/aws-elasticloadbalancingv2";
import { ICertificate } from "aws-cdk-lib/aws-certificatemanager";
import { IStringParameter, StringParameter } from "aws-cdk-lib/aws-ssm";

export function createOpenSearchIAMAccessPolicy(partition: string, region: string, accountId: string): PolicyStatement {
return new PolicyStatement({
Expand All @@ -25,8 +27,8 @@ export function createOpenSearchServerlessIAMAccessPolicy(partition: string, reg
}

export function createMSKConsumerIAMPolicies(scope: Construct, partition: string, region: string, accountId: string, stage: string, deployId: string): PolicyStatement[] {
const mskClusterARN = StringParameter.valueForStringParameter(scope, `/migration/${stage}/${deployId}/mskClusterARN`);
const mskClusterName = StringParameter.valueForStringParameter(scope, `/migration/${stage}/${deployId}/mskClusterName`);
const mskClusterARN = getMigrationStringParameterValue(scope, { parameter: MigrationSSMParameter.MSK_CLUSTER_ARN, stage, defaultDeployId: deployId });
const mskClusterName = getMigrationStringParameterValue(scope, { parameter: MigrationSSMParameter.MSK_CLUSTER_NAME, stage, defaultDeployId: deployId });
const mskClusterConnectPolicy = new PolicyStatement({
effect: Effect.ALLOW,
resources: [mskClusterARN],
Expand Down Expand Up @@ -57,8 +59,8 @@ export function createMSKConsumerIAMPolicies(scope: Construct, partition: string
}

export function createMSKProducerIAMPolicies(scope: Construct, partition: string, region: string, accountId: string, stage: string, deployId: string): PolicyStatement[] {
const mskClusterARN = StringParameter.valueForStringParameter(scope, `/migration/${stage}/${deployId}/mskClusterARN`);
const mskClusterName = StringParameter.valueForStringParameter(scope, `/migration/${stage}/${deployId}/mskClusterName`);
const mskClusterARN = getMigrationStringParameterValue(scope, { parameter: MigrationSSMParameter.MSK_CLUSTER_ARN, stage, defaultDeployId: deployId });
const mskClusterName = getMigrationStringParameterValue(scope, { parameter: MigrationSSMParameter.MSK_CLUSTER_NAME, stage, defaultDeployId: deployId });
const mskClusterConnectPolicy = new PolicyStatement({
effect: Effect.ALLOW,
resources: [mskClusterARN],
Expand Down Expand Up @@ -149,4 +151,75 @@ export function parseRemovalPolicy(optionName: string, policyNameString?: string
throw new Error(`Provided '${optionName}' with value '${policyNameString}' does not match a selectable option, for reference https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.RemovalPolicy.html`)
}
return policy
}
}


export type ALBConfig = NewALBListenerConfig;

export interface NewALBListenerConfig {
alb: IApplicationLoadBalancer,
albListenerCert: ICertificate,
albListenerPort?: number,
}

export function isNewALBListenerConfig(config: ALBConfig): config is NewALBListenerConfig {
const parsed = config as NewALBListenerConfig;
return parsed.alb !== undefined && parsed.albListenerCert !== undefined;
}


export interface MigrationSSMConfig {
parameter: MigrationSSMParameter,
stage: string,
defaultDeployId: string
}

export function createMigrationStringParameter(scope: Construct, stringValue: string, props: MigrationSSMConfig) {
return new StringParameter(scope, `SSMParameter${props.parameter.charAt(0).toUpperCase() + props.parameter.slice(1)}`, {
parameterName: getMigrationStringParameterName(props),
stringValue: stringValue,
description: `Opensearch migration SSM parameter for ${props.parameter} with stage ${props.stage} and deploy id ${props.defaultDeployId}`,
});
}

export function getMigrationStringParameter(scope: Construct, props: MigrationSSMConfig): IStringParameter {
return StringParameter.fromStringParameterName(scope, `SSMParameter${props.parameter.charAt(0).toUpperCase() + props.parameter.slice(1)}`,
getMigrationStringParameterName(props));
}

export function getMigrationStringParameterValue(scope: Construct, props: MigrationSSMConfig): string {
return StringParameter.valueForTypedStringParameterV2(scope, getMigrationStringParameterName(props));
}

export function getCustomStringParameterValue(scope: Construct, parameterName: string): string {
return StringParameter.valueForTypedStringParameterV2(scope, parameterName);
}

export function getMigrationStringParameterName(props: MigrationSSMConfig): string {
return `/migration/${props.stage}/${props.defaultDeployId}/${props.parameter}`;
}

export enum MigrationSSMParameter {
ALB_MIGRATION_URL = 'albMigrationUrl',
ARTIFACT_S3_ARN = 'artifactS3Arn',
CLOUD_MAP_NAMESPACE_ID = 'cloudMapNamespaceId',
FETCH_MIGRATION_COMMAND = 'fetchMigrationCommand',
FETCH_MIGRATION_TASK_DEF_ARN = 'fetchMigrationTaskDefArn',
FETCH_MIGRATION_TASK_EXEC_ROLE_ARN = 'fetchMigrationTaskExecRoleArn',
FETCH_MIGRATION_TASK_ROLE_ARN = 'fetchMigrationTaskRoleArn',
KAFKA_BROKERS = 'kafkaBrokers',
MSK_CLUSTER_ARN = 'mskClusterARN',
MSK_CLUSTER_NAME = 'mskClusterName',
OS_ACCESS_SECURITY_GROUP_ID = 'osAccessSecurityGroupId',
OS_CLUSTER_ENDPOINT = 'osClusterEndpoint',
OS_USER_AND_SECRET_ARN = 'osUserAndSecretArn',
OSI_PIPELINE_LOG_GROUP_NAME = 'osiPipelineLogGroupName',
OSI_PIPELINE_ROLE_ARN = 'osiPipelineRoleArn',
REPLAYER_OUTPUT_ACCESS_SECURITY_GROUP_ID = 'replayerOutputAccessSecurityGroupId',
REPLAYER_OUTPUT_EFS_ID = 'replayerOutputEfsId',
SOURCE_CLUSTER_ENDPOINT = 'sourceClusterEndpoint',
SERVICE_SECURITY_GROUP_ID = 'serviceSecurityGroupId',
SERVICES_YAML_FILE = 'servicesYamlFile',
TRAFFIC_STREAM_SOURCE_ACCESS_SECURITY_GROUP_ID = 'trafficStreamSourceAccessSecurityGroupId',
VPC_ID = 'vpcId',
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Stack, SecretValue} from "aws-cdk-lib";
import {SecretValue, Stack} from "aws-cdk-lib";
import {IVpc} from "aws-cdk-lib/aws-ec2";
import {Construct} from "constructs";
import {
Expand All @@ -12,35 +12,49 @@ import {Secret as SMSecret} from "aws-cdk-lib/aws-secretsmanager";
import {join} from "path";
import {readFileSync} from "fs"
import {StackPropsExt} from "./stack-composer";
import {StringParameter} from "aws-cdk-lib/aws-ssm";
import {
MigrationSSMParameter,
createDefaultECSTaskRole,
createMigrationStringParameter,
createOpenSearchIAMAccessPolicy,
createOpenSearchServerlessIAMAccessPolicy
createOpenSearchServerlessIAMAccessPolicy,
getMigrationStringParameter,
getMigrationStringParameterValue
} from "./common-utilities";

export interface FetchMigrationProps extends StackPropsExt {
readonly vpc: IVpc,
readonly dpPipelineTemplatePath: string,
readonly sourceEndpoint: string,
readonly fargateCpuArch: CpuArchitecture
}

export class FetchMigrationStack extends Stack {

constructor(scope: Construct, id: string, props: FetchMigrationProps) {
super(scope, id, props);
const sourceEndpoint = getMigrationStringParameterValue(this, {
...props,
parameter: MigrationSSMParameter.SOURCE_CLUSTER_ENDPOINT,
});

// Import required values
const targetClusterEndpoint = StringParameter.fromStringParameterName(this, "targetClusterEndpoint", `/migration/${props.stage}/${props.defaultDeployId}/osClusterEndpoint`)
const domainAccessGroupId = StringParameter.valueForStringParameter(this, `/migration/${props.stage}/${props.defaultDeployId}/osAccessSecurityGroupId`)
const targetClusterEndpoint = getMigrationStringParameter(this, {
...props,
parameter: MigrationSSMParameter.OS_CLUSTER_ENDPOINT,
});
const domainAccessGroupId = getMigrationStringParameterValue(this, {
...props,
parameter: MigrationSSMParameter.OS_ACCESS_SECURITY_GROUP_ID,
});
// This SG allows outbound access for ECR access as well as communication with other services in the cluster
const serviceGroupId = StringParameter.valueForStringParameter(this, `/migration/${props.stage}/${props.defaultDeployId}/serviceSecurityGroupId`)

const serviceGroupId = getMigrationStringParameterValue(this, {
...props,
parameter: MigrationSSMParameter.SERVICE_SECURITY_GROUP_ID,
});
const ecsCluster = Cluster.fromClusterAttributes(this, 'ecsCluster', {
clusterName: `migration-${props.stage}-ecs-cluster`,
vpc: props.vpc
})
});

const serviceName = "fetch-migration"
const ecsTaskRole = createDefaultECSTaskRole(this, serviceName)
Expand All @@ -60,22 +74,18 @@ export class FetchMigrationStack extends Stack {
taskRole: ecsTaskRole
});

new StringParameter(this, 'SSMParameterFetchMigrationTaskDefArn', {
description: 'OpenSearch Migration Parameter for Fetch Migration task definition ARN',
parameterName: `/migration/${props.stage}/${props.defaultDeployId}/fetchMigrationTaskDefArn`,
stringValue: fetchMigrationFargateTask.taskDefinitionArn
createMigrationStringParameter(this, fetchMigrationFargateTask.taskDefinitionArn, {
...props,
parameter: MigrationSSMParameter.FETCH_MIGRATION_TASK_DEF_ARN,
});
new StringParameter(this, 'SSMParameterFetchMigrationTaskRoleArn', {
description: 'OpenSearch Migration Parameter for Fetch Migration task role ARN',
parameterName: `/migration/${props.stage}/${props.defaultDeployId}/fetchMigrationTaskRoleArn`,
stringValue: fetchMigrationFargateTask.taskRole.roleArn
createMigrationStringParameter(this, fetchMigrationFargateTask.taskRole.roleArn, {
...props,
parameter: MigrationSSMParameter.FETCH_MIGRATION_TASK_ROLE_ARN,
});
new StringParameter(this, 'SSMParameterFetchMigrationTaskExecRoleArn', {
description: 'OpenSearch Migration Parameter for Fetch Migration task exec role ARN',
parameterName: `/migration/${props.stage}/${props.defaultDeployId}/fetchMigrationTaskExecRoleArn`,
stringValue: fetchMigrationFargateTask.obtainExecutionRole().roleArn
createMigrationStringParameter(this, fetchMigrationFargateTask.obtainExecutionRole().roleArn, {
...props,
parameter: MigrationSSMParameter.FETCH_MIGRATION_TASK_EXEC_ROLE_ARN,
});

// Create Fetch Migration Container
const fetchMigrationContainer = fetchMigrationFargateTask.addContainer("fetchMigrationContainer", {
image: ContainerImage.fromAsset(join(__dirname, "../../../..", "FetchMigration")),
Expand All @@ -86,7 +96,7 @@ export class FetchMigrationStack extends Stack {
// Create DP pipeline config from template file
let dpPipelineData: string = readFileSync(props.dpPipelineTemplatePath, 'utf8');
// Replace only source cluster host - target host will be overridden by inline env var
dpPipelineData = dpPipelineData.replace("<SOURCE_CLUSTER_HOST>", props.sourceEndpoint);
dpPipelineData = dpPipelineData.replace("<SOURCE_CLUSTER_HOST>", sourceEndpoint);
// Base64 encode
let encodedPipeline = Buffer.from(dpPipelineData).toString("base64");

Expand Down Expand Up @@ -115,10 +125,9 @@ export class FetchMigrationStack extends Stack {
executionCommand += ` --cluster ${ecsCluster.clusterName} --launch-type FARGATE`
executionCommand += ` --network-configuration '${networkConfigString}'`

new StringParameter(this, 'SSMParameterFetchMigrationRunTaskCommand', {
description: 'OpenSearch Migration Parameter for CLI command to kick off the Fetch Migration ECS Task',
parameterName: `/migration/${props.stage}/${props.defaultDeployId}/fetchMigrationCommand`,
stringValue: executionCommand
createMigrationStringParameter(this, executionCommand, {
...props,
parameter: MigrationSSMParameter.FETCH_MIGRATION_COMMAND,
});
}
}
Loading
Loading