Skip to content

Commit

Permalink
Set up ms-apollo and update deployment
Browse files Browse the repository at this point in the history
  • Loading branch information
Tehnix committed Oct 24, 2023
1 parent c315cdd commit d68a638
Show file tree
Hide file tree
Showing 17 changed files with 7,038 additions and 39 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ members = [
"ms-router",
]

exclude = ["ui-internal"]
exclude = ["ui-internal", "ms-apollo", "ms-apollo2"]

[profile.release]
# Configurations explicitly listed here for clarity.
Expand Down
Binary file modified deployment/bun.lockb
Binary file not shown.
37 changes: 37 additions & 0 deletions deployment/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import type { Config } from "./lib/types";

export const config: Config = {
apps: [{ service: "internal", subdomain: "internal" }, { service: "app" }],

supergraph: {
service: "mesh",
runtime: "lambda",
path: "/graphql",
},

subgraphs: [
{ name: "users", project: "ms-gql-users" },
{ name: "products", project: "ms-gql-products" },
{ name: "reviews", project: "ms-gql-reviews" },
],

experimental: {
additionalSupergraphs: [
{
service: "gateway",
runtime: "lambda",
path: "/graphql-gateway",
},
{
service: "router",
runtime: "lambda",
path: "/graphql-router",
},
{
service: "router",
runtime: "app-runner",
path: "/graphql-app-router",
},
],
},
};
48 changes: 48 additions & 0 deletions deployment/lib/services/app-runner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as appRunner from "@aws-cdk/aws-apprunner-alpha";

export interface StackProps extends cdk.StackProps {
/**
* The path to the assets we are deploying.
*/
readonly assets: string;

/**
* The environment variables for the function.
*/
readonly environment?: { [key: string]: string };

/**
* The name we want to give the function.
*/
readonly functionName: string;

/**
* The billing group to associate with this stack.
*/
readonly billingGroup: string;
}

/**
* Set up an a Lambda Function.
*/
export class Stack extends cdk.Stack {
/**
* The URL to access the Lambda Function.
*/
// public readonly functionUrl: string;

constructor(scope: Construct, id: string, props: StackProps) {
super(scope, id, props);

new appRunner.Service(this, "Service", {
source: appRunner.Source.fromEcrPublic({
imageConfiguration: { port: 8000 },
imageIdentifier:
"public.ecr.aws/aws-containers/hello-app-runner:latest",
}),
});
}
}
2 changes: 1 addition & 1 deletion deployment/lib/services/lambda.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface StackProps extends cdk.StackProps {
readonly runtime?: lambda.Runtime;

/**
* The name we want to give the function.
* The environment variables for the function.
*/
readonly environment?: { [key: string]: string };

Expand Down
38 changes: 23 additions & 15 deletions deployment/lib/services/s3-website.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,28 +95,33 @@ export class Stack extends cdk.Stack {
});
}

const additionalBehaviors: {
[key: string]: cloudfront.BehaviorOptions & cloudfront.AddBehaviorOptions;
} = {};
const redirectPathToUrl = props.redirectPathToUrl ?? {};
const originRequestPolicy = new cloudfront.OriginRequestPolicy(
this,
"OriginRequestPolicy",
{
// NOTE: We cannot forward the HOST header, it will cause a 403.
// See note in https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/controlling-origin-requests.html#origin-request-understand-origin-request-policy.
headerBehavior: cloudfront.OriginRequestHeaderBehavior.denyList("Host"),
queryStringBehavior: cloudfront.OriginRequestQueryStringBehavior.all(),
headerBehavior: cloudfront.OriginRequestHeaderBehavior.all(),
cookieBehavior: cloudfront.OriginRequestCookieBehavior.all(),
comment: "Allow all headers, cookies, and query strings.",
comment: "Allow all headers (except HOST), cookies, and query strings.",
}
);
const additionalBehaviors: {
[key: string]: cloudfront.BehaviorOptions & cloudfront.AddBehaviorOptions;
} = {};

// Content-Type
const redirectPathToUrl = props.redirectPathToUrl ?? {};
// Iterate over the keys and values of redirectPathToUrl.
for (const key in redirectPathToUrl) {
const url = redirectPathToUrl[key];
const domainPart = cdk.Fn.select(2, cdk.Fn.split("/", url));
additionalBehaviors[key] = {
// NOTE: The trailing slash is an important part of the path.
origin: new cloudfrontOrigins.HttpOrigin(domainPart, {
originPath: "/",
customHeaders: {
"X-Forwarded-Host": props.domain,
},
}),
allowedMethods: cloudfront.AllowedMethods.ALLOW_ALL,
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
Expand Down Expand Up @@ -158,11 +163,11 @@ export class Stack extends cdk.Stack {
// Set up redirects when a user hits a 404 or 403.
// TODO: Are these causing the other pages to be inaccessible?
errorResponses: [
{
httpStatus: 403,
responsePagePath: `/${props.error}`,
responseHttpStatus: 200,
},
// {
// httpStatus: 403,
// responsePagePath: `/${props.error}`,
// responseHttpStatus: 200,
// },
{
httpStatus: 404,
responsePagePath: `/${props.error}`,
Expand Down Expand Up @@ -196,8 +201,11 @@ export class Stack extends cdk.Stack {
new CloudFrontInvalidation(this, "CloudFrontInvalidation", {
...props,
distribution,
// Only invalidate / and index.html since all other files are hashed.
distributionPaths: ["/", `/${props.index}`],
// Only invalidate / and index.html since all other files are hashed, except if we are
// using the rewriteUrl functionality, which means we are serving files without hashes
// at various paths.
distributionPaths:
rewriteUrl !== undefined ? ["/*"] : ["/", `/${props.index}`],
});

// Set up our DNS records that points to our CloudFront distribution.
Expand Down
110 changes: 110 additions & 0 deletions deployment/lib/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
export type Config = {
/**
* Which Applications to deploy:
* - internal: Leptos (Rust/WASM)
* - app: React/Next.js (TypeScript)
*
* NOTE: Only `internal` supports specifying a subdomain. The `app` is
* always located at the root.
*
* Example:
* ```ts
* apps: [
* { service: "internal", subdomain: "internal" },
* { service: "app" }
* ]
* ```
*/
apps: App[];

/**
* Which supergraph to use:
* - mesh: [GraphQL Mesh](https://the-guild.dev/graphql/mesh)
* - router: [Apollo Router](https://www.apollographql.com/docs/router/)
* - gateway: [Apollo Gateway](https://www.apollographql.com/docs/apollo-server/using-federation/apollo-gateway-setup)
*
* NOTE: The `path` defines the path on the App domains where the API will be
* accessible, to avoid running into CORS issues by needing to go cross-domain.
*
* Example:
* ```ts
* supergraph: {
* service: "mesh",
* runtime: "lambda",
* path: "/graphql",
* }
* ```
*/
supergraph: Supergraph;

/**
* Specify the set of subgraphs to run.
*
* NOTE: The `name` is used to identify the subgraph in the supergraph, and
* will be used to construct the environment variable with its URL that is
* passed to the supergraph. E.g. a name of `users` will turn into `SUBGRAPH_USERS_URL`.
*
* Example:
* ```ts
* subgraphs: [
* { name: "users", project: "ms-gql-users" },
* { name: "products", project: "ms-gql-products" },
* { name: "reviews", project: "ms-gql-reviews" },
* ]
* ```
*/
subgraphs: Subgraph[];

/**
* Experimental features.
*/
experimental: {
/**
* Set up additional supergraphs.
*
* NOTE: Make sure to not overlap the paths.
*/
additionalSupergraphs: Supergraph[];
};
};

export type Subgraph = {
name: string;
project: string;
runtime?: "lambda";
memory?:
| 128
| 256
| 512
| 1024
| 2048
| 3072
| 4096
| 5120
| 6144
| 7168
| 8192
| 9216
| 10240;
};

export type App =
| { service: "internal"; subdomain: string }
| { service: "app" };

export type Supergraph =
| {
service: "mesh";
runtime: "lambda";
path: string;
}
| {
service: "gateway";
runtime: "lambda";
path: string;
}
| {
service: "router";
runtime: "app-runner" | "lambda";
path: string;
};
3 changes: 2 additions & 1 deletion deployment/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"bun-types": "latest"
},
"dependencies": {
"@aws-cdk/aws-apprunner-alpha": "2.102.0-alpha.0",
"aws-cdk-lib": "2.100.0",
"constructs": "10.2.70"
"constructs": "10.3.0"
}
}
26 changes: 23 additions & 3 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ _install-tooling-all-platforms:
cargo binstall --no-confirm cargo-lambda
# Install leptosfmt for formatting Leptos View macros.
cargo binstall --no-confirm leptosfmt
# Install cargo-xtask for running tasks.
cargo binstall --no-confirm cargo-xtask

# Setup dependencies and tooling for <project>, e.g. `just setup deployment`.
setup project:
Expand Down Expand Up @@ -167,6 +169,7 @@ compose:
cd ms-router && rover supergraph compose --config ../supergraph-config.yaml --output ../supergraph.graphql
cp ms-router/supergraph.graphql ms-gateway/src/supergraph.graphql
cp ms-router/supergraph.graphql ms-mesh/supergraph.graphql
cp ms-router/supergraph.graphql ms-apollo/supergraph.graphql

# Run tests for <project>, e.g. `just test deployment`.
test project:
Expand Down Expand Up @@ -204,16 +207,26 @@ _dev-ui-internal:
_dev-ms-router:
cd ms-router/bin && ./router --anonymous-telemetry-disabled --config ../router.yaml --supergraph=../supergraph.graphql --dev --hot-reload --log debug

# Can be invoked with:
# cargo lambda invoke --invoke-port 3035 --data-ascii '{ "body": "{\"query\":\"{me { name } }\"}" }'
_dev-ms-router-lambda:
cd ms-router && cargo lambda watch --invoke-port 3035

_dev-ms-gateway:
cd ms-gateway && bun dev

_dev-ms-mesh:
cd ms-mesh && bun devh

# Can be invoked with:
# cargo lambda invoke --invoke-port 3035 --data-ascii '{ "body": "{\"query\":\"{me { name } }\"}" }'
_dev-ms-router-lambda:
cd ms-router && cargo lambda watch --invoke-port 3035
# cargo lambda invoke --invoke-port 3034 --data-ascii '{ "body": "{\"query\":\"{me { name } }\"}" }'
_dev-ms-apollo:
cd ms-apollo && cargo watch -x run --features local

# Can be invoked with:
# cargo lambda invoke --invoke-port 3034 --data-ascii '{ "body": "{\"query\":\"{me { name } }\"}" }'
_dev-ms-apollo-lambda:
cd ms-apollo && cargo lambda watch --invoke-port 3034

# Alternative: cargo lambda watch --invoke-port 3065
_dev-ms-gql-users:
Expand Down Expand Up @@ -260,6 +273,13 @@ _build-ms-router build="release":
@ cp ms-router/router.yaml ./deployment/artifacts/ms-router/router.yaml
@ cp ms-router/supergraph.graphql ./deployment/artifacts/ms-router/supergraph.graphql

_build-ms-apollo build="release":
cd ms-apollo && cargo lambda build --arm64 {{ if build == "debug" { "" } else { "--release" } }}
@ rm -r ./deployment/artifacts/ms-apollo || true
@ mkdir -p ./deployment/artifacts && cp -r ./target/lambda/ms-apollo ./deployment/artifacts/ms-apollo
@ cp ms-apollo/router.yaml ./deployment/artifacts/ms-apollo/router.yaml
@ cp ms-apollo/supergraph.graphql ./deployment/artifacts/ms-apollo/supergraph.graphql

_build-ms-gateway build="release":
cd ms-gateway && bun run build
@ rm -r ./deployment/artifacts/ms-gateway || true
Expand Down
Loading

0 comments on commit d68a638

Please sign in to comment.