From 8c053eb15dd0ed6400f85e4b947a67c3564962dd Mon Sep 17 00:00:00 2001 From: Nathan Curtis Date: Mon, 2 Dec 2024 14:52:48 -0800 Subject: [PATCH] [TM-1519] Only try to proxy the services that are enabled in this env. --- .github/workflows/deploy-api-gateway.yml | 1 + cdk/api-gateway/lib/api-gateway-stack.ts | 109 ++++++++++++----------- 2 files changed, 57 insertions(+), 53 deletions(-) diff --git a/.github/workflows/deploy-api-gateway.yml b/.github/workflows/deploy-api-gateway.yml index 93685dcb..7815be29 100644 --- a/.github/workflows/deploy-api-gateway.yml +++ b/.github/workflows/deploy-api-gateway.yml @@ -24,6 +24,7 @@ env: AWS_ROLE_TO_ASSUME: arn:aws:iam::603634817705:role/terramatch-microservices-github-actions AWS_ROLE_SESSION_NAME: terramatch-microservices-cicd-api-gateway PHP_PROXY_TARGET: ${{ vars.PHP_PROXY_TARGET }} + ENABLED_SERVICES: ${{ vars.ENABLED_SERVICES }} jobs: deploy-api-gateway: diff --git a/cdk/api-gateway/lib/api-gateway-stack.ts b/cdk/api-gateway/lib/api-gateway-stack.ts index dfde5597..a4f06c19 100644 --- a/cdk/api-gateway/lib/api-gateway-stack.ts +++ b/cdk/api-gateway/lib/api-gateway-stack.ts @@ -1,4 +1,4 @@ -import { Construct } from 'constructs'; +import { Construct } from "constructs"; import { CorsHttpMethod, DomainName, @@ -7,59 +7,59 @@ import { HttpApiProps, HttpMethod, IVpcLink, - VpcLink, -} from 'aws-cdk-lib/aws-apigatewayv2'; -import { - HttpAlbIntegration, - HttpUrlIntegration, -} from 'aws-cdk-lib/aws-apigatewayv2-integrations'; -import { - ApplicationListener, - IApplicationListener, -} from 'aws-cdk-lib/aws-elasticloadbalancingv2'; -import { Vpc } from 'aws-cdk-lib/aws-ec2'; -import { Stack, StackProps } from 'aws-cdk-lib'; + VpcLink +} from "aws-cdk-lib/aws-apigatewayv2"; +import { HttpAlbIntegration, HttpUrlIntegration } from "aws-cdk-lib/aws-apigatewayv2-integrations"; +import { ApplicationListener, IApplicationListener } from "aws-cdk-lib/aws-elasticloadbalancingv2"; +import { Vpc } from "aws-cdk-lib/aws-ec2"; +import { Stack, StackProps } from "aws-cdk-lib"; const V3_SERVICES = { - 'user-service': ['auth', 'users'], - 'job-service': ['jobs'], - 'research-service': ['research'] -} + "user-service": ["auth", "users"], + "job-service": ["jobs"], + "research-service": ["research"] +}; const DOMAIN_MAPPINGS: Record = { test: { - name: 'api-test.terramatch.org', - regionalDomainName: 'd-7wg2eazpki.execute-api.eu-west-1.amazonaws.com', - regionalHostedZoneId: 'ZLY8HYME6SFDD', + name: "api-test.terramatch.org", + regionalDomainName: "d-7wg2eazpki.execute-api.eu-west-1.amazonaws.com", + regionalHostedZoneId: "ZLY8HYME6SFDD" }, dev: { - name: 'api-dev.terramatch.org', - regionalDomainName: 'd-p4wtcekqfd.execute-api.eu-west-1.amazonaws.com', - regionalHostedZoneId: 'ZLY8HYME6SFDD', + name: "api-dev.terramatch.org", + regionalDomainName: "d-p4wtcekqfd.execute-api.eu-west-1.amazonaws.com", + regionalHostedZoneId: "ZLY8HYME6SFDD" }, staging: { - name: 'api-staging.terramatch.org', - regionalDomainName: 'd-lwwcq09sse.execute-api.eu-west-1.amazonaws.com', - regionalHostedZoneId: 'ZLY8HYME6SFDD' + name: "api-staging.terramatch.org", + regionalDomainName: "d-lwwcq09sse.execute-api.eu-west-1.amazonaws.com", + regionalHostedZoneId: "ZLY8HYME6SFDD" }, prod: { - name: 'api.terramatch.org', - regionalDomainName: 'd-6bkz3xwm7k.execute-api.eu-west-1.amazonaws.com', - regionalHostedZoneId: 'ZLY8HYME6SFDD' + name: "api.terramatch.org", + regionalDomainName: "d-6bkz3xwm7k.execute-api.eu-west-1.amazonaws.com", + regionalHostedZoneId: "ZLY8HYME6SFDD" } -} +}; -type AddProxyProps = { targetHost: string, service?: never } | { targetHost?: never, service: string }; +type AddProxyProps = { targetHost: string; service?: never } | { targetHost?: never; service: string }; export class ApiGatewayStack extends Stack { private readonly httpApi: HttpApi; private readonly env: string; - constructor (scope: Construct, id: string, props?: StackProps) { + constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); - if (process.env.TM_ENV == null) throw new Error('No TM_ENV defined'); - this.env = process.env.TM_ENV ?? 'local'; + if (process.env.TM_ENV == null) throw new Error("No TM_ENV defined"); + this.env = process.env.TM_ENV ?? "local"; + + const enabledServices = + process.env.ENABLED_SERVICES == null || process.env.ENABLED_SERVICES === "" + ? Object.keys(V3_SERVICES) + : process.env.ENABLED_SERVICES.split(","); + throw new Error(`ENABLED SERVICES ${JSON.stringify({ enabledServices, env: process.env.ENABLED_SERVICES })}`); const httpApiProps: HttpApiProps = { apiName: `TerraMatch API Gateway - ${this.env}`, @@ -70,10 +70,10 @@ export class ApiGatewayStack extends Stack { CorsHttpMethod.PUT, CorsHttpMethod.POST, CorsHttpMethod.PATCH, - CorsHttpMethod.OPTIONS, + CorsHttpMethod.OPTIONS ], allowOrigins: ["*"], - allowHeaders: ['authorization', 'content-type'], + allowHeaders: ["authorization", "content-type"] }, disableExecuteApiEndpoint: true, defaultDomainMapping: { @@ -83,11 +83,13 @@ export class ApiGatewayStack extends Stack { DOMAIN_MAPPINGS[this.env] ) } - } + }; this.httpApi = new HttpApi(this, `TerraMatch API Gateway - ${this.env}`, httpApiProps); for (const [service, namespaces] of Object.entries(V3_SERVICES)) { + if (!enabledServices.includes(service)) continue; + this.addProxy(`API Swagger Docs [${service}]`, `/${service}/documentation/`, { service }); for (const namespace of namespaces) { @@ -98,11 +100,11 @@ export class ApiGatewayStack extends Stack { // The PHP Monolith proxy keeps `/api/` in its path to avoid conflict with the newer // namespace-driven design of the v3 API space, and to minimize disruption with existing // consumers (like Greenhouse and the web TM frontend) as we migrate to this API Gateway. - this.addProxy('PHP Monolith', '/api/', { targetHost: process.env.PHP_PROXY_TARGET ?? '' }); - this.addProxy('PHP OpenAPI Docs', '/documentation/', { targetHost: process.env.PHP_PROXY_TARGET ?? '' }); + this.addProxy("PHP Monolith", "/api/", { targetHost: process.env.PHP_PROXY_TARGET ?? "" }); + this.addProxy("PHP OpenAPI Docs", "/documentation/", { targetHost: process.env.PHP_PROXY_TARGET ?? "" }); } - private addProxy (name: string, path: string, { targetHost, service }: AddProxyProps) { + private addProxy(name: string, path: string, { targetHost, service }: AddProxyProps) { const sourcePath = `${path}{proxy+}`; if (targetHost == null) { this.addAlbProxy(name, sourcePath, service); @@ -111,39 +113,40 @@ export class ApiGatewayStack extends Stack { } } - private addHttpUrlProxy (name: string, sourcePath: string, targetUrl: string) { + private addHttpUrlProxy(name: string, sourcePath: string, targetUrl: string) { this.httpApi.addRoutes({ path: sourcePath, methods: [HttpMethod.GET, HttpMethod.DELETE, HttpMethod.POST, HttpMethod.PATCH, HttpMethod.PUT], - integration: new HttpUrlIntegration(name, targetUrl), + integration: new HttpUrlIntegration(name, targetUrl) }); } private _serviceListeners: Map = new Map(); - private _vpcLink :IVpcLink; - private addAlbProxy (name: string, sourcePath: string, service: string) { + private _vpcLink: IVpcLink; + private addAlbProxy(name: string, sourcePath: string, service: string) { if (this._vpcLink == null) { this._vpcLink = VpcLink.fromVpcLinkAttributes(this, `vpc-link-${this.env}`, { - vpcLinkId: 't74cf1', - vpc: Vpc.fromLookup(this, 'wri-terramatch-vpc', { - vpcId: 'vpc-0beac5973796d96b1', + vpcLinkId: "t74cf1", + vpc: Vpc.fromLookup(this, "wri-terramatch-vpc", { + vpcId: "vpc-0beac5973796d96b1" }) }); } let serviceListener = this._serviceListeners.get(service); if (serviceListener == null) { - this._serviceListeners.set(service, serviceListener = ApplicationListener.fromLookup( - this, - `${service} Listener`, - { loadBalancerTags: { service: `${service}-${this.env}` } } - )); + this._serviceListeners.set( + service, + (serviceListener = ApplicationListener.fromLookup(this, `${service} Listener`, { + loadBalancerTags: { service: `${service}-${this.env}` } + })) + ); } this.httpApi.addRoutes({ path: sourcePath, methods: [HttpMethod.GET, HttpMethod.DELETE, HttpMethod.POST, HttpMethod.PATCH, HttpMethod.PUT], integration: new HttpAlbIntegration(name, serviceListener, { vpcLink: this._vpcLink }) - }) + }); } }