From 3ecd2e94707d2e828a834da71f815f7dec8e9c0a Mon Sep 17 00:00:00 2001 From: "James S. Abreu Mieses" Date: Sat, 4 Nov 2023 02:43:10 -0400 Subject: [PATCH 01/12] Initial commit --- deployment/aws/cdk/read.14868.1.lock | 1 + 1 file changed, 1 insertion(+) create mode 100644 deployment/aws/cdk/read.14868.1.lock diff --git a/deployment/aws/cdk/read.14868.1.lock b/deployment/aws/cdk/read.14868.1.lock new file mode 100644 index 00000000..b947cf73 --- /dev/null +++ b/deployment/aws/cdk/read.14868.1.lock @@ -0,0 +1 @@ +14868 \ No newline at end of file From 6907a329ff199c6300cfa4e0b7bf244957dba512 Mon Sep 17 00:00:00 2001 From: James S Abrue Mieses Date: Sat, 4 Nov 2023 20:51:25 -0700 Subject: [PATCH 02/12] Class for private api construct added --- .gitignore | 1 + deployment/aws/cdk/app.py | 64 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/.gitignore b/.gitignore index 95640297..4dabfc96 100644 --- a/.gitignore +++ b/.gitignore @@ -108,3 +108,4 @@ ENV/ cdk.out/ deployment/k8s/titiler/values-test.yaml docs/src/api/ +.idea diff --git a/deployment/aws/cdk/app.py b/deployment/aws/cdk/app.py index 3317d842..2f8dc0d7 100644 --- a/deployment/aws/cdk/app.py +++ b/deployment/aws/cdk/app.py @@ -11,13 +11,77 @@ from aws_cdk import aws_iam as iam from aws_cdk import aws_lambda from aws_cdk import aws_logs as logs +from aws_cdk.aws_apigateway import ( + EndpointConfiguration, + EndpointType, + LambdaIntegration, + RestApi, +) from aws_cdk.aws_apigatewayv2_integrations_alpha import HttpLambdaIntegration +from aws_cdk.aws_iam import PolicyDocument from config import StackSettings from constructs import Construct settings = StackSettings() +class TitilerPrivateApiStack(Stack): + """ + Titiler Private API Stack + + Private api configuration for titiler. + + author: @jeandsmith + """ + + def __init__( + self, + scope: Construct, + id: str, + memory: int = 1024, + timeout: int = 30, + runtime: aws_lambda.Runtime = aws_lambda.Runtime.PYTHON_3_11, + concurrent: Optional[int] = None, + permissions: Optional[List[iam.PolicyStatement]] = None, + environment: Optional[Dict] = None, + code_dir: str = "./", + **kwargs: Any, + ) -> None: + """Define the stack""" + super().__init__(scope, id, **kwargs) + + permissions = permissions or [] + environment = environment or {} + + lambda_function = aws_lambda.Function( + self, + f"{id}-lambda", + runtime=runtime, + code=aws_lambda.Code.from_docker_build( + path=os.path.abspath(code_dir), + file="lambda/Dockerfile", + ), + handler="handler.handler", + memory_size=memory, + reserved_concurrent_executions=concurrent, + timeout=Duration.seconds(timeout), + environment=environment, + log_retention=logs.RetentionDays.ONE_WEEK, + ) + + for perm in permissions: + lambda_function.add_to_role_policy(perm) + + api = RestApi( + self, + f"{id}-endpoint", + default_integration=LambdaIntegration(handler=lambda_function), + policy=PolicyDocument(statements=[]), + endpoint_configuration=EndpointConfiguration(types=[EndpointType.PRIVATE]), + ) + CfnOutput(self, "Endpoint", value=api.url) + + class titilerLambdaStack(Stack): """ Titiler Lambda Stack From 77eb387c173ae006b98da25cda2e4a3c3b30323f Mon Sep 17 00:00:00 2001 From: James S Abrue Mieses Date: Sat, 4 Nov 2023 20:58:50 -0700 Subject: [PATCH 03/12] Added private api policy --- deployment/aws/cdk/app.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/deployment/aws/cdk/app.py b/deployment/aws/cdk/app.py index 2f8dc0d7..0cf2a00a 100644 --- a/deployment/aws/cdk/app.py +++ b/deployment/aws/cdk/app.py @@ -18,7 +18,7 @@ RestApi, ) from aws_cdk.aws_apigatewayv2_integrations_alpha import HttpLambdaIntegration -from aws_cdk.aws_iam import PolicyDocument +from aws_cdk.aws_iam import Effect, PolicyDocument, PolicyStatement from config import StackSettings from constructs import Construct @@ -76,7 +76,19 @@ def __init__( self, f"{id}-endpoint", default_integration=LambdaIntegration(handler=lambda_function), - policy=PolicyDocument(statements=[]), + policy=PolicyDocument( + statements=[ + PolicyStatement( + effect=Effect.ALLOW, + actions=["execute-api:*"], + resources=[ + Stack.of(self).format_arn( + service="execute-api", resource="*" + ) + ], + ) + ] + ), endpoint_configuration=EndpointConfiguration(types=[EndpointType.PRIVATE]), ) CfnOutput(self, "Endpoint", value=api.url) From bdffe5bc1668a9ffb9eb3e5631968a7243d95e55 Mon Sep 17 00:00:00 2001 From: James S Abrue Mieses Date: Sun, 5 Nov 2023 00:50:06 -0400 Subject: [PATCH 04/12] Getting into testing --- deployment/aws/cdk.json | 2 +- deployment/aws/cdk/app.py | 42 +++++++++++++++++++++++++----------- deployment/aws/cdk/config.py | 3 +++ 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/deployment/aws/cdk.json b/deployment/aws/cdk.json index 57cc60ce..bcc9682d 100644 --- a/deployment/aws/cdk.json +++ b/deployment/aws/cdk.json @@ -1,3 +1,3 @@ { - "app": "python3 cdk/app.py" + "app": "python cdk/app.py" } diff --git a/deployment/aws/cdk/app.py b/deployment/aws/cdk/app.py index 0cf2a00a..c7c6cfd3 100644 --- a/deployment/aws/cdk/app.py +++ b/deployment/aws/cdk/app.py @@ -1,7 +1,7 @@ """Construct App.""" import os -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional, Union, cast from aws_cdk import App, CfnOutput, Duration, Stack, Tags from aws_cdk import aws_apigatewayv2_alpha as apigw @@ -27,9 +27,9 @@ class TitilerPrivateApiStack(Stack): """ - Titiler Private API Stack + Titiler Private API Stack - Private api configuration for titiler. + Private api configuration for titiler. author: @jeandsmith """ @@ -38,13 +38,14 @@ def __init__( self, scope: Construct, id: str, + vpc_endpoint_id: str, memory: int = 1024, timeout: int = 30, runtime: aws_lambda.Runtime = aws_lambda.Runtime.PYTHON_3_11, + code_dir: str = "./", concurrent: Optional[int] = None, permissions: Optional[List[iam.PolicyStatement]] = None, environment: Optional[Dict] = None, - code_dir: str = "./", **kwargs: Any, ) -> None: """Define the stack""" @@ -75,18 +76,24 @@ def __init__( api = RestApi( self, f"{id}-endpoint", - default_integration=LambdaIntegration(handler=lambda_function), + default_integration=LambdaIntegration( + handler=cast(aws_lambda.IFunction, lambda_function) + ), policy=PolicyDocument( statements=[ + PolicyStatement( + effect=Effect.DENY, + actions=["execute-api:Invoke"], + resources=["execute-api:/*/*/*"], + conditions={ + "StringNotEquals": {"aws:sourceVpcId": vpc_endpoint_id} + }, + ), PolicyStatement( effect=Effect.ALLOW, - actions=["execute-api:*"], - resources=[ - Stack.of(self).format_arn( - service="execute-api", resource="*" - ) - ], - ) + actions=["execute-api:Invoke"], + resources=["execute-api:/*/*/*"], + ), ] ), endpoint_configuration=EndpointConfiguration(types=[EndpointType.PRIVATE]), @@ -251,6 +258,16 @@ def __init__( ) ) +private_api = TitilerPrivateApiStack( + app, + f"{settings.name}-private-api-{settings.stage}", + vpc_endpoint_id=settings.vpc_endpoint_id, + memory=settings.memory, + timeout=settings.timeout, + concurrent=settings.max_concurrent, + permissions=perms, + environment=settings.env, +) ecs_stack = titilerECSStack( app, @@ -273,6 +290,7 @@ def __init__( environment=settings.env, ) + # Tag infrastructure for key, value in { "Project": settings.name, diff --git a/deployment/aws/cdk/config.py b/deployment/aws/cdk/config.py index d3fe0f15..0a90e2b4 100644 --- a/deployment/aws/cdk/config.py +++ b/deployment/aws/cdk/config.py @@ -85,4 +85,7 @@ class StackSettings(BaseSettings): # Default: - No specific limit - account limit. max_concurrent: Optional[int] = None + # The VPC Endpoint ID + vpc_endpoint_id = "vpce-0af2022ccaaea117f" + model_config = SettingsConfigDict(env_prefix="TITILER_STACK_", env_file=".env") From 9dcca76098e21b1ff21f81d2710e455eaa8f097a Mon Sep 17 00:00:00 2001 From: James S Abrue Mieses Date: Sun, 5 Nov 2023 12:51:23 -0500 Subject: [PATCH 05/12] Policy fixes & config fix --- deployment/aws/cdk/app.py | 17 ++++++++++++++--- deployment/aws/cdk/config.py | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/deployment/aws/cdk/app.py b/deployment/aws/cdk/app.py index c7c6cfd3..3879a4cc 100644 --- a/deployment/aws/cdk/app.py +++ b/deployment/aws/cdk/app.py @@ -84,20 +84,30 @@ def __init__( PolicyStatement( effect=Effect.DENY, actions=["execute-api:Invoke"], - resources=["execute-api:/*/*/*"], + resources=[ + Stack.of(self).format_arn( + service="execute-api", resource="*" + ) + ], conditions={ - "StringNotEquals": {"aws:sourceVpcId": vpc_endpoint_id} + "StringNotEquals": {"aws:SourceVpce": vpc_endpoint_id} }, ), PolicyStatement( effect=Effect.ALLOW, actions=["execute-api:Invoke"], - resources=["execute-api:/*/*/*"], + resources=[ + Stack.of(self).format_arn( + service="execute-api", resource="*" + ) + ], ), ] ), endpoint_configuration=EndpointConfiguration(types=[EndpointType.PRIVATE]), ) + api.root.add_proxy() + CfnOutput(self, "Endpoint", value=api.url) @@ -301,6 +311,7 @@ def __init__( if value: Tags.of(ecs_stack).add(key, value) Tags.of(lambda_stack).add(key, value) + Tags.of(private_api).add(key, value) app.synth() diff --git a/deployment/aws/cdk/config.py b/deployment/aws/cdk/config.py index 0a90e2b4..e18683de 100644 --- a/deployment/aws/cdk/config.py +++ b/deployment/aws/cdk/config.py @@ -86,6 +86,6 @@ class StackSettings(BaseSettings): max_concurrent: Optional[int] = None # The VPC Endpoint ID - vpc_endpoint_id = "vpce-0af2022ccaaea117f" + vpc_endpoint_id: str = "{{VPCE_ID}}" model_config = SettingsConfigDict(env_prefix="TITILER_STACK_", env_file=".env") From 85fb44aea39199fe2dc23bc14a871feeadbf8e41 Mon Sep 17 00:00:00 2001 From: "James S. Abreu Mieses" Date: Mon, 6 Nov 2023 11:41:00 -0500 Subject: [PATCH 06/12] Fix to policy --- deployment/aws/cdk/app.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/deployment/aws/cdk/app.py b/deployment/aws/cdk/app.py index 3879a4cc..c96f4c6a 100644 --- a/deployment/aws/cdk/app.py +++ b/deployment/aws/cdk/app.py @@ -18,7 +18,7 @@ RestApi, ) from aws_cdk.aws_apigatewayv2_integrations_alpha import HttpLambdaIntegration -from aws_cdk.aws_iam import Effect, PolicyDocument, PolicyStatement +from aws_cdk.aws_iam import Effect, PolicyDocument, PolicyStatement, AnyPrincipal from config import StackSettings from constructs import Construct @@ -82,6 +82,7 @@ def __init__( policy=PolicyDocument( statements=[ PolicyStatement( + principals=[AnyPrincipal()], effect=Effect.DENY, actions=["execute-api:Invoke"], resources=[ @@ -94,6 +95,7 @@ def __init__( }, ), PolicyStatement( + principals=[AnyPrincipal()], effect=Effect.ALLOW, actions=["execute-api:Invoke"], resources=[ From b9693422515f06bbfa11083f648bb06494842ac3 Mon Sep 17 00:00:00 2001 From: "James S. Abreu Mieses" Date: Mon, 6 Nov 2023 11:44:35 -0500 Subject: [PATCH 07/12] Resource perm fix --- deployment/aws/cdk/app.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/deployment/aws/cdk/app.py b/deployment/aws/cdk/app.py index c96f4c6a..5c13749c 100644 --- a/deployment/aws/cdk/app.py +++ b/deployment/aws/cdk/app.py @@ -86,9 +86,7 @@ def __init__( effect=Effect.DENY, actions=["execute-api:Invoke"], resources=[ - Stack.of(self).format_arn( - service="execute-api", resource="*" - ) + "execute-api:*" ], conditions={ "StringNotEquals": {"aws:SourceVpce": vpc_endpoint_id} From 1b59a28f11ef8c1b9bff868a198504c7c20f0b7f Mon Sep 17 00:00:00 2001 From: "James S. Abreu Mieses" Date: Mon, 6 Nov 2023 11:48:38 -0500 Subject: [PATCH 08/12] Private api done --- deployment/aws/cdk/app.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/deployment/aws/cdk/app.py b/deployment/aws/cdk/app.py index 5c13749c..ee052ed1 100644 --- a/deployment/aws/cdk/app.py +++ b/deployment/aws/cdk/app.py @@ -86,7 +86,9 @@ def __init__( effect=Effect.DENY, actions=["execute-api:Invoke"], resources=[ - "execute-api:*" + Stack.of(self).format_arn( + service="execute-api", resource="*" + ) ], conditions={ "StringNotEquals": {"aws:SourceVpce": vpc_endpoint_id} From 74e9a968e617a4309b62d08ed5492db6e73136d1 Mon Sep 17 00:00:00 2001 From: "James S. Abreu Mieses" Date: Mon, 6 Nov 2023 11:52:33 -0500 Subject: [PATCH 09/12] Lint --- deployment/aws/cdk.json | 2 +- deployment/aws/cdk/app.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deployment/aws/cdk.json b/deployment/aws/cdk.json index bcc9682d..57cc60ce 100644 --- a/deployment/aws/cdk.json +++ b/deployment/aws/cdk.json @@ -1,3 +1,3 @@ { - "app": "python cdk/app.py" + "app": "python3 cdk/app.py" } diff --git a/deployment/aws/cdk/app.py b/deployment/aws/cdk/app.py index ee052ed1..d22d111f 100644 --- a/deployment/aws/cdk/app.py +++ b/deployment/aws/cdk/app.py @@ -18,7 +18,7 @@ RestApi, ) from aws_cdk.aws_apigatewayv2_integrations_alpha import HttpLambdaIntegration -from aws_cdk.aws_iam import Effect, PolicyDocument, PolicyStatement, AnyPrincipal +from aws_cdk.aws_iam import AnyPrincipal, Effect, PolicyDocument, PolicyStatement from config import StackSettings from constructs import Construct @@ -86,7 +86,7 @@ def __init__( effect=Effect.DENY, actions=["execute-api:Invoke"], resources=[ - Stack.of(self).format_arn( + Stack.of(self).format_arn( service="execute-api", resource="*" ) ], From d3302f0fdf39418c294a72df706f76db2384c4b0 Mon Sep 17 00:00:00 2001 From: James S Abrue Mieses Date: Tue, 7 Nov 2023 08:10:48 -0500 Subject: [PATCH 10/12] Move private api to it own file, made vpce config optional & removed read artifact --- deployment/aws/cdk/app.py | 99 +--------------- deployment/aws/cdk/config.py | 2 +- deployment/aws/cdk/constructs/__init__.py | 1 + deployment/aws/cdk/constructs/private_api.py | 116 +++++++++++++++++++ deployment/aws/cdk/read.14868.1.lock | 1 - 5 files changed, 121 insertions(+), 98 deletions(-) create mode 100644 deployment/aws/cdk/constructs/__init__.py create mode 100644 deployment/aws/cdk/constructs/private_api.py delete mode 100644 deployment/aws/cdk/read.14868.1.lock diff --git a/deployment/aws/cdk/app.py b/deployment/aws/cdk/app.py index d22d111f..c3d85058 100644 --- a/deployment/aws/cdk/app.py +++ b/deployment/aws/cdk/app.py @@ -1,7 +1,7 @@ """Construct App.""" import os -from typing import Any, Dict, List, Optional, Union, cast +from typing import Any, Dict, List, Optional, Union from aws_cdk import App, CfnOutput, Duration, Stack, Tags from aws_cdk import aws_apigatewayv2_alpha as apigw @@ -11,106 +11,13 @@ from aws_cdk import aws_iam as iam from aws_cdk import aws_lambda from aws_cdk import aws_logs as logs -from aws_cdk.aws_apigateway import ( - EndpointConfiguration, - EndpointType, - LambdaIntegration, - RestApi, -) from aws_cdk.aws_apigatewayv2_integrations_alpha import HttpLambdaIntegration -from aws_cdk.aws_iam import AnyPrincipal, Effect, PolicyDocument, PolicyStatement from config import StackSettings from constructs import Construct -settings = StackSettings() - - -class TitilerPrivateApiStack(Stack): - """ - Titiler Private API Stack - - Private api configuration for titiler. - - author: @jeandsmith - """ +from deployment.aws.cdk.constructs.private_api import TitilerPrivateApiStack - def __init__( - self, - scope: Construct, - id: str, - vpc_endpoint_id: str, - memory: int = 1024, - timeout: int = 30, - runtime: aws_lambda.Runtime = aws_lambda.Runtime.PYTHON_3_11, - code_dir: str = "./", - concurrent: Optional[int] = None, - permissions: Optional[List[iam.PolicyStatement]] = None, - environment: Optional[Dict] = None, - **kwargs: Any, - ) -> None: - """Define the stack""" - super().__init__(scope, id, **kwargs) - - permissions = permissions or [] - environment = environment or {} - - lambda_function = aws_lambda.Function( - self, - f"{id}-lambda", - runtime=runtime, - code=aws_lambda.Code.from_docker_build( - path=os.path.abspath(code_dir), - file="lambda/Dockerfile", - ), - handler="handler.handler", - memory_size=memory, - reserved_concurrent_executions=concurrent, - timeout=Duration.seconds(timeout), - environment=environment, - log_retention=logs.RetentionDays.ONE_WEEK, - ) - - for perm in permissions: - lambda_function.add_to_role_policy(perm) - - api = RestApi( - self, - f"{id}-endpoint", - default_integration=LambdaIntegration( - handler=cast(aws_lambda.IFunction, lambda_function) - ), - policy=PolicyDocument( - statements=[ - PolicyStatement( - principals=[AnyPrincipal()], - effect=Effect.DENY, - actions=["execute-api:Invoke"], - resources=[ - Stack.of(self).format_arn( - service="execute-api", resource="*" - ) - ], - conditions={ - "StringNotEquals": {"aws:SourceVpce": vpc_endpoint_id} - }, - ), - PolicyStatement( - principals=[AnyPrincipal()], - effect=Effect.ALLOW, - actions=["execute-api:Invoke"], - resources=[ - Stack.of(self).format_arn( - service="execute-api", resource="*" - ) - ], - ), - ] - ), - endpoint_configuration=EndpointConfiguration(types=[EndpointType.PRIVATE]), - ) - api.root.add_proxy() - - CfnOutput(self, "Endpoint", value=api.url) +settings = StackSettings() class titilerLambdaStack(Stack): diff --git a/deployment/aws/cdk/config.py b/deployment/aws/cdk/config.py index e18683de..a57b12b1 100644 --- a/deployment/aws/cdk/config.py +++ b/deployment/aws/cdk/config.py @@ -86,6 +86,6 @@ class StackSettings(BaseSettings): max_concurrent: Optional[int] = None # The VPC Endpoint ID - vpc_endpoint_id: str = "{{VPCE_ID}}" + vpc_endpoint_id: None | str = None model_config = SettingsConfigDict(env_prefix="TITILER_STACK_", env_file=".env") diff --git a/deployment/aws/cdk/constructs/__init__.py b/deployment/aws/cdk/constructs/__init__.py new file mode 100644 index 00000000..878c11c3 --- /dev/null +++ b/deployment/aws/cdk/constructs/__init__.py @@ -0,0 +1 @@ +"""Constructs Custom Package""" diff --git a/deployment/aws/cdk/constructs/private_api.py b/deployment/aws/cdk/constructs/private_api.py new file mode 100644 index 00000000..92b1562b --- /dev/null +++ b/deployment/aws/cdk/constructs/private_api.py @@ -0,0 +1,116 @@ +"""Private API Construct""" + +import os +from typing import Any, Dict, List, Optional, cast + +from aws_cdk import CfnOutput, Duration, Stack +from aws_cdk.aws_apigateway import ( + EndpointConfiguration, + EndpointType, + LambdaIntegration, + RestApi, +) +from aws_cdk.aws_iam import AnyPrincipal, Effect, PolicyDocument, PolicyStatement +from aws_cdk.aws_lambda import Code, Function, IFunction, Runtime +from aws_cdk.aws_logs import RetentionDays +from constructs import Construct + + +class TitilerPrivateApiStack(Stack): + """ + Titiler Private API Stack + + Private api configuration for titiler. + + author: @jeandsmith + """ + + def __init__( + self, + scope: Construct, + id: str, + vpc_endpoint_id: None | str, + memory: int = 1024, + timeout: int = 30, + runtime: Runtime = Runtime.PYTHON_3_11, + code_dir: str = "./", + concurrent: Optional[int] = None, + permissions: Optional[List[PolicyStatement]] = None, + environment: Optional[Dict] = None, + **kwargs: Any, + ) -> None: + """Define the stack""" + super().__init__(scope, id, **kwargs) + + permissions = permissions or [] + environment = environment or {} + + lambda_function = Function( + self, + f"{id}-lambda", + runtime=runtime, + code=Code.from_docker_build( + path=os.path.abspath(code_dir), + file="lambda/Dockerfile", + ), + handler="handler.handler", + memory_size=memory, + reserved_concurrent_executions=concurrent, + timeout=Duration.seconds(timeout), + environment=environment, + log_retention=RetentionDays.ONE_WEEK, + ) + + for perm in permissions: + lambda_function.add_to_role_policy(perm) + + policy = ( + PolicyDocument( + statements=[ + PolicyStatement( + principals=[AnyPrincipal()], + effect=Effect.DENY, + actions=["execute-api:Invoke"], + resources=[ + Stack.of(self).format_arn( + service="execute-api", resource="*" + ) + ], + conditions={ + "StringNotEquals": {"aws:SourceVpce": vpc_endpoint_id} + }, + ), + PolicyStatement( + principals=[AnyPrincipal()], + effect=Effect.ALLOW, + actions=["execute-api:Invoke"], + resources=[ + Stack.of(self).format_arn( + service="execute-api", resource="*" + ) + ], + ), + ] + ) + if vpc_endpoint_id + else None + ) + + endpoint_config = ( + EndpointConfiguration(types=[EndpointType.PRIVATE]) + if vpc_endpoint_id + else EndpointConfiguration(types=[EndpointType.REGIONAL]) + ) + + api = RestApi( + self, + f"{id}-endpoint", + default_integration=LambdaIntegration( + handler=cast(IFunction, lambda_function) + ), + policy=policy, + endpoint_configuration=endpoint_config, + ) + api.root.add_proxy() + + CfnOutput(self, "Endpoint", value=api.url) diff --git a/deployment/aws/cdk/read.14868.1.lock b/deployment/aws/cdk/read.14868.1.lock deleted file mode 100644 index b947cf73..00000000 --- a/deployment/aws/cdk/read.14868.1.lock +++ /dev/null @@ -1 +0,0 @@ -14868 \ No newline at end of file From c1ea8b9d9229bc295c04db0b14c9594486785481 Mon Sep 17 00:00:00 2001 From: James S Abrue Mieses Date: Tue, 7 Nov 2023 08:22:35 -0500 Subject: [PATCH 11/12] Renamed constructs to construct directory Name was conflicting with constructs package --- deployment/aws/cdk.json | 2 +- deployment/aws/cdk/__init__.py | 2 +- deployment/aws/cdk/app.py | 3 +- deployment/aws/cdk/constructs/__init__.py | 1 - deployment/aws/cdk/constructs/private_api.py | 116 ------------------- 5 files changed, 3 insertions(+), 121 deletions(-) delete mode 100644 deployment/aws/cdk/constructs/__init__.py delete mode 100644 deployment/aws/cdk/constructs/private_api.py diff --git a/deployment/aws/cdk.json b/deployment/aws/cdk.json index 57cc60ce..bcc9682d 100644 --- a/deployment/aws/cdk.json +++ b/deployment/aws/cdk.json @@ -1,3 +1,3 @@ { - "app": "python3 cdk/app.py" + "app": "python cdk/app.py" } diff --git a/deployment/aws/cdk/__init__.py b/deployment/aws/cdk/__init__.py index 4955682f..82806b39 100644 --- a/deployment/aws/cdk/__init__.py +++ b/deployment/aws/cdk/__init__.py @@ -1 +1 @@ -"""AWS App.""" +"""AWS App""" diff --git a/deployment/aws/cdk/app.py b/deployment/aws/cdk/app.py index c3d85058..a082e8aa 100644 --- a/deployment/aws/cdk/app.py +++ b/deployment/aws/cdk/app.py @@ -13,10 +13,9 @@ from aws_cdk import aws_logs as logs from aws_cdk.aws_apigatewayv2_integrations_alpha import HttpLambdaIntegration from config import StackSettings +from construct.private_api import TitilerPrivateApiStack from constructs import Construct -from deployment.aws.cdk.constructs.private_api import TitilerPrivateApiStack - settings = StackSettings() diff --git a/deployment/aws/cdk/constructs/__init__.py b/deployment/aws/cdk/constructs/__init__.py deleted file mode 100644 index 878c11c3..00000000 --- a/deployment/aws/cdk/constructs/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Constructs Custom Package""" diff --git a/deployment/aws/cdk/constructs/private_api.py b/deployment/aws/cdk/constructs/private_api.py deleted file mode 100644 index 92b1562b..00000000 --- a/deployment/aws/cdk/constructs/private_api.py +++ /dev/null @@ -1,116 +0,0 @@ -"""Private API Construct""" - -import os -from typing import Any, Dict, List, Optional, cast - -from aws_cdk import CfnOutput, Duration, Stack -from aws_cdk.aws_apigateway import ( - EndpointConfiguration, - EndpointType, - LambdaIntegration, - RestApi, -) -from aws_cdk.aws_iam import AnyPrincipal, Effect, PolicyDocument, PolicyStatement -from aws_cdk.aws_lambda import Code, Function, IFunction, Runtime -from aws_cdk.aws_logs import RetentionDays -from constructs import Construct - - -class TitilerPrivateApiStack(Stack): - """ - Titiler Private API Stack - - Private api configuration for titiler. - - author: @jeandsmith - """ - - def __init__( - self, - scope: Construct, - id: str, - vpc_endpoint_id: None | str, - memory: int = 1024, - timeout: int = 30, - runtime: Runtime = Runtime.PYTHON_3_11, - code_dir: str = "./", - concurrent: Optional[int] = None, - permissions: Optional[List[PolicyStatement]] = None, - environment: Optional[Dict] = None, - **kwargs: Any, - ) -> None: - """Define the stack""" - super().__init__(scope, id, **kwargs) - - permissions = permissions or [] - environment = environment or {} - - lambda_function = Function( - self, - f"{id}-lambda", - runtime=runtime, - code=Code.from_docker_build( - path=os.path.abspath(code_dir), - file="lambda/Dockerfile", - ), - handler="handler.handler", - memory_size=memory, - reserved_concurrent_executions=concurrent, - timeout=Duration.seconds(timeout), - environment=environment, - log_retention=RetentionDays.ONE_WEEK, - ) - - for perm in permissions: - lambda_function.add_to_role_policy(perm) - - policy = ( - PolicyDocument( - statements=[ - PolicyStatement( - principals=[AnyPrincipal()], - effect=Effect.DENY, - actions=["execute-api:Invoke"], - resources=[ - Stack.of(self).format_arn( - service="execute-api", resource="*" - ) - ], - conditions={ - "StringNotEquals": {"aws:SourceVpce": vpc_endpoint_id} - }, - ), - PolicyStatement( - principals=[AnyPrincipal()], - effect=Effect.ALLOW, - actions=["execute-api:Invoke"], - resources=[ - Stack.of(self).format_arn( - service="execute-api", resource="*" - ) - ], - ), - ] - ) - if vpc_endpoint_id - else None - ) - - endpoint_config = ( - EndpointConfiguration(types=[EndpointType.PRIVATE]) - if vpc_endpoint_id - else EndpointConfiguration(types=[EndpointType.REGIONAL]) - ) - - api = RestApi( - self, - f"{id}-endpoint", - default_integration=LambdaIntegration( - handler=cast(IFunction, lambda_function) - ), - policy=policy, - endpoint_configuration=endpoint_config, - ) - api.root.add_proxy() - - CfnOutput(self, "Endpoint", value=api.url) From 8eee4d664d8410e19e5aaf2ed26a95c16575037d Mon Sep 17 00:00:00 2001 From: James S Abrue Mieses Date: Tue, 7 Nov 2023 08:23:14 -0500 Subject: [PATCH 12/12] Tracking construct dir --- deployment/aws/cdk/construct/__init__.py | 1 + deployment/aws/cdk/construct/private_api.py | 116 ++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 deployment/aws/cdk/construct/__init__.py create mode 100644 deployment/aws/cdk/construct/private_api.py diff --git a/deployment/aws/cdk/construct/__init__.py b/deployment/aws/cdk/construct/__init__.py new file mode 100644 index 00000000..878c11c3 --- /dev/null +++ b/deployment/aws/cdk/construct/__init__.py @@ -0,0 +1 @@ +"""Constructs Custom Package""" diff --git a/deployment/aws/cdk/construct/private_api.py b/deployment/aws/cdk/construct/private_api.py new file mode 100644 index 00000000..92b1562b --- /dev/null +++ b/deployment/aws/cdk/construct/private_api.py @@ -0,0 +1,116 @@ +"""Private API Construct""" + +import os +from typing import Any, Dict, List, Optional, cast + +from aws_cdk import CfnOutput, Duration, Stack +from aws_cdk.aws_apigateway import ( + EndpointConfiguration, + EndpointType, + LambdaIntegration, + RestApi, +) +from aws_cdk.aws_iam import AnyPrincipal, Effect, PolicyDocument, PolicyStatement +from aws_cdk.aws_lambda import Code, Function, IFunction, Runtime +from aws_cdk.aws_logs import RetentionDays +from constructs import Construct + + +class TitilerPrivateApiStack(Stack): + """ + Titiler Private API Stack + + Private api configuration for titiler. + + author: @jeandsmith + """ + + def __init__( + self, + scope: Construct, + id: str, + vpc_endpoint_id: None | str, + memory: int = 1024, + timeout: int = 30, + runtime: Runtime = Runtime.PYTHON_3_11, + code_dir: str = "./", + concurrent: Optional[int] = None, + permissions: Optional[List[PolicyStatement]] = None, + environment: Optional[Dict] = None, + **kwargs: Any, + ) -> None: + """Define the stack""" + super().__init__(scope, id, **kwargs) + + permissions = permissions or [] + environment = environment or {} + + lambda_function = Function( + self, + f"{id}-lambda", + runtime=runtime, + code=Code.from_docker_build( + path=os.path.abspath(code_dir), + file="lambda/Dockerfile", + ), + handler="handler.handler", + memory_size=memory, + reserved_concurrent_executions=concurrent, + timeout=Duration.seconds(timeout), + environment=environment, + log_retention=RetentionDays.ONE_WEEK, + ) + + for perm in permissions: + lambda_function.add_to_role_policy(perm) + + policy = ( + PolicyDocument( + statements=[ + PolicyStatement( + principals=[AnyPrincipal()], + effect=Effect.DENY, + actions=["execute-api:Invoke"], + resources=[ + Stack.of(self).format_arn( + service="execute-api", resource="*" + ) + ], + conditions={ + "StringNotEquals": {"aws:SourceVpce": vpc_endpoint_id} + }, + ), + PolicyStatement( + principals=[AnyPrincipal()], + effect=Effect.ALLOW, + actions=["execute-api:Invoke"], + resources=[ + Stack.of(self).format_arn( + service="execute-api", resource="*" + ) + ], + ), + ] + ) + if vpc_endpoint_id + else None + ) + + endpoint_config = ( + EndpointConfiguration(types=[EndpointType.PRIVATE]) + if vpc_endpoint_id + else EndpointConfiguration(types=[EndpointType.REGIONAL]) + ) + + api = RestApi( + self, + f"{id}-endpoint", + default_integration=LambdaIntegration( + handler=cast(IFunction, lambda_function) + ), + policy=policy, + endpoint_configuration=endpoint_config, + ) + api.root.add_proxy() + + CfnOutput(self, "Endpoint", value=api.url)