Skip to content

Commit eeecc36

Browse files
committed
implement backent into cdk
1 parent 06affcc commit eeecc36

File tree

11 files changed

+248
-0
lines changed

11 files changed

+248
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ __pycache__
2121
# LocalStack
2222

2323
volume/
24+
.idea

app.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env python3
2+
import os
3+
4+
import aws_cdk as cdk
5+
6+
from quiz_app.quiz_app_stack import QuizAppStack
7+
8+
9+
app = cdk.App()
10+
QuizAppStack(app, "QuizAppStack",
11+
# If you don't specify 'env', this stack will be environment-agnostic.
12+
# Account/Region-dependent features and context lookups will not work,
13+
# but a single synthesized template can be deployed anywhere.
14+
15+
# Uncomment the next line to specialize this stack for the AWS Account
16+
# and Region that are implied by the current CLI configuration.
17+
18+
#env=cdk.Environment(account=os.getenv('CDK_DEFAULT_ACCOUNT'), region=os.getenv('CDK_DEFAULT_REGION')),
19+
20+
# Uncomment the next line if you know exactly what Account and Region you
21+
# want to deploy the stack to. */
22+
23+
#env=cdk.Environment(account='123456789012', region='us-east-1'),
24+
25+
# For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html
26+
)
27+
28+
app.synth()

cdk.json

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
{
2+
"app": "python3 app.py",
3+
"watch": {
4+
"include": [
5+
"**"
6+
],
7+
"exclude": [
8+
"README.md",
9+
"cdk*.json",
10+
"requirements*.txt",
11+
"source.bat",
12+
"**/__init__.py",
13+
"**/__pycache__",
14+
"tests"
15+
]
16+
},
17+
"context": {
18+
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
19+
"@aws-cdk/core:checkSecretUsage": true,
20+
"@aws-cdk/core:target-partitions": [
21+
"aws",
22+
"aws-cn"
23+
],
24+
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
25+
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
26+
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
27+
"@aws-cdk/aws-iam:minimizePolicies": true,
28+
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
29+
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
30+
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
31+
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
32+
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
33+
"@aws-cdk/core:enablePartitionLiterals": true,
34+
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
35+
"@aws-cdk/aws-iam:standardizedServicePrincipals": true,
36+
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
37+
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
38+
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
39+
"@aws-cdk/aws-route53-patters:useCertificate": true,
40+
"@aws-cdk/customresources:installLatestAwsSdkDefault": false,
41+
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
42+
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
43+
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
44+
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
45+
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
46+
"@aws-cdk/aws-redshift:columnId": true,
47+
"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
48+
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
49+
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
50+
"@aws-cdk/aws-kms:aliasNameRef": true,
51+
"@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true,
52+
"@aws-cdk/core:includePrefixInUniqueNameGeneration": true,
53+
"@aws-cdk/aws-efs:denyAnonymousAccess": true,
54+
"@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true,
55+
"@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true,
56+
"@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true,
57+
"@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true,
58+
"@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true,
59+
"@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true,
60+
"@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true,
61+
"@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true,
62+
"@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true,
63+
"@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true,
64+
"@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true
65+
}
66+
}

quiz_app/__init__.py

Whitespace-only changes.

quiz_app/quiz_app_stack.py

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import json
2+
from pathlib import Path
3+
from tty import CFLAG
4+
5+
import aws_cdk
6+
from aws_cdk import (
7+
# Duration,
8+
Stack,
9+
aws_sqs as sqs,
10+
aws_dynamodb as dynamodb,
11+
aws_iam as iam,
12+
aws_lambda as _lambda,
13+
CfnOutput as Output
14+
)
15+
from constructs import Construct
16+
17+
class QuizAppStack(Stack):
18+
19+
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
20+
super().__init__(scope, construct_id, **kwargs)
21+
22+
# TABLES
23+
quizzes_table = dynamodb.Table(
24+
self,
25+
"QuizzesTable",
26+
table_name="Quizzes",
27+
partition_key=dynamodb.Attribute(
28+
name="QuizID",
29+
type=dynamodb.AttributeType.STRING,
30+
),
31+
billing_mode=dynamodb.BillingMode.PROVISIONED,
32+
read_capacity=5,
33+
write_capacity=5,
34+
)
35+
36+
user_submissions_table = dynamodb.Table(
37+
self,
38+
"UserSubmissionsTable",
39+
table_name="UserSubmissions",
40+
partition_key=dynamodb.Attribute(
41+
name="SubmissionID",
42+
type=dynamodb.AttributeType.STRING,
43+
),
44+
billing_mode=dynamodb.BillingMode.PROVISIONED,
45+
read_capacity=5,
46+
write_capacity=5,
47+
)
48+
user_submissions_table.add_global_secondary_index(
49+
index_name="QuizID-Score-index",
50+
partition_key=dynamodb.Attribute(
51+
name="QuizID",
52+
type=dynamodb.AttributeType.STRING,
53+
),
54+
sort_key=dynamodb.Attribute(
55+
name="Score",
56+
type=dynamodb.AttributeType.NUMBER,
57+
),
58+
projection_type=dynamodb.ProjectionType.ALL,
59+
read_capacity=5,
60+
write_capacity=5,
61+
)
62+
63+
Output(self, "QuizTable", value=quizzes_table.table_name)
64+
Output(self, "UserSubmissionsTable", value=user_submissions_table.table_name)
65+
66+
67+
functions_and_roles = [
68+
("CreateQuizFunction","configurations/create_quiz_policy.json","CreateQuizRole", "lambdas/get_quiz/handler.py"),
69+
("GetQuizFunction","configurations/get_quiz_policy.json","GetQuizRole", "lambdas/get_quiz/handler.py"),
70+
("SubmitQuizFunction","configurations/submit_quiz_policy.json", "SubmitQuizRole", "lambdas/submit_quiz/handler.py"),
71+
("ScoringFunction", "configurations/scoring_policy.json", "ScoringRole", "lambdas/scoring/handler.py"),
72+
("GetSubmissionFunction", "configurations/get_submission_policy.json", "GetSubmissionRole", "lambdas/get_submission/handler.py"),
73+
("GetLeaderboardFunction", "configurations/get_leaderboard_policy.json", "GetLeaderboardRole", "lambdas/get_leaderboard/handler.py"),
74+
("ListPublicQuizzesFunction", "configurations/list_quizzes_policy.json", "ListQuizzesRole", "lambdas/list_quizzes/handler.py"),
75+
("RetryQuizzesWritesFunction","configurations/retry_quizzes_writes_policy.json", "RetryQuizzesWritesRole", "lambdas/retry_quizzes_writes/handler.py"),
76+
]
77+
78+
for function_info in functions_and_roles:
79+
80+
function_name, policy_file_path, role_name, handler_path = function_info
81+
policy_json = self.read_policy_file(f"../{policy_file_path}")
82+
policy_document = iam.PolicyDocument.from_json(policy_json)
83+
84+
policy = iam.ManagedPolicy(
85+
self,
86+
"FunctionPolicy",
87+
managed_policy_name=f"{function_name}Policy",
88+
document=policy_document,
89+
)
90+
91+
role = iam.Role(
92+
self,
93+
"LambdaExecutionRole",
94+
role_name=role_name,
95+
assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
96+
description=f"Role for Lambda function {function_name}",
97+
)
98+
99+
# Attach the policy to the role
100+
role.add_managed_policy(policy)
101+
102+
_lambda.Function(
103+
self,
104+
"LambdaFunction",
105+
function_name=function_name,
106+
runtime=_lambda.Runtime.PYTHON_3_11,
107+
handler="handler.lambda_handler",
108+
code=_lambda.Code.from_asset(handler_path),
109+
role=role,
110+
timeout=aws_cdk.Duration.seconds(30),
111+
)
112+
113+
sqs.Queue(scope, "QuizSubmissionQueue", queue_name="QuizSubmissionQueue")
114+
115+
@staticmethod
116+
def read_policy_file(file_path: str) -> dict:
117+
"""Reads a JSON policy file and returns it as a dictionary."""
118+
file_path = Path(file_path)
119+
if not file_path.exists():
120+
raise FileNotFoundError(f"Policy file not found: {file_path}")
121+
with open(file_path, "r") as file:
122+
return json.load(file)

requirements-dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pytest==6.2.5

requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
aws-cdk-lib==2.136.0
2+
constructs>=10.0.0,<11.0.0

source.bat

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@echo off
2+
3+
rem The sole purpose of this script is to make the command
4+
rem
5+
rem source .venv/bin/activate
6+
rem
7+
rem (which activates a Python virtualenv on Linux or Mac OS X) work on Windows.
8+
rem On Windows, this command just runs this batch file (the argument is ignored).
9+
rem
10+
rem Now we don't need to document a Windows command for activating a virtualenv.
11+
12+
echo Executing .venv\Scripts\activate.bat for you
13+
.venv\Scripts\activate.bat

tests/__init__.py

Whitespace-only changes.

tests/unit/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)