Skip to content

Commit

Permalink
fix: ARecords (#216)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattzcarey authored and SEBRATHEZEBRA committed Aug 29, 2023
1 parent d517e21 commit 8c72c52
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 62 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ cdk.context.json
# CDK asset staging directory
.cdk.staging
cdk.out/
cdk.context.json
3 changes: 2 additions & 1 deletion services/core/helpers/certificates.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { StringParameter } from "aws-cdk-lib/aws-ssm";
import { Construct } from "constructs";
import { getStage } from "./env-helpers";

export const getCertificateArn = (
scope: Construct,
stage: string,
subDomain: string
): string | undefined => {
const stage = getStage();
return (
StringParameter.fromStringParameterAttributes(
scope,
Expand Down
42 changes: 22 additions & 20 deletions services/core/resources/constructs/api-gateway.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import {
BasePathMapping,
DomainName,
EndpointType,
RestApi,
RestApiProps,
} from "aws-cdk-lib/aws-apigateway";
import { Certificate } from "aws-cdk-lib/aws-certificatemanager";
import { ARecord, HostedZone, RecordTarget } from "aws-cdk-lib/aws-route53";
import { ApiGateway } from "aws-cdk-lib/aws-route53-targets";
import { Construct } from "constructs";
import { buildResourceName } from "../../helpers";

export interface CoreApiProps extends Omit<RestApiProps, "restApiName"> {
domainNameString: string;
rootDomain?: string;
subDomain?: string;
certificateArn?: string;
}

export class CoreApi extends RestApi {
export class OrionApi extends RestApi {
constructor(scope: Construct, id: string, props: CoreApiProps) {
super(scope, id, {
...props,
Expand All @@ -25,37 +26,38 @@ export class CoreApi extends RestApi {
},
defaultCorsPreflightOptions: {
allowHeaders: [
'Content-Type',
'X-Amz-Date',
'Authorization',
'X-Api-Key',
"Content-Type",
"X-Amz-Date",
"Authorization",
"X-Api-Key",
],
allowMethods: ['OPTIONS', 'GET', 'POST'],
allowMethods: ["OPTIONS", "GET", "POST"],
allowCredentials: true,
allowOrigins: ['http://localhost:3000'],
allowOrigins: ["http://localhost:3000", "https://*.oriontools.ai"],
},
});

const { certificateArn, domainNameString } = props;
const { rootDomain, subDomain, certificateArn } = props;

if (certificateArn) {
if (certificateArn && rootDomain && subDomain) {
const certificate = Certificate.fromCertificateArn(
this,
"Certificate",
certificateArn
);

// Create custom domain
const customDomain = new DomainName(this, "CustomDomain", {
domainName: domainNameString,
this.addDomainName("DomainName", {
domainName: `${subDomain}.${rootDomain}`,
certificate: certificate,
endpointType: EndpointType.EDGE, // or REGIONAL
endpointType: EndpointType.EDGE,
});

// Create a base path mapping that links the custom domain to the API
new BasePathMapping(this, "BasePathMapping", {
domainName: customDomain,
restApi: this,
new ARecord(this, "ApiSubDomainDNS", {
zone: HostedZone.fromLookup(this, "baseZone", {
domainName: rootDomain,
}),
recordName: subDomain,
target: RecordTarget.fromAlias(new ApiGateway(this)),
});
}
}
Expand Down
17 changes: 15 additions & 2 deletions services/core/resources/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,31 @@ import { RemovalPolicyAspect } from "../aspects/RemovalPolicyAspect";

import { buildResourceName, getRegion, getStage } from "../helpers";
import { CoreStack } from "./stacks/core-stack";
import { DemoStack } from "./stacks/demo-stack";

const app = new App();

//Env
const stage = getStage();
const region = getRegion();

//Stacks
const coreStack = new CoreStack(app, "crgpt-core", {
stackName: buildResourceName("crgpt-core"),
stage: stage,
env: { region },
env: { region, account: process.env.CDK_DEFAULT_ACCOUNT },
});

const demoStack = new DemoStack(app, "crgpt-demo", {
stackName: buildResourceName("crgpt-demo"),
stage: stage,
env: { region, account: process.env.CDK_DEFAULT_ACCOUNT },
userTable: coreStack.userTable,
});

//Aspects
Aspects.of(coreStack).add(new RemovalPolicyAspect());
Aspects.of(demoStack).add(new RemovalPolicyAspect());

//enable OTel traces
//OTel traces
Tags.of(app).add("baselime:tracing", `true`);
61 changes: 22 additions & 39 deletions services/core/resources/stacks/core-stack.ts
Original file line number Diff line number Diff line change
@@ -1,74 +1,57 @@
import { Stack, StackProps } from "aws-cdk-lib";
import { LambdaIntegration } from "aws-cdk-lib/aws-apigateway";
import { Table } from "aws-cdk-lib/aws-dynamodb";
import { Key } from "aws-cdk-lib/aws-kms";
import { Construct } from "constructs";
import { DemoReviewLambda } from "../../functions/demo-review-lambda/config";
import { GetUserLambda } from "../../functions/get-user/config";
import { ReviewLambda } from "../../functions/review-lambda/config";
import { UpdateUserLambda } from "../../functions/update-user/config";
import { getCertificateArn, getDomainName, getStage } from "../../helpers";
import { CoreApi } from "../constructs/api-gateway";
import { ReviewBucket } from "../constructs/review-bucket";
import { OrionApi } from "../constructs/api-gateway";
import { UserTable } from "../constructs/user-table";

interface CoreStackProps extends StackProps {
stage: string;
}

export class CoreStack extends Stack {
userTable: Table;
constructor(scope: Construct, id: string, props: CoreStackProps) {
super(scope, id, props);

const api = new CoreApi(this, "core-api", {
domainNameString: `api.${getDomainName(props.stage)}`,
certificateArn: getCertificateArn(this, props.stage, "api"),
//API
const api = new OrionApi(this, "core-api", {
rootDomain: getDomainName(props.stage),
subDomain: "api",
certificateArn: getCertificateArn(this, "api"),
});

const userTable = new UserTable(this, "user-database");

const reviewLambda = new ReviewLambda(this, "review-lambda");

const postReviewRoute = api.root.addResource("postReview");
postReviewRoute.addMethod("POST", new LambdaIntegration(reviewLambda));

// We use a separate api for the demo review to enable strong throttling on it
const demoApi = new CoreApi(this, "demo-api", {
deployOptions: {
throttlingBurstLimit: 1,
throttlingRateLimit: 1,
},
domainNameString: `demo.${getDomainName(props.stage)}`,
certificateArn: getCertificateArn(this, props.stage, "demo"),
});

const demoReviewBucket = new ReviewBucket(this, "demo-review-bucket");

const demoReviewLambda = new DemoReviewLambda(this, "demo-review-lambda", {
table: userTable,
bucket: demoReviewBucket,
});

const demoReviewRoute = demoApi.root.addResource("demoReview");
demoReviewRoute.addMethod("POST", new LambdaIntegration(demoReviewLambda));

// Resources for user management
//KMS
const kmsKey = new Key(this, "encryption-key", {
enableKeyRotation: true,
alias: `${getStage()}/encryption-key`,
});

//DynamoDB
this.userTable = new UserTable(this, "user-database");

//Lambda
const reviewLambda = new ReviewLambda(this, "review-lambda");
const updateUserLambda = new UpdateUserLambda(this, "update-user-lambda", {
table: userTable,
table: this.userTable,
kmsKey: kmsKey,
});
const getUserLambda = new GetUserLambda(this, "get-user-lambda", {
table: this.userTable,
});

//Routes
const postReviewRoute = api.root.addResource("postReview");
postReviewRoute.addMethod("POST", new LambdaIntegration(reviewLambda));

const updateUserRoute = api.root.addResource("updateUser");
updateUserRoute.addMethod("POST", new LambdaIntegration(updateUserLambda));

const getUserLambda = new GetUserLambda(this, "get-user-lambda", {
table: userTable,
});

const getUserRoute = api.root.addResource("getUser");
getUserRoute.addMethod("GET", new LambdaIntegration(getUserLambda));
}
Expand Down
43 changes: 43 additions & 0 deletions services/core/resources/stacks/demo-stack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Stack, StackProps } from "aws-cdk-lib";
import { LambdaIntegration } from "aws-cdk-lib/aws-apigateway";
import { Table } from "aws-cdk-lib/aws-dynamodb";
import { Construct } from "constructs";
import { DemoReviewLambda } from "../../functions/demo-review-lambda/config";
import { getCertificateArn, getDomainName } from "../../helpers";
import { OrionApi } from "../constructs/api-gateway";
import { ReviewBucket } from "../constructs/review-bucket";

interface DemoStackProps extends StackProps {
stage: string;
userTable: Table;
}

export class DemoStack extends Stack {
constructor(scope: Construct, id: string, props: DemoStackProps) {
super(scope, id, props);

// Separate API for the demo to enable strong throttling
const demoApi = new OrionApi(this, "demo-api", {
deployOptions: {
throttlingBurstLimit: 1,
throttlingRateLimit: 1,
},
rootDomain: getDomainName(props.stage),
subDomain: "demo",
certificateArn: getCertificateArn(this, "demo"),
});

//Resources
const demoReviewBucket = new ReviewBucket(this, "demo-review-bucket");

//Lambda
const demoReviewLambda = new DemoReviewLambda(this, "demo-review-lambda", {
table: props.userTable,
bucket: demoReviewBucket,
});

//Routes
const demoReviewRoute = demoApi.root.addResource("demoReview");
demoReviewRoute.addMethod("POST", new LambdaIntegration(demoReviewLambda));
}
}

0 comments on commit 8c72c52

Please sign in to comment.