1+ import {
2+ Stack ,
3+ aws_ec2 as ec2 ,
4+ aws_rds as rds ,
5+ aws_lambda as lambda ,
6+ aws_secretsmanager as secretsmanager ,
7+ CfnOutput ,
8+ } from "aws-cdk-lib" ;
9+ import {
10+ PythonFunction ,
11+ PythonFunctionProps ,
12+ } from "@aws-cdk/aws-lambda-python-alpha" ;
13+ import { HttpApi } from "@aws-cdk/aws-apigatewayv2-alpha" ;
14+ import { HttpLambdaIntegration } from "@aws-cdk/aws-apigatewayv2-integrations-alpha" ;
15+ import { Construct } from "constructs" ;
16+
17+ export class TitilerPgstacApiLambda extends Construct {
18+ readonly url : string ;
19+
20+ constructor ( scope : Construct , id : string , props : TitilerPgStacApiLambdaProps ) {
21+ super ( scope , id ) ;
22+
23+ const apiCode = props . apiCode || {
24+ entry : `${ __dirname } /runtime` ,
25+ index : "src/handler.py" ,
26+ handler : "handler" ,
27+ } ;
28+
29+ const handler = new PythonFunction ( this , "titiler-pgstac-api" , {
30+ ...apiCode ,
31+ /**
32+ * NOTE: Unable to use Py3.9, due to issues with hashes:
33+ *
34+ * ERROR: Hashes are required in --require-hashes mode, but they are missing
35+ * from some requirements. Here is a list of those requirements along with the
36+ * hashes their downloaded archives actually had. Add lines like these to your
37+ * requirements files to prevent tampering. (If you did not enable
38+ * --require-hashes manually, note that it turns on automatically when any
39+ * package has a hash.)
40+ * anyio==3.6.1 --hash=sha256:cb29b9c70620506a9a8f87a309591713446953302d7d995344d0d7c6c0c9a7be
41+ * */
42+ runtime : lambda . Runtime . PYTHON_3_8 ,
43+ architecture : lambda . Architecture . X86_64 ,
44+ environment : {
45+ PGSTAC_SECRET_ARN : props . dbSecret . secretArn ,
46+ DB_MIN_CONN_SIZE : "0" ,
47+ DB_MAX_CONN_SIZE : "1" ,
48+ ...props . apiEnv ,
49+ } ,
50+ vpc : props . vpc ,
51+ vpcSubnets : props . subnetSelection ,
52+ allowPublicSubnet : true ,
53+ memorySize : 8192 ,
54+ } ) ;
55+
56+ props . dbSecret . grantRead ( handler ) ;
57+ handler . connections . allowTo ( props . db , ec2 . Port . tcp ( 5432 ) , "allow connections from titiler" ) ;
58+
59+ const stacApi = new HttpApi ( this , `${ Stack . of ( this ) . stackName } -titiler-pgstac-api` , {
60+ defaultIntegration : new HttpLambdaIntegration ( "integration" , handler ) ,
61+ } ) ;
62+
63+ this . url = stacApi . url ! ;
64+
65+ new CfnOutput ( this , "titiler-pgstac-api-output" , {
66+ exportName : `${ Stack . of ( this ) . stackName } -url` ,
67+ value : this . url ,
68+ } ) ;
69+ }
70+ }
71+
72+ export interface TitilerPgStacApiLambdaProps {
73+ /**
74+ * VPC into which the lambda should be deployed.
75+ */
76+ readonly vpc : ec2 . IVpc ;
77+
78+ /**
79+ * RDS Instance with installed pgSTAC.
80+ */
81+ readonly db : rds . IDatabaseInstance ;
82+
83+ /**
84+ * Subnet into which the lambda should be deployed.
85+ */
86+ readonly subnetSelection : ec2 . SubnetSelection ;
87+
88+ /**
89+ * Secret containing connection information for pgSTAC database.
90+ */
91+ readonly dbSecret : secretsmanager . ISecret ;
92+
93+ /**
94+ * Custom code to run for titiler-pgstac.
95+ *
96+ * @default - simplified version of titiler-pgstac
97+ */
98+ readonly apiCode ?: TitilerApiEntrypoint ;
99+
100+ /**
101+ * Customized environment variables to send to titiler-pgstac runtime.
102+ */
103+ readonly apiEnv ?: Record < string , string > ;
104+ }
105+
106+ export interface TitilerApiEntrypoint {
107+ /**
108+ * Path to the source of the function or the location for dependencies.
109+ */
110+ readonly entry : PythonFunctionProps [ "entry" ] ;
111+ /**
112+ * The path (relative to entry) to the index file containing the exported handler.
113+ */
114+ readonly index : PythonFunctionProps [ "index" ] ;
115+ /**
116+ * The name of the exported handler in the index file.
117+ */
118+ readonly handler : PythonFunctionProps [ "handler" ] ;
119+ }
120+
0 commit comments