Skip to content

Commit

Permalink
[TM-1519] Only try to proxy the services that are enabled in this env.
Browse files Browse the repository at this point in the history
  • Loading branch information
roguenet committed Dec 2, 2024
1 parent 1ecf67c commit 8c053eb
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 53 deletions.
1 change: 1 addition & 0 deletions .github/workflows/deploy-api-gateway.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
109 changes: 56 additions & 53 deletions cdk/api-gateway/lib/api-gateway-stack.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Construct } from 'constructs';
import { Construct } from "constructs";
import {
CorsHttpMethod,
DomainName,
Expand All @@ -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<string, DomainNameAttributes> = {
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}`,
Expand All @@ -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: {
Expand All @@ -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) {
Expand All @@ -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);
Expand All @@ -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<string, IApplicationListener> = 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 })
})
});
}
}

0 comments on commit 8c053eb

Please sign in to comment.