From a0e7ab5dfa9f10dd71513381c91b51aab0d8ff05 Mon Sep 17 00:00:00 2001 From: emileten Date: Fri, 1 Sep 2023 11:27:08 +0900 Subject: [PATCH 1/6] custom runtimes option for titiler and ingestor --- lib/ingestor-api/index.ts | 73 +++++++++++++++++++++++++++++++-- lib/titiler-pgstac-api/index.ts | 20 ++++++++- 2 files changed, 88 insertions(+), 5 deletions(-) diff --git a/lib/ingestor-api/index.ts b/lib/ingestor-api/index.ts index c2de4d8..1c0d8ea 100644 --- a/lib/ingestor-api/index.ts +++ b/lib/ingestor-api/index.ts @@ -11,7 +11,7 @@ import { RemovalPolicy, Stack, } from "aws-cdk-lib"; -import { PythonFunction } from "@aws-cdk/aws-lambda-python-alpha"; +import { PythonFunction, PythonFunctionProps } from "@aws-cdk/aws-lambda-python-alpha"; import { Construct } from "constructs"; export class StacIngestor extends Construct { @@ -108,11 +108,17 @@ export class StacIngestor extends Construct { dbVpc: ec2.IVpc; dbSecurityGroup: ec2.ISecurityGroup; subnetSelection: ec2.SubnetSelection + apiCode: ApiCode; }): PythonFunction { - const handler = new PythonFunction(this, "api-handler", { + const apiCode = props.apiCode || { entry: `${__dirname}/runtime`, index: "src/handler.py", + handler: "handler", + }; + + const handler = new PythonFunction(this, "api-handler", { + ...apiCode, runtime: lambda.Runtime.PYTHON_3_9, timeout: Duration.seconds(30), environment: { DB_SECRET_ARN: props.dbSecret.secretArn, ...props.env }, @@ -145,10 +151,19 @@ export class StacIngestor extends Construct { dbVpc: ec2.IVpc; dbSecurityGroup: ec2.ISecurityGroup; subnetSelection: ec2.SubnetSelection; + ingestorCode: IngestorCode; }): PythonFunction { - const handler = new PythonFunction(this, "stac-ingestor", { + + + + const ingestorCode = props.ingestorCode || { entry: `${__dirname}/runtime`, index: "src/ingestor.py", + handler: "handler", + }; + + const handler = new PythonFunction(this, "stac-ingestor", { + ...ingestorCode, runtime: lambda.Runtime.PYTHON_3_9, timeout: Duration.seconds(180), environment: { DB_SECRET_ARN: props.dbSecret.secretArn, ...props.env }, @@ -290,4 +305,56 @@ export interface StacIngestorProps { * Custom Domain Name Options for Ingestor API */ readonly ingestorDomainNameOptions?: apigateway.DomainNameOptions; + + /** + * Custom code for the ingestor api. + * + * @default - default in the runtime folder. + */ + readonly apiCode?: ApiCode; + + /** + * Custom code for the ingestor. + * + * @default - default in the runtime folder. + */ + readonly ingestorCode?: IngestorCode; } + +export interface ApiCode { + + /** + * Path to the source of the function or the location for dependencies, for the api lambda. + */ + readonly entry: PythonFunctionProps["entry"]; + + /** + * Path to the index file containing the exported handler, relative to `api_lambda_entry`. + */ + readonly index: PythonFunctionProps["index"]; + + /** + * The name of the exported handler in the `api_lambda_index` file. + */ + readonly handler: PythonFunctionProps["handler"]; + +} + +export interface IngestorCode { + + /** + * Path to the source of the function or the location for dependencies, for the ingestor lambda. + */ + readonly entry: PythonFunctionProps["entry"]; + + /** + * Path to the index file containing the exported handler, relative to `ingestor_lambda_entry`. + */ + readonly index: PythonFunctionProps["index"]; + + /** + * The name of the exported handler in the `ingestor_lambda_index` file. + */ + readonly handler: PythonFunctionProps["handler"]; + +} \ No newline at end of file diff --git a/lib/titiler-pgstac-api/index.ts b/lib/titiler-pgstac-api/index.ts index a64cbb3..7f2122a 100644 --- a/lib/titiler-pgstac-api/index.ts +++ b/lib/titiler-pgstac-api/index.ts @@ -40,7 +40,7 @@ import { this.titilerPgstacLambdaFunction = new lambda.Function(this, "lambda", { handler: "handler.handler", runtime: lambda.Runtime.PYTHON_3_10, - code: lambda.Code.fromDockerBuild(__dirname, { + code: props.titilerApiAsset ?? lambda.Code.fromDockerBuild(__dirname, { file: "runtime/Dockerfile", buildArgs: { PYTHON_VERSION: '3.10' }, }), @@ -48,7 +48,7 @@ import { vpc: props.vpc, vpcSubnets: props.subnetSelection, allowPublicSubnet: true, - memorySize: 3008, + memorySize: props.titilerLambdaMemorySize ?? 3008, logRetention: aws_logs.RetentionDays.ONE_WEEK, environment: titilerPgstacEnv, }); @@ -118,4 +118,20 @@ import { * Custom Domain Name Options for Titiler Pgstac API, */ readonly titilerPgstacApiDomainName?: IDomainName; + + /** + * asset created by a docker build with the titiler pgstac application, + * can be produced with lambda.Code.fromDockerBuild. + * + * If undefined, the default application contained in the runtime folder will be used. + * + * @default - undefined + */ + readonly titilerApiAsset?: lambda.AssetCode; + + + /** + * amount of memory to allocate to the lambda function. + */ + readonly titilerLambdaMemorySize?: number; } From 0731e3284e275c723ca6cdb6cfd64fc4961bfa0f Mon Sep 17 00:00:00 2001 From: emileten Date: Fri, 1 Sep 2023 11:36:13 +0900 Subject: [PATCH 2/6] make those optional --- lib/ingestor-api/index.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/ingestor-api/index.ts b/lib/ingestor-api/index.ts index 1c0d8ea..dc65f02 100644 --- a/lib/ingestor-api/index.ts +++ b/lib/ingestor-api/index.ts @@ -55,6 +55,7 @@ export class StacIngestor extends Construct { dbVpc: props.vpc, dbSecurityGroup: props.stacDbSecurityGroup, subnetSelection: props.subnetSelection, + apiCode: props.apiCode, }); this.buildApiEndpoint({ @@ -72,6 +73,7 @@ export class StacIngestor extends Construct { dbVpc: props.vpc, dbSecurityGroup: props.stacDbSecurityGroup, subnetSelection: props.subnetSelection, + ingestorCode: props.ingestorCode, }); this.registerSsmParameter({ @@ -108,7 +110,7 @@ export class StacIngestor extends Construct { dbVpc: ec2.IVpc; dbSecurityGroup: ec2.ISecurityGroup; subnetSelection: ec2.SubnetSelection - apiCode: ApiCode; + apiCode?: ApiCode; }): PythonFunction { const apiCode = props.apiCode || { @@ -151,7 +153,7 @@ export class StacIngestor extends Construct { dbVpc: ec2.IVpc; dbSecurityGroup: ec2.ISecurityGroup; subnetSelection: ec2.SubnetSelection; - ingestorCode: IngestorCode; + ingestorCode?: IngestorCode; }): PythonFunction { From 1766f761300ca81550f33fdb3d28716badf9d702 Mon Sep 17 00:00:00 2001 From: emileten Date: Mon, 4 Sep 2023 15:48:02 +0900 Subject: [PATCH 3/6] switch to pythonFunction for titiler runtime, remove boto3 from requirements, a coupl adjustments accordingly, fix optional env vars --- lib/tipg-api/index.ts | 4 +- lib/titiler-pgstac-api/index.ts | 119 ++++++++++++------ lib/titiler-pgstac-api/runtime/Dockerfile | 20 --- .../runtime/dev_requirements.txt | 3 +- .../runtime/requirements.txt | 2 +- lib/titiler-pgstac-api/runtime/src/handler.py | 2 +- 6 files changed, 85 insertions(+), 65 deletions(-) delete mode 100644 lib/titiler-pgstac-api/runtime/Dockerfile diff --git a/lib/tipg-api/index.ts b/lib/tipg-api/index.ts index 23dcb39..c9f7fe7 100644 --- a/lib/tipg-api/index.ts +++ b/lib/tipg-api/index.ts @@ -87,9 +87,9 @@ import { readonly dbSecret: secretsmanager.ISecret; /** - * Custom code to run for fastapi-pgstac. + * Custom code to run for the application. * - * @default - simplified version of fastapi-pgstac + * @default - simplified version of tipg. */ readonly apiCode?: TiPgApiEntrypoint; diff --git a/lib/titiler-pgstac-api/index.ts b/lib/titiler-pgstac-api/index.ts index 7f2122a..0b788ea 100644 --- a/lib/titiler-pgstac-api/index.ts +++ b/lib/titiler-pgstac-api/index.ts @@ -9,49 +9,74 @@ import { Duration, aws_logs, } from "aws-cdk-lib"; + import {PythonFunction, PythonFunctionProps} from "@aws-cdk/aws-lambda-python-alpha"; import { IDomainName, HttpApi } from "@aws-cdk/aws-apigatewayv2-alpha"; import { HttpLambdaIntegration } from "@aws-cdk/aws-apigatewayv2-integrations-alpha"; import { Construct } from "constructs"; + + // default settings that can be overridden by the user-provided environment. + let defaultTitilerPgstacEnv :{ [key: string]: any } = { + "CPL_VSIL_CURL_ALLOWED_EXTENSIONS": ".tif,.TIF,.tiff", + "GDAL_CACHEMAX": "200", + "GDAL_DISABLE_READDIR_ON_OPEN": "EMPTY_DIR", + "GDAL_INGESTED_BYTES_AT_OPEN": "32768", + "GDAL_HTTP_MERGE_CONSECUTIVE_RANGES": "YES", + "GDAL_HTTP_MULTIPLEX": "YES", + "GDAL_HTTP_VERSION": "2", + "PYTHONWARNINGS": "ignore", + "VSI_CACHE": "TRUE", + "VSI_CACHE_SIZE": "5000000", + "DB_MIN_CONN_SIZE": "1", + "DB_MAX_CONN_SIZE": "1" + } + + const defaultMemorySize = 3008; + export class TitilerPgstacApiLambda extends Construct { readonly url: string; public titilerPgstacLambdaFunction: lambda.Function; constructor(scope: Construct, id: string, props: TitilerPgStacApiLambdaProps) { super(scope, id); - - const titilerPgstacEnv = { - "CPL_VSIL_CURL_ALLOWED_EXTENSIONS": ".tif,.TIF,.tiff", - "GDAL_CACHEMAX": "200", - "GDAL_DISABLE_READDIR_ON_OPEN": "EMPTY_DIR", - "GDAL_INGESTED_BYTES_AT_OPEN": "32768", - "GDAL_HTTP_MERGE_CONSECUTIVE_RANGES": "YES", - "GDAL_HTTP_MULTIPLEX": "YES", - "GDAL_HTTP_VERSION": "2", - "PYTHONWARNINGS": "ignore", - "VSI_CACHE": "TRUE", - "VSI_CACHE_SIZE": "5000000", - "DB_MIN_CONN_SIZE": "1", - "DB_MAX_CONN_SIZE": "1", - "PGSTAC_SECRET_ARN": props.dbSecret.secretArn, - } - - - this.titilerPgstacLambdaFunction = new lambda.Function(this, "lambda", { - handler: "handler.handler", + + + // if user provided environment variables, merge them with the defaults. + const apiEnv = props.apiEnv ? { ...defaultTitilerPgstacEnv, ...props.apiEnv, "PGSTAC_SECRET_ARN": props.dbSecret.secretArn } : defaultTitilerPgstacEnv; + + const apiCode = props.apiCode || { + entry: `${__dirname}/runtime`, + index: "src/handler.py", + handler: "handler", + }; + + this.titilerPgstacLambdaFunction = new PythonFunction(this, "titiler-pgstac-api", { + ...apiCode, runtime: lambda.Runtime.PYTHON_3_10, - code: props.titilerApiAsset ?? lambda.Code.fromDockerBuild(__dirname, { - file: "runtime/Dockerfile", - buildArgs: { PYTHON_VERSION: '3.10' }, - }), - timeout: Duration.seconds(30), + architecture: lambda.Architecture.X86_64, + environment: apiEnv, vpc: props.vpc, vpcSubnets: props.subnetSelection, allowPublicSubnet: true, - memorySize: props.titilerLambdaMemorySize ?? 3008, - logRetention: aws_logs.RetentionDays.ONE_WEEK, - environment: titilerPgstacEnv, - }); + memorySize: props.titilerLambdaMemorySize ?? defaultMemorySize, + logRetention: aws_logs.RetentionDays.ONE_WEEK + }) + + // this.titilerPgstacLambdaFunction = new lambda.Function(this, "lambda", { + // handler: "handler.handler", + // runtime: lambda.Runtime.PYTHON_3_10, + // code: props.titilerApiAsset ?? lambda.Code.fromDockerBuild(__dirname, { + // file: "runtime/Dockerfile", + // buildArgs: { PYTHON_VERSION: '3.10' }, + // }), + // timeout: Duration.seconds(30), + // vpc: props.vpc, + // vpcSubnets: props.subnetSelection, + // allowPublicSubnet: true, + // memorySize: props.titilerLambdaMemorySize ?? 3008, + // logRetention: aws_logs.RetentionDays.ONE_WEEK, + // environment: titilerPgstacEnv, + // }); // grant access to buckets using addToRolePolicy if (props.buckets) { @@ -105,8 +130,9 @@ import { readonly dbSecret: secretsmanager.ISecret; /** - * Customized environment variables to send to titiler-pgstac runtime. - */ + * Customized environment variables to send to titiler-pgstac runtime. These will be merged with `defaultTitilerPgstacEnv`. + * The database secret arn is automatically added to the environment variables at deployment. + /*/ readonly apiEnv?: Record; /** @@ -120,18 +146,31 @@ import { readonly titilerPgstacApiDomainName?: IDomainName; /** - * asset created by a docker build with the titiler pgstac application, - * can be produced with lambda.Code.fromDockerBuild. - * - * If undefined, the default application contained in the runtime folder will be used. - * - * @default - undefined + * Custom code to run for titiler-pgstac. + * + * @default - the app code in the `runtime` folder. */ - readonly titilerApiAsset?: lambda.AssetCode; - - + readonly apiCode?: TitilerPgstacEntrypoint; /** + * amount of memory to allocate to the lambda function. */ readonly titilerLambdaMemorySize?: number; } + + + + export interface TitilerPgstacEntrypoint { + /** + * Path to the source of the function or the location for dependencies. + */ + readonly entry: PythonFunctionProps["entry"]; + /** + * The path (relative to entry) to the index file containing the exported handler. + */ + readonly index: PythonFunctionProps["index"]; + /** + * The name of the exported handler in the index file. + */ + readonly handler: PythonFunctionProps["handler"]; + } diff --git a/lib/titiler-pgstac-api/runtime/Dockerfile b/lib/titiler-pgstac-api/runtime/Dockerfile deleted file mode 100644 index 54263ca..0000000 --- a/lib/titiler-pgstac-api/runtime/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -ARG PYTHON_VERSION - -FROM --platform=linux/amd64 public.ecr.aws/lambda/python:${PYTHON_VERSION} - -WORKDIR /tmp -RUN python -m pip install pip -U - -COPY runtime/requirements.txt requirements.txt -RUN python -m pip install -r requirements.txt "mangum>=0.14,<0.15" -t /asset - -# Reduce package size and remove useless files -RUN find /asset -type f -name '*.pyc' | while read f; do n=$(echo $f | sed 's/__pycache__\///' | sed 's/.cpython-[0-9]*//'); cp $f $n; done; -RUN find /asset -type d -name '__pycache__' -print0 | xargs -0 rm -rf -RUN find /asset -type f -name '*.py' -print0 | xargs -0 rm -f -RUN find /asset -type d -name 'tests' -print0 | xargs -0 rm -rf -RUN rm -rdf /asset/numpy/doc/ /asset/boto3* /asset/botocore* /asset/bin /asset/geos_license /asset/Misc - -COPY runtime/src/*.py /asset/ - -CMD ["echo", "hello world"] \ No newline at end of file diff --git a/lib/titiler-pgstac-api/runtime/dev_requirements.txt b/lib/titiler-pgstac-api/runtime/dev_requirements.txt index 400ebf5..5bb1c4c 100644 --- a/lib/titiler-pgstac-api/runtime/dev_requirements.txt +++ b/lib/titiler-pgstac-api/runtime/dev_requirements.txt @@ -1 +1,2 @@ -uvicorn \ No newline at end of file +uvicorn +boto3>=1.26.139 diff --git a/lib/titiler-pgstac-api/runtime/requirements.txt b/lib/titiler-pgstac-api/runtime/requirements.txt index 0659895..7a7838b 100644 --- a/lib/titiler-pgstac-api/runtime/requirements.txt +++ b/lib/titiler-pgstac-api/runtime/requirements.txt @@ -1,3 +1,3 @@ titiler.pgstac==0.5.1 -boto3>=1.26.139 psycopg[binary, pool] +mangum>=0.14,<0.15 diff --git a/lib/titiler-pgstac-api/runtime/src/handler.py b/lib/titiler-pgstac-api/runtime/src/handler.py index 2b5a987..23e8ed2 100644 --- a/lib/titiler-pgstac-api/runtime/src/handler.py +++ b/lib/titiler-pgstac-api/runtime/src/handler.py @@ -5,7 +5,7 @@ import asyncio import os from mangum import Mangum -from utils import get_secret_dict +from src.utils import get_secret_dict pgstac_secret_arn = os.environ["PGSTAC_SECRET_ARN"] From 12f307070bc462c47a6a38a96df028534ea44091 Mon Sep 17 00:00:00 2001 From: emileten Date: Mon, 4 Sep 2023 15:49:47 +0900 Subject: [PATCH 4/6] remove ref to duration --- lib/titiler-pgstac-api/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/titiler-pgstac-api/index.ts b/lib/titiler-pgstac-api/index.ts index 0b788ea..2a029f5 100644 --- a/lib/titiler-pgstac-api/index.ts +++ b/lib/titiler-pgstac-api/index.ts @@ -6,7 +6,6 @@ import { aws_lambda as lambda, aws_secretsmanager as secretsmanager, CfnOutput, - Duration, aws_logs, } from "aws-cdk-lib"; import {PythonFunction, PythonFunctionProps} from "@aws-cdk/aws-lambda-python-alpha"; From b2e882a5a02b04ba1818707a460656e8e79f9825 Mon Sep 17 00:00:00 2001 From: emileten Date: Mon, 4 Sep 2023 15:51:34 +0900 Subject: [PATCH 5/6] put back the duration --- lib/titiler-pgstac-api/index.ts | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/lib/titiler-pgstac-api/index.ts b/lib/titiler-pgstac-api/index.ts index 2a029f5..b4ad852 100644 --- a/lib/titiler-pgstac-api/index.ts +++ b/lib/titiler-pgstac-api/index.ts @@ -6,6 +6,7 @@ import { aws_lambda as lambda, aws_secretsmanager as secretsmanager, CfnOutput, + Duration, aws_logs, } from "aws-cdk-lib"; import {PythonFunction, PythonFunctionProps} from "@aws-cdk/aws-lambda-python-alpha"; @@ -58,25 +59,10 @@ import { vpcSubnets: props.subnetSelection, allowPublicSubnet: true, memorySize: props.titilerLambdaMemorySize ?? defaultMemorySize, - logRetention: aws_logs.RetentionDays.ONE_WEEK + logRetention: aws_logs.RetentionDays.ONE_WEEK, + timeout: Duration.seconds(30) }) - // this.titilerPgstacLambdaFunction = new lambda.Function(this, "lambda", { - // handler: "handler.handler", - // runtime: lambda.Runtime.PYTHON_3_10, - // code: props.titilerApiAsset ?? lambda.Code.fromDockerBuild(__dirname, { - // file: "runtime/Dockerfile", - // buildArgs: { PYTHON_VERSION: '3.10' }, - // }), - // timeout: Duration.seconds(30), - // vpc: props.vpc, - // vpcSubnets: props.subnetSelection, - // allowPublicSubnet: true, - // memorySize: props.titilerLambdaMemorySize ?? 3008, - // logRetention: aws_logs.RetentionDays.ONE_WEEK, - // environment: titilerPgstacEnv, - // }); - // grant access to buckets using addToRolePolicy if (props.buckets) { props.buckets.forEach(bucket => { From 9f31c319dee935f645633468b7ed1944491cbb2c Mon Sep 17 00:00:00 2001 From: emileten Date: Tue, 5 Sep 2023 16:01:08 +0900 Subject: [PATCH 6/6] wrap the python lambda settings that are optional in an interface to make things clearer and more configurable, add bundling --- lib/titiler-pgstac-api/index.ts | 62 ++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/lib/titiler-pgstac-api/index.ts b/lib/titiler-pgstac-api/index.ts index b4ad852..0a09fb0 100644 --- a/lib/titiler-pgstac-api/index.ts +++ b/lib/titiler-pgstac-api/index.ts @@ -8,8 +8,10 @@ import { CfnOutput, Duration, aws_logs, + BundlingOptions } from "aws-cdk-lib"; - import {PythonFunction, PythonFunctionProps} from "@aws-cdk/aws-lambda-python-alpha"; + import { Runtime } from 'aws-cdk-lib/aws-lambda'; + import {PythonFunction} from "@aws-cdk/aws-lambda-python-alpha"; import { IDomainName, HttpApi } from "@aws-cdk/aws-apigatewayv2-alpha"; import { HttpLambdaIntegration } from "@aws-cdk/aws-apigatewayv2-integrations-alpha"; import { Construct } from "constructs"; @@ -31,8 +33,6 @@ import { "DB_MAX_CONN_SIZE": "1" } - const defaultMemorySize = 3008; - export class TitilerPgstacApiLambda extends Construct { readonly url: string; public titilerPgstacLambdaFunction: lambda.Function; @@ -44,21 +44,21 @@ import { // if user provided environment variables, merge them with the defaults. const apiEnv = props.apiEnv ? { ...defaultTitilerPgstacEnv, ...props.apiEnv, "PGSTAC_SECRET_ARN": props.dbSecret.secretArn } : defaultTitilerPgstacEnv; - const apiCode = props.apiCode || { + const pythonLambdaOptions: TitilerPgstacPythonLambdaOptions = props.pythonLambdaOptions ?? { + runtime: lambda.Runtime.PYTHON_3_10, entry: `${__dirname}/runtime`, index: "src/handler.py", handler: "handler", - }; + memorySize: 3008, + architecture: lambda.Architecture.X86_64 + } this.titilerPgstacLambdaFunction = new PythonFunction(this, "titiler-pgstac-api", { - ...apiCode, - runtime: lambda.Runtime.PYTHON_3_10, - architecture: lambda.Architecture.X86_64, + ...pythonLambdaOptions, environment: apiEnv, vpc: props.vpc, vpcSubnets: props.subnetSelection, allowPublicSubnet: true, - memorySize: props.titilerLambdaMemorySize ?? defaultMemorySize, logRetention: aws_logs.RetentionDays.ONE_WEEK, timeout: Duration.seconds(30) }) @@ -127,35 +127,57 @@ import { /** * Custom Domain Name Options for Titiler Pgstac API, + * + * @default - undefined. */ readonly titilerPgstacApiDomainName?: IDomainName; /** - * Custom code to run for titiler-pgstac. + * Optional settings for the titiler-pgstac python lambda function. * - * @default - the app code in the `runtime` folder. + * @default - defined in the construct. */ - readonly apiCode?: TitilerPgstacEntrypoint; - /** + readonly pythonLambdaOptions?: TitilerPgstacPythonLambdaOptions; - * amount of memory to allocate to the lambda function. - */ - readonly titilerLambdaMemorySize?: number; } + export interface TitilerPgstacPythonLambdaOptions { - export interface TitilerPgstacEntrypoint { /** * Path to the source of the function or the location for dependencies. */ - readonly entry: PythonFunctionProps["entry"]; + readonly entry: string; + /** + * The runtime environment. Only runtimes of the Python family are + * supported. + */ + readonly runtime: Runtime; + /** * The path (relative to entry) to the index file containing the exported handler. + * */ - readonly index: PythonFunctionProps["index"]; + readonly index: string; /** * The name of the exported handler in the index file. */ - readonly handler: PythonFunctionProps["handler"]; + readonly handler: string; + + /** + * Bundling options to use for this function. Use this to specify custom bundling options like + * the bundling Docker image, asset hash type, custom hash, architecture, etc. + */ + readonly bundling?: BundlingOptions; + + /** + * The amount of memory, in MB, that is allocated to your Lambda function. + */ + readonly memorySize: number; + + /** + * The system architectures compatible with this lambda function. + */ + readonly architecture: lambda.Architecture; + }