Skip to content

Commit

Permalink
CDK update: Add endpoint for Cognito and enable WAF
Browse files Browse the repository at this point in the history
Signed-off-by: Prudhvi Godithi <pgodithi@amazon.com>
  • Loading branch information
prudhvigodithi committed Apr 8, 2024
1 parent 72bd700 commit cdf0109
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 23 deletions.
32 changes: 24 additions & 8 deletions infrastructure/lib/constructs/opensearchNginxProxyCognito.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ export interface opensearchDashboardUrlProps {
}

export class OpenSearchMetricsNginxCognito extends Construct {

static readonly COGNITO_ALB_ARN: string = 'cognitoAlbArn';

readonly asg: AutoScalingGroup;

constructor(scope: Construct, id: string, props: NginxProps) {
Expand All @@ -64,28 +67,37 @@ export class OpenSearchMetricsNginxCognito extends Construct {
healthCheck: HealthCheck.ec2({ grace: Duration.seconds(90) }),
machineImage: MachineImage.latestAmazonLinux2(),
// Temp added public subnet and IP, until backed up by ALB
associatePublicIpAddress: true,
associatePublicIpAddress: false,
allowAllOutbound: true,
desiredCapacity: 1,
minCapacity: 1,
vpc: props.vpc,
vpcSubnets: {
// Temp added public subnet and IP, until backed up by ALB
// subnetType: SubnetType.PUBLIC,
subnetType: SubnetType.PUBLIC
subnetType: SubnetType.PRIVATE_WITH_EGRESS
},
role: instanceRole,
// Actually update the existing instance instead of leaving it running. This will build a new ASG
// and then destroy the old one in order to maintain availability
updatePolicy: UpdatePolicy.replacingUpdate()
});
Tags.of(this.asg).add("Name", "OpenSearchMetricsCognito")

if (props.albProps) {

const albSecurityGroup = new SecurityGroup(this, 'ALBSecurityGroup', {
vpc,
allowAllOutbound: true,
});
albSecurityGroup.addIngressRule(Peer.prefixList(Project.RESTRICTED_PREFIX), Port.tcp(443));

const openSearchCognitoApplicationLoadBalancer = new ApplicationLoadBalancer(this, `OpenSearchMetricsCognito-NginxProxyAlb`, {
loadBalancerName: "OpenSearchMetricsCognito",
vpc: vpc,
internetFacing: true
internetFacing: true,
securityGroup: albSecurityGroup
});

new CfnOutput(this, 'cognitoAlbArn', {
value: openSearchCognitoApplicationLoadBalancer.loadBalancerArn,
exportName: OpenSearchMetricsNginxCognito.COGNITO_ALB_ARN,
});

const listenerCertificate = ListenerCertificate.fromArn(props.albProps.certificateArn);
Expand All @@ -99,13 +111,17 @@ export class OpenSearchMetricsNginxCognito extends Construct {
listener.addTargets(`OpenSearchMetricsCognito-NginxProxyAlbTarget`, {
port: 443,
protocol: ApplicationProtocol.HTTPS,
healthCheck: {
port: '80',
path: '/',
},
targets: [this.asg]
});


const aRecord = new ARecord(this, "OpenSearchMetricsCognito-DNS", {
zone: props.albProps.hostedZone.zone,
recordName: Project.METRICS_HOSTED_ZONE,
recordName: Project.METRICS_COGNITO_HOSTED_ZONE,
target: RecordTarget.fromAlias(new LoadBalancerTarget(openSearchCognitoApplicationLoadBalancer)),
});
}
Expand Down
2 changes: 1 addition & 1 deletion infrastructure/lib/enums/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ enum Project{
JENKINS_AGENT_ROLE = '',
REGION = '',
METRICS_HOSTED_ZONE = 'metrics.opensearch.org',
// Temp until the project is public
METRICS_COGNITO_HOSTED_ZONE = 'metrics.login.opensearch.org',
RESTRICTED_PREFIX = '',
LAMBDA_PACKAGE = 'opensearch-metrics-1.0.zip',
}
Expand Down
12 changes: 11 additions & 1 deletion infrastructure/lib/infrastructure-stack.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {App, CfnOutput, Stack, StackProps} from 'aws-cdk-lib';
import {App, Fn, Stack, StackProps} from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { VpcStack } from "./stacks/vpc";
import {jenkinsAccess, OpenSearchDomainStack} from "./stacks/opensearch";
Expand All @@ -7,6 +7,8 @@ import {OpenSearchHealthRoute53} from "./stacks/route53";
import {OpenSearchMetricsWorkflowStack} from "./stacks/metricsWorkflow";
import {OpenSearchMetricsNginxReadonly} from "./stacks/opensearchNginxProxyReadonly";
import {ArnPrincipal, IPrincipal} from "aws-cdk-lib/aws-iam";
import {OpenSearchWAF} from "./stacks/waf";
import {OpenSearchMetricsNginxCognito} from "./constructs/opensearchNginxProxyCognito";

// import * as sqs from 'aws-cdk-lib/aws-sqs';
export class InfrastructureStack extends Stack {
Expand Down Expand Up @@ -62,5 +64,13 @@ export class InfrastructureStack extends Stack {
});
openSearchMetricsNginxReadonly.node.addDependency(vpcStack, openSearchDomainStack);

// Create an OpenSearch WAF stack
const openSearchWAF = new OpenSearchWAF(app, "OpenSearchWAF", {
readOnlyLoadBalancerArn: Fn.importValue(`${OpenSearchMetricsNginxReadonly.READONLY_ALB_ARN}`),
cognitoLoadBalancerArn: Fn.importValue(`${OpenSearchMetricsNginxCognito.COGNITO_ALB_ARN}`),
appName: "OpenSearchMetricsWAF"
});
openSearchWAF.node.addDependency(openSearchDomainStack, openSearchMetricsNginxReadonly);

}
}
16 changes: 14 additions & 2 deletions infrastructure/lib/stacks/opensearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import * as iam from "aws-cdk-lib/aws-iam";
import { ArnPrincipal, CompositePrincipal, Effect, IRole, ManagedPolicy, PolicyDocument, PolicyStatement, Role, ServicePrincipal } from "aws-cdk-lib/aws-iam";
import { VpcStack } from "./vpc";
import {OpenSearchMetricsCognito} from "../constructs/opensearchCognito";
import {OpenSearchMetricsNginxCognito} from "../constructs/opensearchNginxProxyCognito";;
import {OpenSearchMetricsNginxCognito} from "../constructs/opensearchNginxProxyCognito";
import {OpenSearchHealthRoute53} from "./route53";
import Project from "../enums/project";

;


export interface OpenSearchStackProps {
Expand Down Expand Up @@ -176,14 +180,22 @@ export class OpenSearchDomainStack extends Stack {
this.domain.node.addDependency(serviceLinkedRole);

if(props.enableNginxCognito) {
const metricsHostedZone = new OpenSearchHealthRoute53(this, "OpenSearchMetricsCognito-HostedZone", {
hostedZone: Project.METRICS_COGNITO_HOSTED_ZONE,
appName: "OpenSearchMetricsCognito"
});
new OpenSearchMetricsNginxCognito(this, "OpenSearchMetricsNginx", {
region: this.props.region,
vpc: props.vpcStack.vpc,
securityGroup: props.vpcStack.securityGroup,
opensearchDashboardUrlProps: {
opensearchDashboardVpcUrl: this.domain.domainEndpoint,
cognitoDomain: metricsCognito.userPoolDomain.domain
}
},
albProps: {
hostedZone: metricsHostedZone,
certificateArn: metricsHostedZone.certificateArn,
},
});
}
}
Expand Down
17 changes: 10 additions & 7 deletions infrastructure/lib/stacks/opensearchNginxProxyReadonly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
AmazonLinuxImage, MachineImage
} from 'aws-cdk-lib/aws-ec2';
import * as iam from "aws-cdk-lib/aws-iam";
import {Aspects, Duration, Stack, Tag, Tags} from 'aws-cdk-lib';
import {Aspects, CfnOutput, Duration, Stack, Tag, Tags} from 'aws-cdk-lib';
import { Construct } from 'constructs';
import {
ApplicationLoadBalancer, ApplicationProtocol,
Expand Down Expand Up @@ -46,6 +46,9 @@ export interface opensearchDashboardUrlProps {
}

export class OpenSearchMetricsNginxReadonly extends Stack {

static readonly READONLY_ALB_ARN: string = 'readOnlyAlbArn';

readonly asg: AutoScalingGroup;

constructor(scope: Construct, id: string, props: NginxProps) {
Expand All @@ -54,8 +57,6 @@ export class OpenSearchMetricsNginxReadonly extends Stack {
super(scope, id);

const instanceRole = this.createNginxReadonlyInstanceRole(props);


this.asg = new AutoScalingGroup(this, 'OpenSearchMetricsReadonly-MetricsProxyAsg', {
instanceType: InstanceType.of(InstanceClass.M5, InstanceSize.LARGE),
blockDevices: [{ deviceName: '/dev/xvda', volume: BlockDeviceVolume.ebs(10) }], // GB
Expand Down Expand Up @@ -88,11 +89,13 @@ export class OpenSearchMetricsNginxReadonly extends Stack {
securityGroup: albSecurityGroup
});

const openSearchWAF = new OpenSearchWAF(this, "OpenSearchWAF", {
loadBalancer: openSearchApplicationLoadBalancer,
appName: "OpenSearchMetricsWAF"
new CfnOutput(this, 'readOnlyAlbArn', {
value: openSearchApplicationLoadBalancer.loadBalancerArn,
exportName: OpenSearchMetricsNginxReadonly.READONLY_ALB_ARN,
});
openSearchWAF.node.addDependency(openSearchApplicationLoadBalancer)

//const importedArnSecretBucketValue = Fn.importValue(`${CIConfigStack.CERTIFICATE_ARN_SECRET_EXPORT_VALUE}`);


const listenerCertificate = ListenerCertificate.fromArn(props.albProps.certificateArn);

Expand Down
13 changes: 9 additions & 4 deletions infrastructure/lib/stacks/waf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,21 @@ export class WebACLAssociation extends CfnWebACLAssociation {
}

export interface WafProps extends StackProps{
loadBalancer: ApplicationLoadBalancer,
readOnlyLoadBalancerArn: string,
cognitoLoadBalancerArn: string
appName: string
}

export class OpenSearchWAF extends Construct {
export class OpenSearchWAF extends Stack {
constructor(scope: Construct, id: string, props: WafProps) {
super(scope, id);
const waf = new WAF(this, `${props.appName}-WAFv2`);
new WebACLAssociation(this, 'wafALBassociation', {
resourceArn: props.loadBalancer.loadBalancerArn,
new WebACLAssociation(this, 'wafReadOnlyALBassociation', {
resourceArn: props.readOnlyLoadBalancerArn,
webAclArn: waf.attrArn,
});
new WebACLAssociation(this, 'wafCognitoALBassociation', {
resourceArn: props.cognitoLoadBalancerArn,
webAclArn: waf.attrArn,
});
}
Expand Down

0 comments on commit cdf0109

Please sign in to comment.