Esempio n. 1
0
    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        table_name = 'items'

        items_graphql_api = CfnGraphQLApi(self,
                                          'ItemsApi',
                                          name='items-api',
                                          authentication_type='API_KEY')

        CfnApiKey(self, 'ItemsApiKey', api_id=items_graphql_api.attr_api_id)

        api_schema = CfnGraphQLSchema(self,
                                      'ItemsSchema',
                                      api_id=items_graphql_api.attr_api_id,
                                      definition=f"""\
                type {table_name} {{
                    {table_name}Id: ID!
                    name: String
                }}
                type Paginated{table_name} {{
                    items: [{table_name}!]!
                    nextToken: String
                }}
                type Query {{
                    all(limit: Int, nextToken: String): Paginated{table_name}!
                    getOne({table_name}Id: ID!): {table_name}
                }}
                type Mutation {{
                    save(name: String!): {table_name}
                    delete({table_name}Id: ID!): {table_name}
                }}
                type Schema {{
                    query: Query
                    mutation: Mutation
                }}""")

        items_table = Table(
            self,
            'ItemsTable',
            table_name=table_name,
            partition_key=Attribute(name=f'{table_name}Id',
                                    type=AttributeType.STRING),
            billing_mode=BillingMode.PAY_PER_REQUEST,
            stream=StreamViewType.NEW_IMAGE,

            # The default removal policy is RETAIN, which means that cdk
            # destroy will not attempt to delete the new table, and it will
            # remain in your account until manually deleted. By setting the
            # policy to DESTROY, cdk destroy will delete the table (even if it
            # has data in it)
            removal_policy=core.RemovalPolicy.
            DESTROY  # NOT recommended for production code
        )

        items_table_role = Role(
            self,
            'ItemsDynamoDBRole',
            assumed_by=ServicePrincipal('appsync.amazonaws.com'))

        items_table_role.add_managed_policy(
            ManagedPolicy.from_aws_managed_policy_name(
                'AmazonDynamoDBFullAccess'))

        data_source = CfnDataSource(
            self,
            'ItemsDataSource',
            api_id=items_graphql_api.attr_api_id,
            name='ItemsDynamoDataSource',
            type='AMAZON_DYNAMODB',
            dynamo_db_config=CfnDataSource.DynamoDBConfigProperty(
                table_name=items_table.table_name, aws_region=self.region),
            service_role_arn=items_table_role.role_arn)

        get_one_resolver = CfnResolver(
            self,
            'GetOneQueryResolver',
            api_id=items_graphql_api.attr_api_id,
            type_name='Query',
            field_name='getOne',
            data_source_name=data_source.name,
            request_mapping_template=f"""\
            {{
                "version": "2017-02-28",
                "operation": "GetItem",
                "key": {{
                "{table_name}Id": $util.dynamodb.toDynamoDBJson($ctx.args.{table_name}Id)
                }}
            }}""",
            response_mapping_template="$util.toJson($ctx.result)")

        get_one_resolver.add_depends_on(api_schema)

        get_all_resolver = CfnResolver(
            self,
            'GetAllQueryResolver',
            api_id=items_graphql_api.attr_api_id,
            type_name='Query',
            field_name='all',
            data_source_name=data_source.name,
            request_mapping_template=f"""\
            {{
                "version": "2017-02-28",
                "operation": "Scan",
                "limit": $util.defaultIfNull($ctx.args.limit, 20),
                "nextToken": $util.toJson($util.defaultIfNullOrEmpty($ctx.args.nextToken, null))
            }}""",
            response_mapping_template="$util.toJson($ctx.result)")

        get_all_resolver.add_depends_on(api_schema)

        save_resolver = CfnResolver(
            self,
            'SaveMutationResolver',
            api_id=items_graphql_api.attr_api_id,
            type_name='Mutation',
            field_name='save',
            data_source_name=data_source.name,
            request_mapping_template=f"""\
            {{
                "version": "2017-02-28",
                "operation": "PutItem",
                "key": {{
                    "{table_name}Id": {{ "S": "$util.autoId()" }}
                }},
                "attributeValues": {{
                    "name": $util.dynamodb.toDynamoDBJson($ctx.args.name)
                }}
            }}""",
            response_mapping_template="$util.toJson($ctx.result)")

        save_resolver.add_depends_on(api_schema)

        delete_resolver = CfnResolver(
            self,
            'DeleteMutationResolver',
            api_id=items_graphql_api.attr_api_id,
            type_name='Mutation',
            field_name='delete',
            data_source_name=data_source.name,
            request_mapping_template=f"""\
            {{
                "version": "2017-02-28",
                "operation": "DeleteItem",
                "key": {{
                "{table_name}Id": $util.dynamodb.toDynamoDBJson($ctx.args.{table_name}Id)
                }}
            }}""",
            response_mapping_template="$util.toJson($ctx.result)")

        delete_resolver.add_depends_on(api_schema)
Esempio n. 2
0
    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        graphql_api = CfnGraphQLApi(self,
                                    'WeatherApi',
                                    name='weather-api',
                                    authentication_type='API_KEY')

        CfnApiKey(self, 'WeatherApiKey', api_id=graphql_api.attr_api_id)

        api_schema = CfnGraphQLSchema(self,
                                      'WeatherSchema',
                                      api_id=graphql_api.attr_api_id,
                                      definition="""
                type Destination {
                    id: ID!
                    description: String!
                    state: String!
                    city: String!
                    zip: String!
                    conditions: Weather!
                }
                        
                type Mutation {
                    addDestination(
                        id: ID,
                        description: String!,
                        state: String!,
                        city: String!,
                        zip: String!
                    ): Destination!
                }
                        
                type Query {
                    getWeather(city: String!): Weather
                    # Get a single value of type 'Post' by primary key.
                    getDestination(id: ID!, zip: String): Destination
                    getAllDestinations: [Destination]
                    getDestinationsByState(state: String!): [Destination]
                }
                        
                type Subscription {
                    newDestination: Destination
                        @aws_subscribe(mutations: ["addDestination"])
                }
                        
                type Weather {
                    description: String
                    current: String
                    maxTemp: String
                    minTemp: String
                }
                        
                schema {
                    query: Query
                    mutation: Mutation
                    subscription: Subscription
                }
            """)

        table_name = 'destinations'

        table = Table(self,
                      'DestinationsTable',
                      table_name=table_name,
                      partition_key=Attribute(
                          name="id",
                          type=AttributeType.STRING,
                      ),
                      billing_mode=BillingMode.PAY_PER_REQUEST,
                      stream=StreamViewType.NEW_IMAGE)

        table_role = Role(self,
                          'DestinationsDynamoDBRole',
                          assumed_by=ServicePrincipal('appsync.amazonaws.com'))

        table_role.add_managed_policy(
            ManagedPolicy.from_aws_managed_policy_name(
                'AmazonDynamoDBFullAccess'))

        data_source = CfnDataSource(
            self,
            'DestinationsDataSource',
            api_id=graphql_api.attr_api_id,
            name='DestinationsDynamoDataSource',
            type='AMAZON_DYNAMODB',
            dynamo_db_config=CfnDataSource.DynamoDBConfigProperty(
                table_name=table.table_name, aws_region=self.region),
            service_role_arn=table_role.role_arn)

        lambdaFn = Function(self,
                            "GetWeather",
                            code=Code.asset(os.getcwd() + "/lambdas/weather/"),
                            handler="weather.get",
                            timeout=core.Duration.seconds(900),
                            memory_size=128,
                            runtime=Runtime.NODEJS_10_X,
                            environment={'APPID': os.getenv('APPID')})

        lambda_role = Role(
            self,
            'WeatherLambdaRole',
            assumed_by=ServicePrincipal('appsync.amazonaws.com'))

        lambda_role.add_managed_policy(
            ManagedPolicy.from_aws_managed_policy_name('AWSLambdaFullAccess'))

        lambda_source = CfnDataSource(
            self,
            'WeatherDataSource',
            api_id=graphql_api.attr_api_id,
            name='WeatherCondition',
            type='AWS_LAMBDA',
            lambda_config=CfnDataSource.LambdaConfigProperty(
                lambda_function_arn=lambdaFn.function_arn),
            service_role_arn=lambda_role.role_arn)

        self.add_resolvers(graphql_api,
                           api_schema,
                           data_source=data_source,
                           lambda_source=lambda_source)
    def __init__(self, scope: core.Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # The code that defines your stack goes here
        table_name = "trainers"

        trainers_graphql_api = CfnGraphQLApi(
            self,'trainersApi',
            name="trainers-api",
            authentication_type='API_KEY'
        )
        
        CfnApiKey(
            self,'TrainersApiKey',
            api_id = trainers_graphql_api.attr_api_id

        )

        api_schema = CfnGraphQLSchema(
            self,"TrainersSchema",
            api_id = trainers_graphql_api.attr_api_id,
            definition=data_schema
        )

        trainers_table = Table(
            self, 'TrainersTable',
            table_name=table_name,
            partition_key=Attribute(
                name='id',
                type=AttributeType.STRING,

            ),

        
            billing_mode=BillingMode.PAY_PER_REQUEST,
            stream=StreamViewType.NEW_IMAGE,

            # The default removal policy is RETAIN, which means that cdk
            # destroy will not attempt to delete the new table, and it will
            # remain in your account until manually deleted. By setting the
            # policy to DESTROY, cdk destroy will delete the table (even if it
            # has data in it)
            removal_policy=core.RemovalPolicy.DESTROY  # NOT recommended for production code
        )

        trainers_table_role = Role(
            self, 'TrainersDynamoDBRole',
            assumed_by=ServicePrincipal('appsync.amazonaws.com')
        )

        trainers_table_role.add_managed_policy(
            ManagedPolicy.from_aws_managed_policy_name(
                'AmazonDynamoDBFullAccess'
            )
        )

        data_source = CfnDataSource(
            self, 'TrainersDataSource',
            api_id=trainers_graphql_api.attr_api_id,
            name='TrainersDynamoDataSource',
            type='AMAZON_DYNAMODB',
            dynamo_db_config=CfnDataSource.DynamoDBConfigProperty(
                table_name=trainers_table.table_name,
                aws_region=self.region
            ),
            service_role_arn=trainers_table_role.role_arn
        )

        get_Trainer_resolver = CfnResolver(
            self, 'GetOneQueryResolver',
            api_id=trainers_graphql_api.attr_api_id,
            type_name='Query',
            field_name='getTrainer',
            data_source_name=data_source.name,
            request_mapping_template=get_trainer,
            response_mapping_template="$util.toJson($ctx.result)"
        )

        get_Trainer_resolver.add_depends_on(api_schema)

        get_all_trainers_resolver = CfnResolver(
            self, 'GetAllQueryResolver',
            api_id=trainers_graphql_api.attr_api_id,
            type_name='Query',
            field_name='allTrainers',
            data_source_name=data_source.name,
            request_mapping_template=all_trainers,
            response_mapping_template="$util.toJson($ctx.result)"
        )

        get_all_trainers_resolver.add_depends_on(api_schema)
     
        create_trainers_resolver = CfnResolver(
            self, 'CreateTrainerMutationResolver',
            api_id=trainers_graphql_api.attr_api_id,
            type_name='Mutation',
            field_name='createTrainer',
            data_source_name=data_source.name,
            request_mapping_template=create_trainer,
            response_mapping_template="$util.toJson($ctx.result)"
        )

        create_trainers_resolver.add_depends_on(api_schema)

        update_trainers_resolver = CfnResolver(
            self,'UpdateMutationResolver',
            api_id=trainers_graphql_api.attr_api_id,
            type_name="Mutation",
            field_name="updateTrainers",
            data_source_name=data_source.name,
            request_mapping_template=update_trainer,
            response_mapping_template="$util.toJson($ctx.result)"
        )
        update_trainers_resolver.add_depends_on(api_schema)

        delete_trainer_resolver = CfnResolver(
            self, 'DeleteMutationResolver',
            api_id=trainers_graphql_api.attr_api_id,
            type_name='Mutation',
            field_name='deleteTrainer',
            data_source_name=data_source.name,
            request_mapping_template=delete_trainer,
            response_mapping_template="$util.toJson($ctx.result)"
        )
#core
        delete_trainer_resolver.add_depends_on(api_schema)
    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":"******"}',
                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)