def _build_api(self, *, stack): self.api = appsync.GraphqlApi(stack, 'exampleapi', name="examplegraphqlapi", log_config=appsync.LogConfig(field_log_level=appsync.FieldLogLevel.ALL), schema=appsync.Schema.from_asset(file_path="../appsync-conf/schema.graphql") ) self.api_key = appsync.CfnApiKey(stack, 'examplegraphqlapi', api_id=self.api.api_id )
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # Create a new AppSync GraphQL API api = appsync.GraphQLApi( self, 'Api', name="demoapi", log_config=appsync.LogConfig( field_log_level=appsync.FieldLogLevel.ALL), schema_definition_file="schema/schema.graphql") api_key = appsync.CfnApiKey(self, 'the-simple-graphql-service-api-key', api_id=api.api_id) # Create new DynamoDB Table for Customer customer_table = dynamo_db.Table( self, "CustomerTable", partition_key=dynamo_db.Attribute( name="id", type=dynamo_db.AttributeType.STRING)) # Add Customer DynamoDB as a Datasource for the Graphql API. customer_ds = api.add_dynamo_db_data_source( 'Customer', 'The customer data source', customer_table) # Query Resolver to get all Customers customer_ds.create_resolver( type_name='Query', field_name='getCustomers', request_mapping_template=appsync.MappingTemplate. dynamo_db_scan_table(), response_mapping_template=appsync.MappingTemplate. dynamo_db_result_list(), ) # Query Resolver to get an individual Customer by their id customer_ds.create_resolver( type_name='Query', field_name='getCustomer', request_mapping_template=appsync.MappingTemplate. dynamo_db_get_item('id', 'id'), response_mapping_template=appsync.MappingTemplate. dynamo_db_result_item(), ) # Mutation Resolver for adding a new Customer customer_ds.create_resolver( type_name='Mutation', field_name='addCustomer', request_mapping_template=appsync.MappingTemplate. dynamo_db_put_item(key=appsync.PrimaryKey.partition('id').auto(), values=appsync.Values.projecting('customer')), response_mapping_template=appsync.MappingTemplate. dynamo_db_result_item()) # Mutation Resolver for updating an existing Customer customer_ds.create_resolver( type_name='Mutation', field_name='saveCustomer', request_mapping_template=appsync.MappingTemplate. dynamo_db_put_item( key=appsync.PrimaryKey.partition('id').is_('id'), values=appsync.Values.projecting('customer')), response_mapping_template=appsync.MappingTemplate. dynamo_db_result_item()) # Mutation resolver for creating a new customer along with their first order customer_ds.create_resolver( type_name='Mutation', field_name='saveCustomerWithFirstOrder', request_mapping_template=appsync.MappingTemplate. dynamo_db_put_item( key=appsync.PrimaryKey.partition('order').auto().sort( 'customer').is_('customer.id'), values=appsync.Values.projecting('order').attribute( 'referral').is_('referral')), response_mapping_template=appsync.MappingTemplate. dynamo_db_result_item()) # Mutation Resolver for deleting an existing Customer customer_ds.create_resolver( type_name='Mutation', field_name='removeCustomer', request_mapping_template=appsync.MappingTemplate. dynamo_db_delete_item('id', 'id'), response_mapping_template=appsync.MappingTemplate. dynamo_db_result_item(), ) # defines an AWS Lambda resource loyalty_lambda = _lambda.Function( self, "LoyaltyLambdaHandler", runtime=_lambda.Runtime.NODEJS_12_X, handler="loyalty.handler", code=_lambda.Code.from_asset("lambda_fns"), ) # Add Loyalty Lambda as a Datasource for the Graphql API. loyalty_ds = api.add_lambda_data_source('Loyalty', 'The loyalty data source', loyalty_lambda) # Query Resolver to get all Customers loyalty_ds.create_resolver( type_name='Query', field_name='getLoyaltyLevel', request_mapping_template=appsync.MappingTemplate.lambda_request(), response_mapping_template=appsync.MappingTemplate.lambda_result(), ) # GraphQL API Endpoint core.CfnOutput(self, 'Endpoint', value=api.graph_ql_url) # API Key core.CfnOutput(self, 'API_Key', value=api_key.attr_api_key)
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) # store dynamodb_table = dynamodb.Table( self, 'dynamodb_table', table_name=f'{PROJECT}_{STAGE}', partition_key=dynamodb.Attribute( name='date', type=dynamodb.AttributeType.STRING), billing_mode=dynamodb.BillingMode.PAY_PER_REQUEST, point_in_time_recovery=False, removal_policy=core.RemovalPolicy.DESTROY, server_side_encryption=True, ) # public api public_api = appsync.CfnGraphQLApi( self, 'public_api', name=f'{PROJECT}_{STAGE}', authentication_type='API_KEY', ) now = time.localtime() epoch = time.mktime(now) public_api_key = appsync.CfnApiKey( self, 'public_api_key', api_id=public_api.attr_api_id, expires=epoch + core.Duration.days(90).to_seconds(), ) with open('schema.gql', mode='r') as f: graphql_schema = f.read() appsync.CfnGraphQLSchema(self, 'public_api_schema', api_id=public_api.attr_api_id, definition=graphql_schema) public_api_role = iam.Role( self, 'public_api_role', assumed_by=iam.ServicePrincipal('appsync.amazonaws.com'), managed_policies=[ iam.ManagedPolicy.from_aws_managed_policy_name( 'AmazonDynamoDBFullAccess') ], ) public_api_datasource = appsync.CfnDataSource( self, 'public_api_datasource', api_id=public_api.attr_api_id, name=f'{PROJECT}_{STAGE}_dynamodb', type='AMAZON_DYNAMODB', dynamo_db_config={ 'awsRegion': 'us-east-1', 'tableName': dynamodb_table.table_name, }, service_role_arn=public_api_role.role_arn, ) with open('mapping_templates/get_holiday.json', mode='r') as f: get_holiday_json = f.read() appsync.CfnResolver( self, 'public_api_resolver_get_holiday', api_id=public_api.attr_api_id, type_name='Query', field_name='getHoliday', data_source_name=public_api_datasource.attr_name, kind='UNIT', request_mapping_template=get_holiday_json, response_mapping_template='$util.toJson($context.result)', ) with open('mapping_templates/list_holidays.json', mode='r') as f: list_holidays_json = f.read() appsync.CfnResolver( self, 'public_api_resolver_list_holidays', api_id=public_api.attr_api_id, type_name='Query', field_name='listHolidays', data_source_name=public_api_datasource.attr_name, kind='UNIT', request_mapping_template=list_holidays_json, response_mapping_template='$util.toJson($context.result)', ) # lambda source code upload to s3 lambda_assets = s3_assets.Asset(self, 'lambda_assets', path='./function/.artifact/') # update function func_api = lambda_.Function( self, f'{PROJECT}-{STAGE}-func', function_name=f'{PROJECT}-{STAGE}-func', code=lambda_.Code.from_bucket(bucket=lambda_assets.bucket, key=lambda_assets.s3_object_key), handler='app.handler', runtime=lambda_.Runtime.PYTHON_3_7, timeout=core.Duration.seconds(120), log_retention=logs.RetentionDays.SIX_MONTHS, memory_size=128, tracing=lambda_.Tracing.ACTIVE, ) func_api.add_environment('TABLE_NAME', dynamodb_table.table_name) func_api.add_environment('CSV_URL', CSV_URL) func_api.add_to_role_policy( iam.PolicyStatement( actions=[ 'dynamodb:Get*', 'dynamodb:Put*', 'dynamodb:Batch*', ], resources=[dynamodb_table.table_arn], )) # schedule execute events.Rule( self, f'{PROJECT}-{STAGE}-schedule', enabled=True, schedule=events.Schedule.rate(core.Duration.days(10)), targets=[events_targets.LambdaFunction(func_api)], ) # lambda@edge func_lambdaedge = lambda_.Function( self, f'{PROJECT}-{STAGE}-func-lambdaedge', function_name=f'{PROJECT}-{STAGE}-func-lambdaedge', code=lambda_.Code.from_inline( open('./function/src/lambdaedge.py').read().replace( '__X_API_KEY__', public_api_key.attr_api_key)), handler='index.handler', runtime=lambda_.Runtime.PYTHON_3_7, timeout=core.Duration.seconds(30), memory_size=128, role=iam.Role( self, f'{PROJECT}-{STAGE}-func-lambdaedge-role', assumed_by=iam.CompositePrincipal( iam.ServicePrincipal('edgelambda.amazonaws.com'), iam.ServicePrincipal('lambda.amazonaws.com'), ), managed_policies=[ iam.ManagedPolicy.from_aws_managed_policy_name( 'service-role/AWSLambdaBasicExecutionRole'), ], ), ) lambdaedge_version = func_lambdaedge.add_version( hashlib.sha256( open('./function/src/lambdaedge.py').read().replace( '__X_API_KEY__', public_api_key.attr_api_key).encode()).hexdigest()) # ACM certificates = acm.Certificate( self, 'certificates', domain_name=DOMAIN, validation_method=acm.ValidationMethod.DNS, ) # CDN cdn = cloudfront.CloudFrontWebDistribution( self, f'{PROJECT}-{STAGE}-cloudfront', origin_configs=[ cloudfront.SourceConfiguration( behaviors=[ # default behavior cloudfront.Behavior( allowed_methods=cloudfront. CloudFrontAllowedMethods.ALL, default_ttl=core.Duration.seconds(0), max_ttl=core.Duration.seconds(0), min_ttl=core.Duration.seconds(0), is_default_behavior=True, lambda_function_associations=[ cloudfront.LambdaFunctionAssociation( event_type=cloudfront.LambdaEdgeEventType. ORIGIN_REQUEST, lambda_function=lambdaedge_version, ), ]) ], custom_origin_source=cloudfront.CustomOriginConfig( domain_name=core.Fn.select( 2, core.Fn.split('/', public_api.attr_graph_ql_url)), ), ) ], alias_configuration=cloudfront.AliasConfiguration( acm_cert_ref=certificates.certificate_arn, names=[DOMAIN], security_policy=cloudfront.SecurityPolicyProtocol. TLS_V1_2_2018, ), price_class=cloudfront.PriceClass.PRICE_CLASS_ALL, ) core.CfnOutput( self, 'cloudfront-domain', value=cdn.domain_name, )
def __init__(self, scope: core.Construct, id: str, vpc_id: str, subnet_ids, rds_secret_arn: str, **kwargs) -> None: super().__init__(scope, id, **kwargs) vpc = ec2.Vpc.from_vpc_attributes(self, vpc_id, vpc_id=vpc_id, availability_zones= [ 'eu-west-1c'], public_subnet_ids= subnet_ids) # creating vote table for dynamodb resolver vote_table = ddb.Table(self, 'votes', table_name='votes', partition_key={ "name": "productid", "type": ddb.AttributeType.STRING }, # Sortkey structure is like : UP#20200902T12:34:00 - DOWN#20201030T10:45:12 sort_key={ "name": "votesortkey", "type": ddb.AttributeType.STRING }, read_capacity=5, write_capacity=5 ) # creating API with GraphQL schema api = appsync.GraphqlApi(self, 'example_appsync_api', name="example_appsync_api", log_config=appsync.LogConfig(field_log_level=appsync.FieldLogLevel.ALL), schema=appsync.Schema.from_asset(file_path="../appsync-conf/schema.graphql") ) # Authentication done with API key - for development purposes only appsync.CfnApiKey(self, 'examplegraphqlapi', api_id=api.api_id ) # create security group for lambda # this will need to be added to your RDS inbound lambda_security_group = ec2.SecurityGroup(self, "Example-AppSyncResolverLambdaSG", security_group_name="Example-AppSyncResolverLambdaSG", vpc=vpc, allow_all_outbound=True ) # getting the code from local directory lambda_rds_code = aws_lambda.Code.asset("../lambda-rds") lambda_rds_resolver = aws_lambda.Function(self, "LambdaAppSyncSQLResolver", function_name=f"LambdaAppSyncSQLResolver", code=lambda_rds_code, handler="index.handler", runtime=aws_lambda.Runtime.NODEJS_12_X, memory_size=512, timeout=core.Duration.seconds(60), log_retention=logs.RetentionDays.ONE_MONTH, vpc=vpc, vpc_subnets={ "subnet_type": ec2.SubnetType.PUBLIC }, allow_public_subnet=True, security_group=lambda_security_group, ) # env parameters for rds lambda to perform SQL calls lambda_rds_resolver.add_environment("SECRET_ARN", rds_secret_arn) # allow lambda to read secret lambda_rds_resolver.add_to_role_policy(iam.PolicyStatement( effect=iam.Effect.ALLOW, actions=[ 'secretsmanager:GetSecretValue' ], resources=[ rds_secret_arn ] )) # adding the product datasource as lamda resolver products_ds = api.add_lambda_data_source('Products', lambda_rds_resolver) # creates resolver for query getProduct products_ds.create_resolver( type_name='Query', field_name='getProduct', request_mapping_template=appsync.MappingTemplate.from_file("../appsync-conf/vtl/getProduct.vtl"), response_mapping_template=appsync.MappingTemplate.from_file("../appsync-conf/vtl/getProduct_output_template.vtl"), ) # adding lamda resolver for vote fields in product model lambda_dynamodb_code = aws_lambda.Code.asset("../lambda-dynamodb") lambda_dynamodb_votes_resolver = aws_lambda.Function(self, "LambdaAppSyncVotesResolver", function_name=f"LambdaAppSyncVotesResolver", code=lambda_dynamodb_code, handler="index.handler", runtime=aws_lambda.Runtime.NODEJS_12_X, memory_size=512, timeout=core.Duration.seconds(60), ) # allow lambda to query dynamodb lambda_dynamodb_votes_resolver.add_to_role_policy(iam.PolicyStatement( effect=iam.Effect.ALLOW, actions=[ "dynamodb:GetItem", "dynamodb:Query", ], resources=[ vote_table.table_arn, vote_table.table_arn + "/*" ] )); # create lambda datasource for dynamodb queries votes_ds = api.add_lambda_data_source('Votes', lambda_dynamodb_votes_resolver) votes_ds.create_resolver( type_name='Product', field_name='ups', request_mapping_template=appsync.MappingTemplate.from_file("../appsync-conf/vtl/fields/votes_up.vtl"), response_mapping_template=appsync.MappingTemplate.from_file("../appsync-conf/vtl/fields/votes_up_output_template.vtl"), ) votes_ds.create_resolver( type_name='Product', field_name='downs', request_mapping_template=appsync.MappingTemplate.from_file("../appsync-conf/vtl/fields/votes_down.vtl"), response_mapping_template=appsync.MappingTemplate.from_file("../appsync-conf/vtl/fields/votes_down_output_template.vtl"), )