Skip to content

Commit bf8263e

Browse files
authored
refactor: move db to construct (#527)
1 parent aa76dc1 commit bf8263e

File tree

5 files changed

+140
-128
lines changed

5 files changed

+140
-128
lines changed

cdk/my_service/service_construct.py renamed to cdk/my_service/api_construct.py

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from aws_cdk import aws_logs
66
from aws_cdk.aws_lambda_python_alpha import PythonLayerVersion
77
from constructs import Construct
8+
from my_service.api_db_construct import ApiDbConstruct # type: ignore
89

910
import cdk.my_service.constants as constants
1011

@@ -14,26 +15,12 @@ class ApiConstruct(Construct):
1415
def __init__(self, scope: Construct, id_: str, appconfig_app_name: str) -> None:
1516
super().__init__(scope, id_)
1617

17-
self.db = self._build_db(id_)
18-
self.lambda_role = self._build_lambda_role(self.db)
18+
self.api_db = ApiDbConstruct(self, f'{id_}db')
19+
self.lambda_role = self._build_lambda_role(self.api_db.db)
1920
self.common_layer = self._build_common_layer()
2021
self.rest_api = self._build_api_gw()
2122
api_resource: aws_apigateway.Resource = self.rest_api.root.add_resource('api').add_resource(constants.GW_RESOURCE)
22-
self.__add_post_lambda_integration(api_resource, self.lambda_role, self.db, appconfig_app_name)
23-
24-
def _build_db(self, id_prefix: str) -> dynamodb.Table:
25-
table_id = f'{id_prefix}{constants.TABLE_NAME}'
26-
table = dynamodb.Table(
27-
self,
28-
table_id,
29-
table_name=table_id,
30-
partition_key=dynamodb.Attribute(name='order_id', type=dynamodb.AttributeType.STRING),
31-
billing_mode=dynamodb.BillingMode.PAY_PER_REQUEST,
32-
point_in_time_recovery=True,
33-
removal_policy=RemovalPolicy.DESTROY,
34-
)
35-
CfnOutput(self, id=constants.TABLE_NAME_OUTPUT, value=table.table_name).override_logical_id(constants.TABLE_NAME_OUTPUT)
36-
return table
23+
self._add_post_lambda_integration(api_resource, self.lambda_role, self.api_db.db, appconfig_app_name)
3724

3825
def _build_api_gw(self) -> aws_apigateway.RestApi:
3926
rest_api: aws_apigateway.RestApi = aws_apigateway.RestApi(
@@ -50,7 +37,7 @@ def _build_api_gw(self) -> aws_apigateway.RestApi:
5037
def _build_lambda_role(self, db: dynamodb.Table) -> iam.Role:
5138
return iam.Role(
5239
self,
53-
constants.SERVICE_ROLE,
40+
'ServiceRole',
5441
assumed_by=iam.ServicePrincipal('lambda.amazonaws.com'),
5542
inline_policies={
5643
'dynamic_configuration':
@@ -62,12 +49,10 @@ def _build_lambda_role(self, db: dynamodb.Table) -> iam.Role:
6249
)
6350
]),
6451
'dynamodb_db':
65-
iam.PolicyDocument(
66-
statements=[iam.PolicyStatement(actions=['dynamodb:PutItem'], resources=[db.table_arn], effect=iam.Effect.ALLOW)]),
52+
iam.PolicyDocument(statements=[
53+
iam.PolicyStatement(actions=['dynamodb:PutItem', 'dynamodb:GetItem'], resources=[db.table_arn], effect=iam.Effect.ALLOW)
54+
]),
6755
},
68-
managed_policies=[
69-
iam.ManagedPolicy.from_aws_managed_policy_name(managed_policy_name=(f'service-role/{constants.LAMBDA_BASIC_EXECUTION_ROLE}'))
70-
],
7156
)
7257

7358
def _build_common_layer(self) -> PythonLayerVersion:
@@ -79,7 +64,7 @@ def _build_common_layer(self) -> PythonLayerVersion:
7964
removal_policy=RemovalPolicy.DESTROY,
8065
)
8166

82-
def __add_post_lambda_integration(self, api_name: aws_apigateway.Resource, role: iam.Role, db: dynamodb.Table, appconfig_app_name: str):
67+
def _add_post_lambda_integration(self, api_name: aws_apigateway.Resource, role: iam.Role, db: dynamodb.Table, appconfig_app_name: str):
8368
lambda_function = _lambda.Function(
8469
self,
8570
'ServicePost',

cdk/my_service/api_db_construct.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from aws_cdk import CfnOutput, RemovalPolicy
2+
from aws_cdk import aws_dynamodb as dynamodb
3+
from constructs import Construct
4+
5+
import cdk.my_service.constants as constants
6+
7+
8+
class ApiDbConstruct(Construct):
9+
10+
def __init__(self, scope: Construct, id_: str) -> None:
11+
super().__init__(scope, id_)
12+
13+
self.db: dynamodb.Table = self._build_db(id_)
14+
15+
def _build_db(self, id_prefix: str) -> dynamodb.Table:
16+
table_id = f'{id_prefix}{constants.TABLE_NAME}'
17+
table = dynamodb.Table(
18+
self,
19+
table_id,
20+
table_name=table_id,
21+
partition_key=dynamodb.Attribute(name='order_id', type=dynamodb.AttributeType.STRING),
22+
billing_mode=dynamodb.BillingMode.PAY_PER_REQUEST,
23+
point_in_time_recovery=True,
24+
removal_policy=RemovalPolicy.DESTROY,
25+
)
26+
CfnOutput(self, id=constants.TABLE_NAME_OUTPUT, value=table.table_name).override_logical_id(constants.TABLE_NAME_OUTPUT)
27+
return table

cdk/my_service/service_stack.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
from aws_cdk import Stack
55
from constructs import Construct
66
from git import Repo
7+
from my_service.api_construct import ApiConstruct # type: ignore
78

89
from cdk.my_service.configuration.configuration_construct import ConfigurationStore
910
from cdk.my_service.constants import CONFIGURATION_NAME, ENVIRONMENT, SERVICE_NAME
10-
from cdk.my_service.service_construct import ApiConstruct
1111

1212

1313
def get_stack_name() -> str:

docs/cdk.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ All ASW Lambda function configurations are saved as constants at the `cdk.my_ser
3838
### **Deployed Resources**
3939

4040
- AWS Cloudformation stack: **cdk.my_service.service_stack.py** which is consisted of one construct
41-
- Construct: **cdk.my_service.service_construct.py** which includes:
41+
- Construct: **cdk.my_service.api_construct.py** which includes:
4242
- **Lambda Layer** - deployment optimization meant to be used with multiple handlers under the same API GW, sharing code logic and dependencies. You can read more about it in Yan - Cui's [blog](https://medium.com/theburningmonk-com/lambda-layer-not-a-package-manager-but-a-deployment-optimization-85ddcae40a96){:target="_blank" rel="noopener"}
4343
- **Lambda Function** - The Lambda handler function itself. Handler code is taken from the service `folder`.
4444
- **Lambda Role** - The role of the Lambda function.
4545
- **API GW with Lambda Integration** - API GW with a Lambda integration POST /api/orders that triggers the Lambda function.
46-
- **AWS DynamoDB table** - stores request data
46+
- **AWS DynamoDB table** - stores request data. Created in its own construct: api_db_construct.py
4747

4848
### **CDK Tests**
4949

0 commit comments

Comments
 (0)