in 6-serverless-graphql-stack/backend/app_sync_cdk/app_sync_cdk_stack.py [0:0]
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
db_name = 'petclinic'
db_cluster = 'petclinic-serverless-graphql'
petclinic_graphql_api = CfnGraphQLApi(
self, 'PetClinicApi',
name='PetClinicApi',
authentication_type='API_KEY'
)
petclinic_graphql_key = CfnApiKey(
self, 'ItemsApiKey',
api_id=petclinic_graphql_api.attr_api_id
)
with open('./definition/petclinic.graphql', 'rt') as f:
schema_def = f.read()
petclinic_schema = CfnGraphQLSchema(
self, 'PetclinicSchema',
api_id=petclinic_graphql_api.attr_api_id,
definition=schema_def
)
serverless_rds_secret = Secret(
self, 'PetclinicRDSSecret',
generate_secret_string=SecretStringGenerator(
generate_string_key='password',
secret_string_template='{"username":"master"}',
exclude_characters= '"@/',
password_length=16
)
)
serverless_rds_cluster = CfnDBCluster(
self, 'PetclinicRDSServerless',
engine='aurora',
database_name=db_name,
db_cluster_identifier=db_cluster,
engine_mode='serverless',
master_username=serverless_rds_secret.secret_value_from_json('username').to_string(),
master_user_password=serverless_rds_secret.secret_value_from_json('password').to_string(),
scaling_configuration=CfnDBCluster.ScalingConfigurationProperty(
min_capacity=1,
max_capacity=2,
auto_pause=False
)
)
serverless_rds_cluster.apply_removal_policy(core.RemovalPolicy.DESTROY)
serverless_rds_arn='arn:aws:rds:' + self.region + ':' + self.account + ':cluster:' + db_cluster
website_bucket = Bucket(self, 'PetclinicWebsite',
website_index_document='index.html',
public_read_access=True,
removal_policy=core.RemovalPolicy.DESTROY
)
deployment = BucketDeployment(self, 'PetclinicDeployWebsite',
sources=[Source.asset('../frontend/public')],
destination_bucket=website_bucket,
retain_on_delete=False
#destination_key_prefix='web/static'
)
iam_policy = [PolicyStatement(
actions=["secretsmanager:GetSecretValue"],
effect=Effect.ALLOW,
resources=[serverless_rds_secret.secret_arn]
),PolicyStatement(
actions=["rds-data:ExecuteStatement",
"rds-data:DeleteItems",
"rds-data:ExecuteSql",
"rds-data:GetItems",
"rds-data:InsertItems",
"rds-data:UpdateItems"],
effect=Effect.ALLOW,
resources=[serverless_rds_arn, serverless_rds_arn + ':*']
),PolicyStatement(
actions=["rds:*"],
effect=Effect.ALLOW,
resources=[serverless_rds_arn, serverless_rds_arn + ':*']
),PolicyStatement(
actions=[ "s3:PutObject","s3:PutObjectAcl","s3:PutObjectVersionAcl","s3:GetObject"],
effect=Effect.ALLOW,
resources=[website_bucket.bucket_arn + "/*"]
),PolicyStatement(
actions=[ "s3:ListBucket"],
effect=Effect.ALLOW,
resources=[website_bucket.bucket_arn]
)]
init_resource = CustomResource(self, "PetlinicInitCustomResource",
provider=CustomResourceProvider.lambda_(
SingletonFunction(
self, "CustomResourceSingleton",
uuid="f7d4f730-4ee1-11e8-9c2d-fa7ae01bbebc",
code=Code.from_asset('./custom-resource-code'),
handler="index.handler",
timeout=core.Duration.seconds(600),
runtime=Runtime.PYTHON_3_7,
initial_policy=iam_policy
)
),
properties={
"DBClusterIdentifier": db_cluster,
"DBClusterArn": serverless_rds_arn,
"DBSecretArn": serverless_rds_secret.secret_arn,
"DBName": db_name,
"Bucket": website_bucket.bucket_name,
"GraphqlApi": petclinic_graphql_api.attr_graph_ql_url,
"GraphqlKey": petclinic_graphql_key.attr_api_key
}
)
petclinic_rds_role = Role(
self, 'PetclinicRDSRole',
assumed_by=ServicePrincipal('appsync.amazonaws.com')
)
petclinic_rds_role.add_to_policy(iam_policy[0])
petclinic_rds_role.add_to_policy(iam_policy[1])
data_source = CfnDataSource(
self, 'PetclinicRDSDatesource',
api_id=petclinic_graphql_api.attr_api_id,
type='RELATIONAL_DATABASE',
name='PetclinicRDSDatesource',
relational_database_config=CfnDataSource.RelationalDatabaseConfigProperty(
relational_database_source_type='RDS_HTTP_ENDPOINT',
rds_http_endpoint_config=CfnDataSource.RdsHttpEndpointConfigProperty(
aws_region=self.region,
aws_secret_store_arn=serverless_rds_secret.secret_arn,
database_name='petclinic',
db_cluster_identifier=serverless_rds_arn
)
),
service_role_arn=petclinic_rds_role.role_arn
)
data_source.add_depends_on(petclinic_schema)
data_source.add_depends_on(serverless_rds_cluster)
query_req_path = './definition/template/query/request/'
query_res_path = './definition/template/query/response/'
for req_file in os.listdir(query_req_path):
query_name = req_file.split('.')[0]
with open(query_req_path + req_file, 'rt') as f:
query_req = f.read()
with open(query_res_path + query_name + '.vm', 'rt') as f:
query_res = f.read()
pettypes_resolver = CfnResolver(
self, query_name,
api_id=petclinic_graphql_api.attr_api_id,
type_name='Query',
field_name=query_name,
data_source_name=data_source.name,
request_mapping_template=query_req,
response_mapping_template=query_res
)
pettypes_resolver.add_depends_on(data_source)
func_dict = {}
func_req_path = './definition/template/function/request/'
func_res_path = './definition/template/function/response/'
for req_file in os.listdir(func_req_path):
func_name = req_file.split('.')[0]
with open(func_req_path + req_file) as f:
func_req = f.read()
with open(func_res_path + func_name + '.vm') as f:
func_res = f.read()
func_dict[func_name] = CfnFunctionConfiguration(
self, func_name,
api_id=petclinic_graphql_api.attr_api_id,
data_source_name=data_source.name,
name=func_name,
function_version='2018-05-29',
request_mapping_template=func_req,
response_mapping_template=func_res
)
func_dict[func_name].add_depends_on(data_source)
query_owner = CfnResolver(
self, 'QueryOnwer',
api_id=petclinic_graphql_api.attr_api_id,
kind='PIPELINE',
type_name='Query',
field_name='owner',
request_mapping_template="{}",
response_mapping_template="$util.toJson($ctx.result)",
pipeline_config=CfnResolver.PipelineConfigProperty(
functions=[func_dict['Query_Owner_getOwnerById'].attr_function_id,
func_dict['Query_Owner_getPetsByOwner'].attr_function_id,
func_dict['Query_Owner_getVistsByPet'].attr_function_id]
)
)
query_owner.add_depends_on(func_dict['Query_Owner_getOwnerById'])
query_owner.add_depends_on(func_dict['Query_Owner_getPetsByOwner'])
query_owner.add_depends_on(func_dict['Query_Owner_getVistsByPet'])
query_all_owners = CfnResolver(
self, 'QueryAllOnwers',
api_id=petclinic_graphql_api.attr_api_id,
kind='PIPELINE',
type_name='Query',
field_name='owners',
request_mapping_template="{}",
response_mapping_template="$util.toJson($ctx.result)",
pipeline_config=CfnResolver.PipelineConfigProperty(
functions=[func_dict['Query_Owners_getAllOwners'].attr_function_id,
func_dict['Query_Owners_getPetsByOwner'].attr_function_id]
)
)
query_all_owners.add_depends_on(func_dict['Query_Owners_getAllOwners'])
query_all_owners.add_depends_on(func_dict['Query_Owners_getPetsByOwner'])
query_pet = CfnResolver(
self, 'QueryPet',
api_id=petclinic_graphql_api.attr_api_id,
kind='PIPELINE',
type_name='Query',
field_name='pet',
request_mapping_template="{}",
response_mapping_template="$util.toJson($ctx.result)",
pipeline_config=CfnResolver.PipelineConfigProperty(
functions=[func_dict['Query_Pet_getPetById'].attr_function_id,
func_dict['Query_Pet_getVisitByPet'].attr_function_id]
)
)
query_pet.add_depends_on(func_dict['Query_Pet_getPetById'])
query_pet.add_depends_on(func_dict['Query_Pet_getVisitByPet'])
query_vets = CfnResolver(
self, 'QueryVets',
api_id=petclinic_graphql_api.attr_api_id,
kind='PIPELINE',
type_name='Query',
field_name='vets',
request_mapping_template="{}",
response_mapping_template="$util.toJson($ctx.result)",
pipeline_config=CfnResolver.PipelineConfigProperty(
functions=[func_dict['Query_Vets_getVets'].attr_function_id,
func_dict['Query_Vets_getSpecByVets'].attr_function_id]
)
)
query_vets.add_depends_on(func_dict['Query_Vets_getVets'])
query_vets.add_depends_on(func_dict['Query_Vets_getSpecByVets'])
mutation_req_path = './definition/template/mutation/request/'
mutation_res_path = './definition/template/mutation/response/'
for req_file in os.listdir(mutation_req_path):
mutation_name = req_file.split('.')[0]
with open(mutation_req_path + req_file) as f:
func_req = f.read()
with open(mutation_res_path + mutation_name + '.vm') as f:
func_res = f.read()
mutation = CfnResolver(
self, mutation_name,
api_id=petclinic_graphql_api.attr_api_id,
type_name='Mutation',
field_name=mutation_name,
data_source_name=data_source.name,
request_mapping_template=func_req,
response_mapping_template=func_res
)
mutation.add_depends_on(data_source)
core.CfnOutput(self,"GraphqlPetclinicWebsiteUrl",export_name="GraphqlPetclinicWebsiteUrl",value=website_bucket.bucket_website_url)